中国网络渗透测试联盟
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-7-27 18:30
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
1 [& R1 g) X+ b; O7 I
ThinkPHP 3.1.3及之前的版本存在一个
SQL注入
漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
p8 C1 a7 ~. Z( K# W, I
根据官方文档对”防止
SQL注入
”的方法解释(见
http://doc.thinkphp.cn/manual/sql_injection.html
)
; i; g% @, O8 C3 ?. l: l$ T V6 D
使用查询条件预处理可以防止
SQL注入
,没错,当使用如下代码时可以起到效果:
, x- E1 P- F0 p& ~0 e0 d4 r
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
) }( t/ f, u3 e. z$ `/ K5 `8 ^
0 X7 [; _- w, }; C, V: z
或者
: V$ B/ z- Q# k6 A8 @, c
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
2 K( u4 X& w2 S! X
+ d" ~7 W# M% k+ j; W( t
但是,当你使用如下代码时,却没有”防止
SQL注入
”效果(而官方文档却说可以防止
SQL注入
):
+ B ?) d7 Y& i/ X
$model->query('select * from user where id=%d and status=%s',$id,$status);
3 w) a# b5 K4 O& }4 J
1 b1 Z: v) X+ Y
或者
- M/ I" e% M) |' P
$model->query('select * from user where id=%d and status=%s',array($id,$status));
5 a1 d: M- K/ `2 K0 k5 y
* Y' v& @& d- z2 _8 `
原因:
c6 q# i/ M# }; g+ l
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
p# t' p K' P+ o
原函数:
- s N" W% w$ B9 Y/ |! U$ m
protected function parseSql($sql,$parse) {
6 `$ ~! y9 a2 e3 u
// 分析表达式
- Z% q' v$ }. s( a
if(true === $parse) {
- w0 g3 T$ b% p8 S
$options = $this->_parseOptions();
4 a5 }, J+ C. d; F4 C+ `9 r
$sql = $this->db->parseSql($sql,$options);
, K0 v. _/ |1 C. r. F
}elseif(is_array($parse)){ // SQL预处理
; g$ w& z' D) h f6 ^1 e$ E, {
$sql = vsprintf($sql,$parse);
7 C. s, a4 t% h. {
}else{
7 t- X0 c. e! @$ d$ f% h9 M
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
* K# e" J% S4 E0 ] ]% \0 M1 {
}
4 Y1 N/ Q) O) }3 |$ h7 k
$this->db->setModel($this->name);
/ A" x* V/ j7 f; d b
return $sql;
( Z/ j) ? \% i8 r( o5 G
}
c' @6 f, {* P% f4 d
$ f2 |) M: ]/ B
验证漏洞(举例):
' f+ z% o# [; ^* I; L
请求地址:
8 R; |% _, G' t
http://localhost/Main?id=boo” or 1=”1
+ ?4 @% ~5 E3 }& d$ J+ h, \7 |9 }
或
: {* b. S2 n- w9 ]$ f. S
http://localhost/Main?id=boo%22%20or%201=%221
8 S: `% k' k/ M; r
action代码:
# ?& g# R3 N* e) ?+ }
$model=M('Peipeidui');
1 V8 S% q& W& }/ F5 @) h
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
2 a& u: E- M4 [2 X w+ ^
dump($m);exit;
4 T$ N: I1 X' f4 i: W
或者
6 S4 P6 `2 O2 A4 Q \; x( O
$model=M('Peipeidui');
$ g) T* {9 }& e% N4 ~
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
1 b; m: B* x) c" B' c& i; t* O
dump($m);exit;
- Q, q7 L$ E# I! k7 r1 @; H4 i1 z
结果:
7 Q5 Z! j" n6 m; X3 J
表peipeidui所有数据被列出,
SQL注入
语句起效.
) w% ?/ T8 A1 d2 o
解决办法:
& e X0 u1 ^ ~# L
将parseSql函数修改为:
2 i7 X' I7 o0 i$ N
protected function parseSql($sql,$parse) {
; U: c: P, G$ l# J
// 分析表达式
) r2 l, l0 J: u) x: c' s- d* b
if(true === $parse) {
@, F8 l V( k/ ?
$options = $this->_parseOptions();
8 K" { F1 N: @) S9 u
$sql = $this->db->parseSql($sql,$options);
, R# k- S2 V- ?. s6 v. p+ |7 j4 o
}elseif(is_array($parse)){ // SQL预处理
8 `4 Z6 S, f" x% d5 V
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
. d3 O* u7 c9 ~- Z
$sql = vsprintf($sql,$parse);
5 P" \0 y9 W! z& n: @. x6 n* e0 X5 D: Z
}else{
( G/ x; L0 |3 A( {# Y0 x, J3 p% T. e% Y
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
6 J# j1 e0 H& ^2 a
}
) v1 v; _) ?. l
$this->db->setModel($this->name);
0 C5 m5 M. {# E1 ?8 Z8 V
return $sql;
8 V. `- E5 @# ^! ]. t
}
0 H8 Q; a* ?+ q' F
. D i) n1 Y$ f5 u! ~: \7 N) D( J( Y& n
总结:
" H' _6 }0 T8 F& ~8 a
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
3 P4 L9 ^4 h' V+ v# Q' j. @% M
不建议直接用$_GET,$_POST
8 G; ]( N* b1 L6 p1 N
[/td][/tr]
) ~) p9 A& v; a" V3 `" `
[/table]+1
f4 h% G2 `4 e' s. {; N9 j- f
8 T" @2 u2 N2 L
# w V$ a# `( S
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2