中国网络渗透测试联盟
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-7-27 18:30
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
9 Z0 p7 b2 Q N, n
ThinkPHP 3.1.3及之前的版本存在一个
SQL注入
漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
) @+ b% ^ v' d8 }
根据官方文档对”防止
SQL注入
”的方法解释(见
http://doc.thinkphp.cn/manual/sql_injection.html
)
+ x2 {# d. \0 {' n
使用查询条件预处理可以防止
SQL注入
,没错,当使用如下代码时可以起到效果:
9 c3 o! w0 Y3 L8 M! J. F
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
0 n( n! @& _: s5 w) m
& l7 M/ b: {8 c+ n
或者
1 w2 w. Y1 q* W' O/ u
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
, q) Z- i: R$ E7 a5 L. p
. c G( b" B+ [
但是,当你使用如下代码时,却没有”防止
SQL注入
”效果(而官方文档却说可以防止
SQL注入
):
8 v1 A% e. h: Z4 u" U; ]
$model->query('select * from user where id=%d and status=%s',$id,$status);
% ]4 L, i- G" c3 N6 x
& U' E& O! E5 ~( @0 F
或者
; H, T2 }) y! g6 s
$model->query('select * from user where id=%d and status=%s',array($id,$status));
7 x3 n8 }% N! d2 c. y% l2 G
7 I8 T& ^0 q# }# R
原因:
* H/ u' I: i1 G6 T
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
2 J& l5 r$ A& W: Z& I
原函数:
, Y6 X4 f% {/ e/ M/ F
protected function parseSql($sql,$parse) {
2 n0 {( N' G& C# E4 A; S
// 分析表达式
# F% c) {% ^( S7 z2 `& l) j
if(true === $parse) {
) _' J! A o2 R7 \& @" `7 V
$options = $this->_parseOptions();
+ T1 i& y8 B4 U& s5 n2 c- G
$sql = $this->db->parseSql($sql,$options);
, Z# T% U2 l' }1 V
}elseif(is_array($parse)){ // SQL预处理
: D# L, A$ r: P# P% }7 f
$sql = vsprintf($sql,$parse);
5 n# T0 Y6 N# o' X
}else{
- j7 w2 c8 e% f+ d/ B
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
3 z; Z% n' ^9 d
}
: m v1 e7 y2 Z3 \* M
$this->db->setModel($this->name);
& }% `9 l- n, Z
return $sql;
0 K" H# g6 y- c3 y! q
}
% B! t% O" N, c% |, U& D9 l
! a+ W7 y# A6 l! ~! [* M. o0 m# V" n7 I5 k
验证漏洞(举例):
- `0 C0 o3 d4 n1 x: ?4 R) v* M
请求地址:
/ E7 z1 r2 l; f6 I. s& u0 l9 ~& |
http://localhost/Main?id=boo” or 1=”1
+ x+ ^. |5 x% K0 y7 G, |4 a
或
1 V) B1 P$ g: H
http://localhost/Main?id=boo%22%20or%201=%221
4 u9 l4 H: i- A( Q. _
action代码:
; A/ t- v- E1 Y, m
$model=M('Peipeidui');
: q+ S0 S" E( f' d$ r
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
3 U; D: ^5 ^1 d7 i2 k H3 j" S8 w0 H8 C
dump($m);exit;
+ ^$ c- N6 i9 n* O6 x
或者
1 M9 x5 C0 b/ S+ i; i. r
$model=M('Peipeidui');
) b2 S3 P. m5 p* c& ~7 o
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
" `' Q- N I$ S6 w2 y
dump($m);exit;
7 W/ y7 N6 i% i7 s
结果:
7 J# _9 q7 q+ H) P
表peipeidui所有数据被列出,
SQL注入
语句起效.
, y C) v% S" A
解决办法:
6 y) i7 r5 F8 L
将parseSql函数修改为:
6 V* Z0 Q% f% X- y; I2 L
protected function parseSql($sql,$parse) {
+ }; n7 c9 r7 `5 B6 ~* t* w
// 分析表达式
) I) v9 e( Z5 l. H5 l" s. Z
if(true === $parse) {
4 `7 ]7 O- y8 L1 h* l
$options = $this->_parseOptions();
* G- C# \. O' w: J. ]
$sql = $this->db->parseSql($sql,$options);
' _7 V' C/ A0 d- k7 Q
}elseif(is_array($parse)){ // SQL预处理
* B) U+ j$ e0 m* c
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
) e; `: d6 \, P
$sql = vsprintf($sql,$parse);
, y7 E0 r1 d. I2 u; q5 H/ Y
}else{
% p" r* J6 X3 H8 Z& l. X
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
/ o- L) Z: U) ]5 s3 ?8 @. F6 M6 m
}
+ n# [2 d- ~6 i& h
$this->db->setModel($this->name);
& s6 G, h1 g' v
return $sql;
( C7 `7 M! H' _/ |1 I
}
/ d+ L! s c* q" Y
. Z' l o; `9 ^' ` `& u: N" N
总结:
0 ? {0 ?7 Q: ^$ s5 ]
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
, V3 i. W* u2 N/ Q
不建议直接用$_GET,$_POST
# O- _( N' h; o! t: z' I. q3 x1 L6 J
[/td][/tr]
' f% P# \" b& A, F
[/table]+1
( M) Y" L* s- V& _8 a' ?
8 A/ k I- N. k' O! R* t
+ Q; a$ g3 n3 U& l7 r
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2