找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 2040|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
楼主
发表于 2013-7-27 18:30:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
. y/ Q0 }9 j/ ^6 s* A+ ^$ F( yThinkPHP 3.1.3及之前的版本存在一个SQL注入漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件+ @6 e! t) s: b" @
根据官方文档对”防止SQL注入”的方法解释(见http://doc.thinkphp.cn/manual/sql_injection.html)/ P; Y' b* O) p$ d: a3 f8 ]! {6 O
使用查询条件预处理可以防止SQL注入,没错,当使用如下代码时可以起到效果:; t  ^5 }+ B, M& O! q# `: @
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();" P' O. S) j$ D6 ?4 X  @
7 i8 o' P2 B/ r4 s; Z8 k1 h6 r
或者% m( n( ]- u4 n1 k
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
( o% Y  N* Q! }# ?' J% u0 S  }8 K# P% ^# C
但是,当你使用如下代码时,却没有”防止SQL注入”效果(而官方文档却说可以防止SQL注入):/ {1 q1 Z, s* W- K  y  j
$model->query('select * from user where id=%d and status=%s',$id,$status);
1 I/ W" r9 t5 x% m. B/ O, J9 k" f2 p3 X
或者* N  g2 t; @# v; l- f  a" S
$model->query('select * from user where id=%d and status=%s',array($id,$status));
" s. u' i: Y' r1 I2 R% A" P. y
' I! W: W' o6 {, | 原因:
  `) W+ z9 }$ j4 }+ F+ pThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.& E  H8 E: Y' j
原函数:
) p7 x2 f' N8 bprotected function parseSql($sql,$parse) {
; i1 C# ~) {/ @# k        // 分析表达式
1 f3 o- X# N: N3 H" E2 `        if(true === $parse) {& q; N0 j; f- S; q
            $options =  $this->_parseOptions();. v+ ~3 l6 ?3 @  B
            $sql  =   $this->db->parseSql($sql,$options);& E9 B* ~, x6 l" Y% D3 L5 k0 ~
        }elseif(is_array($parse)){ // SQL预处理
9 h4 m! O1 A' u            $sql  = vsprintf($sql,$parse);/ t/ c* E  ]: N3 o
        }else{
; E+ k* u. W/ Y/ G( s1 D            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));# Z- y8 \9 `" o- t, F
        }# V2 z, l1 m3 U! R; u3 l
        $this->db->setModel($this->name);
/ F% e8 P- f9 C% i( f# w, l        return $sql;
  @* s1 m, f" J% Z/ D( p% A& J4 Z) V    }& @0 S* f+ a8 J

5 {' _& [6 Z1 b验证漏洞(举例):
. n3 O- c4 R; O请求地址:
* y! i1 Q8 n9 _. K) ?6 g- k+ Phttp://localhost/Main?id=boo” or 1=”1. O* @) r* v/ `. Z1 ]
# f( A9 o( F& ?! d" T- k- D
http://localhost/Main?id=boo%22%20or%201=%221( _$ ?% A( }  U3 M
action代码:
6 A. T* T4 x$ I- i$model=M('Peipeidui');
4 F% Q  v. j7 ]- Z        $m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);" n9 _$ i+ e* M1 W
        dump($m);exit;
7 V+ d, O6 l- M4 o或者
/ R! J/ [2 J" c: b7 B$model=M('Peipeidui');6 B% k* d9 d( h0 [( H% B; z
        $m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
2 U+ l. v$ D% M        dump($m);exit;1 X- C* O2 u3 M+ M
结果:
* H7 T9 S) B5 k2 Z5 s1 I表peipeidui所有数据被列出,SQL注入语句起效.% S; f+ @6 s. Y+ h$ ]4 s
解决办法:' G& j" Q8 l3 z
将parseSql函数修改为:
( F, Z8 R$ s; O; j9 A- s  mprotected function parseSql($sql,$parse) {: S4 t4 M4 u1 h7 v! Y
        // 分析表达式
4 z; Z/ z, m: N% U7 N8 {, S+ b        if(true === $parse) {
( M$ _- ^* C3 |& m9 |5 @            $options =  $this->_parseOptions();
9 {8 @$ y4 o0 s: q            $sql  =   $this->db->parseSql($sql,$options);
: a1 W8 P* v( L7 w3 S        }elseif(is_array($parse)){ // SQL预处理
3 k0 c# d9 E# p            $parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
8 `- h' n3 W# m" Z& L6 }& w            $sql  = vsprintf($sql,$parse);
8 k0 e4 \/ y1 r, W        }else{% b) V" \6 h( [  G: c0 V1 W3 U
            $sql    =   strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
: i8 W6 Z5 \3 j; ^* g        }& L- s! A- d( `  D
        $this->db->setModel($this->name);- r$ v# c2 L* S$ t7 Y, ^5 L6 a
        return $sql;* a- J6 |: e6 q  ]
    }
/ h- h% H1 T- p5 B* W  Y  q9 b+ `
1 j( G& r+ ^" N+ c- y( a* `总结:
  P0 p, }& |6 q) N0 P3 s不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
$ L, d& e* Z. l% g( x不建议直接用$_GET,$_POST
. X) x3 }( p* o. {9 v[/td][/tr]' d8 C: v: F, ]0 C1 Z$ ^
[/table]+1# K  i9 Y5 Z" }1 l/ J1 R# ~( }" F
2 V* A' c5 g# R* J3 y9 m* t
1 h$ |/ @, f: v1 A9 c
回复

使用道具 举报

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

本版积分规则

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