中国网络渗透测试联盟
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-7-27 18:30
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
6 l- z- c9 j8 |' P: h
ThinkPHP 3.1.3及之前的版本存在一个
SQL注入
漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
* y5 j, f4 S: P4 K' e, t X7 y
根据官方文档对”防止
SQL注入
”的方法解释(见
http://doc.thinkphp.cn/manual/sql_injection.html
)
7 r( L9 v" y1 A7 ]9 _8 @
使用查询条件预处理可以防止
SQL注入
,没错,当使用如下代码时可以起到效果:
' B0 _% V1 d, G% `+ i+ p" q w
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
% p5 R- o, |4 |3 {
: Q& y3 k2 ^# O3 x
或者
1 n. z/ U0 T6 t7 }4 j8 r5 U y0 g
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
! w" Y6 i1 g& ?: u0 H
+ e' G" t# ?" \7 F; N
但是,当你使用如下代码时,却没有”防止
SQL注入
”效果(而官方文档却说可以防止
SQL注入
):
9 M( R& J0 l q
$model->query('select * from user where id=%d and status=%s',$id,$status);
' z( [5 G9 [" X+ P1 g1 J' t2 }
0 `2 n$ d" p8 i U: l
或者
* l8 y: Q, ^ ^
$model->query('select * from user where id=%d and status=%s',array($id,$status));
6 q [- q) x8 E; V
& H% F( B( G% ?( A
原因:
* x: a: q" G( N, Z( t
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
) n* m0 ?6 e2 j: ]( B9 f% s1 ]
原函数:
( m" f6 S, p2 V! p Z6 s6 r
protected function parseSql($sql,$parse) {
! f2 i1 x% i" I2 t' j) C( e
// 分析表达式
* }! k( C& _6 ^/ P' @ D9 z( r6 w# A9 a
if(true === $parse) {
- i5 d- C/ w% V v$ Z5 U4 C( V; }8 r" H9 o
$options = $this->_parseOptions();
( B Q( h* ^2 J: ]/ e
$sql = $this->db->parseSql($sql,$options);
% e& F0 k; R& U$ [2 k! L8 @/ `
}elseif(is_array($parse)){ // SQL预处理
|* Z; J& q8 Y" F1 w
$sql = vsprintf($sql,$parse);
[/ c. W9 v3 g7 q& ?: n
}else{
7 `2 V1 H( L' T' p5 c0 c2 E/ J( ~ ]& w
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
1 L9 N/ s6 x6 ~/ A/ E$ l
}
" G/ P! u( N, e2 ?0 P( z; E
$this->db->setModel($this->name);
' y0 G& u3 n2 Q: `6 k' P. y# a j3 b
return $sql;
4 ^/ |2 V' x/ {9 K2 n4 ?
}
* B/ |0 F* F4 H( C; b1 s% r
3 |7 {7 W( Y7 z) s- c/ k' s) \& g0 ~& ?
验证漏洞(举例):
$ c+ W' W: V/ z# h2 @
请求地址:
: R6 D* B* `4 _4 l& I I
http://localhost/Main?id=boo” or 1=”1
0 x0 P% b t* W$ A: }* O
或
- V% ~& ?4 W. B6 W3 ?; `& G7 B
http://localhost/Main?id=boo%22%20or%201=%221
; w6 L" ?9 v9 {; J" Q3 L
action代码:
" A0 J- e$ Q- u6 i
$model=M('Peipeidui');
i% ]# s7 o2 s
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
1 L/ v; m, o: I4 ~) x) }
dump($m);exit;
' E7 @8 ~' B4 w6 U2 x |& u( E
或者
* K4 V# ~- a, l$ f
$model=M('Peipeidui');
& _% |1 l* E! B E$ F
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
6 {3 r/ l+ c- a, Q" s6 [
dump($m);exit;
) E& T8 U* @2 o8 E2 j
结果:
6 {, Z, l- Q% j, j! {' k
表peipeidui所有数据被列出,
SQL注入
语句起效.
. Y5 y" [9 f7 ?9 n: D7 ^
解决办法:
3 ]' l7 \5 q1 z5 r
将parseSql函数修改为:
5 _- m: _) M4 g7 L7 c
protected function parseSql($sql,$parse) {
( p9 J$ w/ }8 @. z1 P
// 分析表达式
7 J, j# U" ~/ I6 ~! T
if(true === $parse) {
7 j* G! [, C& z$ [) S P# R
$options = $this->_parseOptions();
# C/ o( r, V5 ~ v7 }4 L: f
$sql = $this->db->parseSql($sql,$options);
) N, f. r, @' Q) ?: k7 c" \
}elseif(is_array($parse)){ // SQL预处理
8 y+ q7 S3 s B& y# w p
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
" b- H6 I, \- u! l6 d1 ]3 G
$sql = vsprintf($sql,$parse);
5 e) d [& h- A+ i C
}else{
6 t/ r: h8 ~ q6 E/ R' D; N
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
/ L) g% i1 b$ w9 n6 x- ^0 v' g: ^
}
; V, I! k: L O! V
$this->db->setModel($this->name);
) R7 }3 X0 s0 L& u8 Y2 S6 X$ c
return $sql;
j: A. C$ q' U. M; a7 c
}
9 ~; _1 x' c1 r! X5 L& J
1 [( N9 h/ t) ]/ I/ u' A
总结:
: C: z' V7 F* N! S# q
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
1 g% U' B P, }. x' w
不建议直接用$_GET,$_POST
+ U" M0 U. `7 g0 h
[/td][/tr]
) b2 `* y3 o" P* L- ~1 `, a
[/table]+1
2 f0 K) ~/ p+ V0 [- z# J2 t$ V
+ Q+ l# c: F& {9 P2 X& D' j$ j0 v
7 r+ y( E, q% @+ h: T; T5 V6 v4 L
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2