中国网络渗透测试联盟
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-7-27 18:30
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
+ Y- T* u/ G5 ~8 J. a/ m
ThinkPHP 3.1.3及之前的版本存在一个
SQL注入
漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
# A* s. n* w3 K9 g2 Z) X
根据官方文档对”防止
SQL注入
”的方法解释(见
http://doc.thinkphp.cn/manual/sql_injection.html
)
' z6 m' I2 ~7 j' z# z, V
使用查询条件预处理可以防止
SQL注入
,没错,当使用如下代码时可以起到效果:
+ E: S$ X( k" a8 C/ Q( l
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
9 m+ B" C# }; o
2 x+ _9 ~4 Z: Y7 P% `6 F
或者
+ P1 i8 [5 B! e
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
+ F, t" e3 `" }% l: i% T
' U7 D, {- {" d( |
但是,当你使用如下代码时,却没有”防止
SQL注入
”效果(而官方文档却说可以防止
SQL注入
):
4 U3 m1 l+ r+ W( S+ G. n
$model->query('select * from user where id=%d and status=%s',$id,$status);
8 g6 {$ j: S& z
+ c9 f1 H7 m# A1 |
或者
; T7 z+ p+ B2 G8 [/ w
$model->query('select * from user where id=%d and status=%s',array($id,$status));
( R- U A6 G' A- Z& M
1 M$ T5 R: e6 U2 _/ E# w
原因:
( C+ _% U; n0 r" Y* [" E$ l
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
6 c9 }" m& [ x* T
原函数:
( Q9 m) s7 I9 l$ m, b, b
protected function parseSql($sql,$parse) {
4 `1 Q/ j; M$ |# R% m1 P
// 分析表达式
2 W, g2 q* p$ ?) U, E
if(true === $parse) {
+ Y2 |1 k$ _. y: w
$options = $this->_parseOptions();
6 g& H5 T. @1 x& U; p. h+ r) V
$sql = $this->db->parseSql($sql,$options);
( a0 z! ^7 f: b5 r
}elseif(is_array($parse)){ // SQL预处理
( I0 a: I5 A; Q
$sql = vsprintf($sql,$parse);
9 B8 w1 F7 C8 Y- M5 _+ D
}else{
3 _$ ?* W) U$ x& f' d" P
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
4 j% I: b* S! S( I0 r; _, f
}
; @5 Y1 \ ?% r3 ?) p$ I
$this->db->setModel($this->name);
7 C$ [" ]/ V& d' u1 t/ `
return $sql;
& H, P" @! J8 L2 z$ h" l# f9 n
}
, B3 t' @ Y* J
" B4 `! \2 E! ?8 D
验证漏洞(举例):
, J D" H# |% C# U0 m1 b* v
请求地址:
* g4 N! G' ^) Z- S5 ]5 K
http://localhost/Main?id=boo” or 1=”1
5 w( H, \* P3 u" m7 C# o# n
或
4 Q2 U9 g8 G5 u- r- L4 O3 y/ z3 j
http://localhost/Main?id=boo%22%20or%201=%221
' l7 l/ K# ]9 l, L8 J) e4 N9 m% W
action代码:
T D9 _& y7 p; Y- @
$model=M('Peipeidui');
# Z: H$ \+ ~" I( o- k7 h9 J: B
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
2 X8 `. w- w) X# F
dump($m);exit;
+ n+ D' O( k! ~) a
或者
! W0 C7 t; A k0 A2 x6 D* Z
$model=M('Peipeidui');
+ O* ~6 a! c0 w; ~0 U+ F# ?
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
5 s: M5 P' U% t$ a
dump($m);exit;
" y8 h# o6 ]5 i* h
结果:
- x$ x, J4 w- n1 H" r) V/ O8 w$ R" g
表peipeidui所有数据被列出,
SQL注入
语句起效.
6 X8 e3 k) |3 M
解决办法:
! A# l3 W! J! ^5 a7 b* A$ x" f
将parseSql函数修改为:
# t. V+ x0 Z( R. N
protected function parseSql($sql,$parse) {
: q# Q# d% v- o0 l' `" z
// 分析表达式
. X+ q2 m$ W+ ]0 f9 U
if(true === $parse) {
9 x2 S& e: l" Q8 ~ R9 U5 A! M) t5 I
$options = $this->_parseOptions();
- Q8 i4 S9 M7 O
$sql = $this->db->parseSql($sql,$options);
. q W5 b3 `* ]4 m% J
}elseif(is_array($parse)){ // SQL预处理
3 {7 d# Z N1 l( C; Z+ ?. s
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
" z. Y- I& d8 G3 l2 F9 @
$sql = vsprintf($sql,$parse);
6 {! b, E3 U! k2 W& _
}else{
& U0 _: j* @ Q' g# g' d* f# M: x
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
4 y( j$ s4 I4 r6 b
}
5 A3 ~: S* l5 E& P- \# u" s
$this->db->setModel($this->name);
; ~( x) m. V3 c) @+ n' r" u, c$ E3 G6 N
return $sql;
; F2 B! y/ \' L
}
]4 F! |- g' }. I2 c) G
# c, D# t' b. V+ S
总结:
! i7 V6 E1 ]$ f, Y# K* [( m! k
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
( V1 w; X+ j: ~8 N( S0 A) g
不建议直接用$_GET,$_POST
4 V( j& j; e$ M
[/td][/tr]
+ a- Y' Z& W! U! U5 Q' f
[/table]+1
3 F* i( ^, v) p# O H, m
! C6 L4 {7 Z/ v5 Q- {5 [
/ j; F0 I/ V) m! c
欢迎光临 中国网络渗透测试联盟 (https://cobjon.com/)
Powered by Discuz! X3.2