找回密码
 立即注册
查看: 2710|回复: 0
打印 上一主题 下一主题

ThinkPHP框架通杀所有版本的一个SQL注入漏洞

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-27 18:30:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。) h) v3 Y! ^2 S* l
ThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件, p$ \! G3 H' P8 I
根据官方文档对”防止SQL注入”的方法解释(见http://doc.thinkphp.cn/manual/sql_injection.html)
0 b! b- `. n. q; y  A1 w* e使用查询条件预处理可以防止SQL注入,没错,当使用如下代码时可以起到效果:
$ [& T% `( w" }; [$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
* A% M/ h$ Z) y6 l$ h% d# T4 d3 V, l% P& M0 q7 b
或者
2 s# {$ f$ I) f$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
* j0 r3 f1 F$ C
1 R0 \6 x: V. P% h- J0 l 但是,当你使用如下代码时,却没有”防止SQL注入”效果(而官方文档却说可以防止SQL注入):! N, @  E$ {* B$ D! ~( Z
$model->query('select * from user where id=%d and status=%s',$id,$status);
. O6 Y0 Q' R' y  i- y) C0 L% L6 `' u; w! Z4 U8 d; n- w
或者
2 x2 z: d  M5 f! {1 O; N$model->query('select * from user where id=%d and status=%s',array($id,$status));4 J- h, X- c" q4 n0 s1 ^! o

; C& }& g! N' {' v4 ^2 g. d 原因:
- h6 t7 W5 B( V; G! @ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.2 ~  w5 e$ @  ~7 X( V
原函数:
+ J/ y$ d% f7 q# a' h1 ?: Zprotected function parseSql($sql,$parse) {
' m0 s, M( ?2 p, j        // 分析表达式
  \( u5 h. Z/ H. ]0 R, u. I        if(true === $parse) {2 @! p' C' }" b/ X5 h0 s
            $options =  $this->_parseOptions();
( T) b/ \; b' w            $sql  =   $this->db->parseSql($sql,$options);3 O3 Z7 R$ U5 a3 |5 o; C' _
        }elseif(is_array($parse)){ // SQL预处理$ ^) N8 y- a1 s1 b# H
            $sql  = vsprintf($sql,$parse);
9 w8 \, d6 ?" G# @        }else{! u5 g' {' w5 Z  y$ x
            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
) w- a+ B# X8 r& t+ c        }
# m* c4 \: @. W: E* Q$ R        $this->db->setModel($this->name);
# m8 Q) ^: l6 y6 Z" N+ f        return $sql;
# E5 z8 |: I5 V; |    }8 Q: S) Q- @/ t( e4 g8 R; D9 r
# W* H- T$ r, Y) B: i
验证漏洞(举例):
0 J; b& u1 G" @. M请求地址:
( K  L$ e3 l- E* Y) Z! Khttp://localhost/Main?id=boo” or 1=”1% s; h' N. }( s5 }5 W% C! v- |& @
. \* w% d# ^$ @- _: m" q' f
http://localhost/Main?id=boo%22%20or%201=%2215 n) _) c( j: {
action代码:7 A6 }# K' _5 t7 z. ]( d
$model=M('Peipeidui');/ e/ n9 I9 j% l  g* z: T
        $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);- N8 E# p$ k7 O  W
        dump($m);exit;0 F" N# F" w' _% g
或者! O, `5 S9 u6 Z% |3 Z. M
$model=M('Peipeidui');
- s7 d0 O  v+ d" J        $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));( }( H$ H% Q4 ^3 l2 B7 {
        dump($m);exit;! ^( L- D) Q/ p: |
结果:% g; M9 y, |2 V; ]8 t
表peipeidui所有数据被列出,SQL注入语句起效.3 S- @# D3 k4 y8 k
解决办法:0 q" h5 P* w* c" _6 u* C8 T6 Q
将parseSql函数修改为:
2 Q% O7 _: \" r+ ~9 Kprotected function parseSql($sql,$parse) {* x- M( L$ o7 j1 p
        // 分析表达式; h( m! X8 s; I. M" _/ V) I
        if(true === $parse) {
$ G! D2 j2 I/ v, A  o! a            $options =  $this->_parseOptions();
3 X  |% I+ Y" F            $sql  =   $this->db->parseSql($sql,$options);$ p  C" h6 A; N1 p0 \. G
        }elseif(is_array($parse)){ // SQL预处理
. v0 B6 J( Z$ r7 Z& {            $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码4 e, G1 w: X5 L. b
            $sql  = vsprintf($sql,$parse);
' S1 |% o( i1 b& ^6 t4 d+ `0 z6 D        }else{3 n# u7 Z# `' g7 c; |7 {  L) L: q
            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));& ]3 t/ i2 l" L
        }
0 p& E. \+ v8 u. L3 l9 N        $this->db->setModel($this->name);: C  I8 }5 @' i1 L  s5 x. ]+ T+ G
        return $sql;
8 g5 [% z8 ]" o; b, Q7 n' D* V    }
) C" E8 m, l+ h9 O! P: F. u( m! }2 \% c3 s- J' O+ c( ]
总结:8 [' ~" U/ I4 B" h
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查' ~0 t9 e1 o6 C6 d: J( v0 ]( P9 b
不建议直接用$_GET,$_POST
7 y8 J2 J6 R( O! M[/td][/tr]6 R7 H) M) B6 W" z% B. s
[/table]+16 F( }- C* `- G0 ?8 b
1 \' V7 Y2 I! o

/ c0 c; O7 q' ~# d& ]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表