Date: Wed, 6 Jan 2016 21:57:34 -0500 From: Peter Chen <peterchencs@gmail.com> To: Henry Hu <henry.hu.sh@gmail.com> Cc: "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org> Subject: Re: Nginx Vulnerability on FreeBSD Message-ID: <CAHF3bU8BvZcrjFVFwPSF=NotM2FCQgpE1BPgX8Ns2BRV2sHQRg@mail.gmail.com> In-Reply-To: <CAHF3bU8K3MYASnOOzH2h_Lj7yYR%2B_ex9LmZfAjkFSxVMbPofEw@mail.gmail.com> References: <CAHF3bU_KEYaTmeCQvkbPHPG2o=GRZXXXAYiDh4WfFeeLywroNA@mail.gmail.com> <CAEJt7hZiXHALJGaPSua24D_djXrbjiAdfY4A3t3=KGd4Rm1rvA@mail.gmail.com> <CAHF3bU8K3MYASnOOzH2h_Lj7yYR%2B_ex9LmZfAjkFSxVMbPofEw@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
After I tried that on FreeBSD, and used "truss" to trace system calls, the Nginx worker process still cannot crash. It seems that FreeBSD's recvfrom() automatically divide the received data into 4096-sized chunks, and it will not overflow. The system call trace is as follows (different from http://www.vnsecurity.net/research/2013/05/21/analysis-of-nginx-cve-2013-2028.html 's 1024 and 4112, here the recvfrom's received size is 1024, 4096 and 16): ======================================================== kevent(8,{},0,{0x6,EVFILT_READ,0x0,0,0x1,0x801cd3000},512,0x0) = 1 (0x1) gettimeofday({1452134269.299028 },0x0) = 0 (0x0) accept4(0x6,0x7fffffffe650,0x7fffffffe6bc,0x20000000,0xffff,0x2) = 3 (0x3) kevent(8,{0x3,EVFILT_READ,EV_ADD|EV_ENABLE|EV_CLEAR,0,0x0,0x801cd30e0},1,{0x3,EVFILT_READ,EV_CLEAR,0,0x1410,0x801cd30e0},512,{60.000000000 }) = 1 (0x1) gettimeofday({1452134269.299901 },0x0) = 0 (0x0) recvfrom(3,"GET / HTTP/1.1rnHost: 1337.vnsec"...,1024,0x0,NULL,0x0) = 1024 (0x400) writev(0x3,0x7fffffffdcb0,0x2,0x7fffffffffffef87,0x68,0x1) = 172 (0xac) shutdown(3,SHUT_WR) = 0 (0x0) recvfrom(3,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...,4096,0x0,NULL,0x0) = 4096 (0x1000) recvfrom(3,"AAAAAAAACCCCCCCC",4096,0x0,NULL,0x0) = 16 (0x10) kevent(8,{},0,{0x3,EVFILT_READ,EV_CLEAR|EV_EOF,54,0x0,0x801cd30e0},512,{5.000000000 }) = 1 (0x1) gettimeofday({1452134269.306013 },0x0) = 0 (0x0) write(4,"172.16.187.1 - - [06/Jan/2016:21"...,1089) = 1089 (0x441) close(3) ======================================================== Any idea how to make the crash happen? I can modify the kernel if needed. But I did not find recvfrom()'s maximum "len" in the recvfrom system call implementation -- sys_recvfrom. ( https://github.com/freebsd/freebsd/blob/63cd1c131acbe2c4896430de52395b168ee9b73d/sys/kern/uipc_syscalls.c ) Thanks!! On Tue, Jan 5, 2016 at 12:59 AM, Peter Chen <peterchencs@gmail.com> wrote: > Thanks a million for the prompt reply! I'll try > http://www.vnsecurity.net/research/2013/05/21/analysis-of-nginx-cve-2013-2028.html > . > > On Tue, Jan 5, 2016 at 12:49 AM, Henry Hu <henry.hu.sh@gmail.com> wrote: > >> >> >> On Tue, Jan 5, 2016 at 12:14 AM, Peter Chen <peterchencs@gmail.com> >> wrote: >> >>> Hi, >>> >>> I am trying to do a security research experiment on FreeBSD. >>> I try to test the Nginx Vulnerability CVE-2013-2028 on FreeBSD x86-64, >>> with >>> Nginx 1.3.9/1.4.0. >>> (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2028) >>> >>> However, most exploit samples can succeed on Linux, but not FreeBSD. >>> The basic idea for the exploit, is to send a packet with a very large >>> chunk >>> size, making the victim process stack-overflow. After Nginx's many >>> crashes, >>> the attacker can find enough gadgets to launch a return-oriented >>> programming attack. >>> >>> However, it is hard to let Nginx worker process crash (due to overwritten >>> return address) on FreeBSD. Process crash is the first step of the whole >>> exploit. >>> >>> I guess (probably a wrong guess) the reason may be: the exploit needs to >>> set MTU to a large value. But FreeBSD seems only to allows a max MTU of >>> 16110. >>> >>> It is probably because of other reasons. Any comments/suggestions on >>> this, >>> just to make the victim process crash? >>> >>> Here are two exploit code examples, which can run against Linux target, >>> but >>> fail to make the Nginx worker process crash on FreeBSD: >>> >>> http://www.scs.stanford.edu/brop/ >>> http://www.scs.stanford.edu/brop/nginx-1.4.0-exp.tgz >>> >>> https://www.exploit-db.com/docs/27074.pdf >>> http://seclists.org/fulldisclosure/2013/Jul/att-90/ngxunlock_pl.bin >>> >>> >> With a simple experiment on nginx 1.4.0, it's possible that FreeBSD has >> more strict checks in recvfrom. >> >> For the exploit: >> Pwning IP 127.0.0.1 >> Pwning >> Checking for vuln... Not vuln2 >> >> From error.log: >> 2016/01/05 00:43:35 [alert] 79819#0: *14 recv() failed (22: Invalid >> argument) while sending response to client, client: 127.0.0.1, server: >> localhost, request: "GET / HTTP/1.1", host: "bla.com" >> From ktrace: >> 79819 nginx CALL recvfrom(0x3,0x801a15400,0x400,0,0,0) >> 79819 nginx GIO fd 3 read 104 bytes >> "GET / HTTP/1.1\r >> ... >> 79819 nginx CALL >> recvfrom(0x3,0x7fffffffcf30,0xeadbeefdeadbef03,0,0,0) >> 79819 nginx RET recvfrom -1 errno 22 Invalid argument >> >> >> From an analysis, this should succeed: >> (from >> http://www.vnsecurity.net/research/2013/05/21/analysis-of-nginx-cve-2013-2028.html >> ) >> >> strace -p 11337 -s 5000 2>&1 | grep recv >> recvfrom(3, "GET / HTTP/1.1rnHost: 1337.vnsecurity.netrnAccept: >> */*rnTransfer-Encoding: chunkedrnrnfff...snip..fff0f0f0f0f", 1024, 0, NULL, >> NULL) = 1024 >> recvfrom(3, "AAA..snip..AACCCCCCCC", 18446744069667229461, 0, NULL, NULL) >> = 4112 >> >> >>> >>> Thanks!! >>> >>> Best, >>> Peter >>> _______________________________________________ >>> freebsd-hackers@freebsd.org mailing list >>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers >>> To unsubscribe, send any mail to " >>> freebsd-hackers-unsubscribe@freebsd.org" >>> >> >> >> >> -- >> Cheers, >> Henry >> > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAHF3bU8BvZcrjFVFwPSF=NotM2FCQgpE1BPgX8Ns2BRV2sHQRg>