中国网络渗透测试联盟
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
[打印本页]
作者:
admin
时间:
2013-7-27 18:30
标题:
ThinkPHP框架通杀所有版本的一个SQL注入漏洞
下面是摘自thinkphp官方的一个公告,官方直接贴出这些东西是非常不负责的行为,跟上次apache公开的Struts2的代码执行一样的行为,会造成很多用户被黑。建议类似的厂商不要再做这种蠢事。
4 S' f1 `0 U4 y- P) W
ThinkPHP 3.1.3及之前的版本存在一个
SQL注入
漏洞,漏洞存在于ThinkPHP/Lib/Core/Model.class.php 文件
' w9 j" J8 D1 e# f+ \. ?6 E
根据官方文档对”防止
SQL注入
”的方法解释(见
http://doc.thinkphp.cn/manual/sql_injection.html
)
/ u+ |' z* E( e2 G% w( g
使用查询条件预处理可以防止
SQL注入
,没错,当使用如下代码时可以起到效果:
% R1 O1 R7 R5 {
$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();
# d- k) z0 Q& r
% u. r0 `% L8 i
或者
9 \+ h+ P. d; v4 E
$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
U7 w O9 j$ H
4 X. n) I f1 i* ~" K0 U
但是,当你使用如下代码时,却没有”防止
SQL注入
”效果(而官方文档却说可以防止
SQL注入
):
: R: C" L- }$ \. A! `
$model->query('select * from user where id=%d and status=%s',$id,$status);
. K0 E3 s/ R$ ~( y
! h5 Y- h: i: {' o0 N
或者
1 a5 R- D+ w! _, E8 S( P- V
$model->query('select * from user where id=%d and status=%s',array($id,$status));
+ C' a) E+ c- j5 y- {
: Z5 H# J- I& `# ~6 T" o4 ^
原因:
5 N% u, T2 e% v0 s" Q Z, k5 p2 J9 U
ThinkPHP/Lib/Core/Model.class.php 文件里的parseSql函数没有实现SQL过滤.
% W: A6 A* \9 U
原函数:
5 c6 E6 s5 k; O' v9 y' j& s8 ^) T) w: x
protected function parseSql($sql,$parse) {
9 {6 B; x$ `2 {, p4 s
// 分析表达式
9 U, X8 K( E5 @
if(true === $parse) {
# U y* T: Y% t( W$ t4 U# P U
$options = $this->_parseOptions();
9 Y- r2 E5 h2 B+ ?# ~5 t3 W. i
$sql = $this->db->parseSql($sql,$options);
8 _5 E& i: w: L* i
}elseif(is_array($parse)){ // SQL预处理
) o* o% f. d: T$ t2 D/ W
$sql = vsprintf($sql,$parse);
. j( Z1 Y: I6 Z& L5 P5 g( [
}else{
2 o: D7 g3 A9 P
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
# x8 h* A' x: P2 R( ~
}
4 e! x8 d/ Y9 c. I" t9 L% o
$this->db->setModel($this->name);
p5 ?" d o9 b9 `/ u+ \# {7 b
return $sql;
/ ~8 v5 _* n( ~% i# ?7 O
}
: u6 u4 i" T5 v" g6 N' }
% |& b6 q# K I- o
验证漏洞(举例):
) {2 @! @, f0 S0 p0 F* L& \! W+ C
请求地址:
1 t5 S) w5 p! ]8 S
http://localhost/Main?id=boo” or 1=”1
' H8 ]5 y" }% n
或
) F% Y! D' b9 f/ [
http://localhost/Main?id=boo%22%20or%201=%221
$ \) c5 ?+ N U0 _) _: j. a! ^1 h* O
action代码:
6 D, m K; ~0 D
$model=M('Peipeidui');
1 [. K- V- n! l: G J0 B" \
$m=$model->query('select * from peipeidui where name="%s"',$_GET['id']);
6 G# [ y! y/ O0 I* G/ I
dump($m);exit;
( W0 P* M6 Z$ E9 {2 o
或者
" Z, ~# i8 j C5 C
$model=M('Peipeidui');
& S4 k) V4 O6 ]3 A$ e$ a8 f9 v
$m=$model->query('select * from peipeidui where name="%s"',array($_GET['id']));
8 s; X+ l' Y/ _% o, F
dump($m);exit;
5 e, J$ n- h+ _" M* g$ z# b1 J
结果:
& K* P6 H! n, r
表peipeidui所有数据被列出,
SQL注入
语句起效.
3 g9 f5 j; c0 y$ o" }
解决办法:
4 v' t5 f5 u+ y& [
将parseSql函数修改为:
, z6 r) ]# k% V, `% {, K+ O
protected function parseSql($sql,$parse) {
3 B5 P1 h+ M% c8 W; U G8 |" W
// 分析表达式
) G ]2 e9 l2 A/ B8 Z9 H
if(true === $parse) {
3 ]1 F8 R! i8 x4 W# u! W5 M
$options = $this->_parseOptions();
2 v6 G1 `; @. C3 j
$sql = $this->db->parseSql($sql,$options);
" Z; ?. y! O# o0 W5 n C) K: i
}elseif(is_array($parse)){ // SQL预处理
! L7 c& x( m. B3 \: ^8 d, E
$parse = array_map(array($this->db,'escapeString'),$parse);//此行为新增代码
# }/ l5 u: s/ y, ]3 |
$sql = vsprintf($sql,$parse);
* i R% w9 L. D/ x3 [' |
}else{
q' S$ V" i- v7 U! B
$sql = strtr($sql,array('__TABLE__'=>$this->getTableName(),'__PREFIX__'=>C('DB_PREFIX')));
( T( S2 R' T4 Q
}
7 J T& ]0 j5 I, ?6 s% M" m
$this->db->setModel($this->name);
. H# o1 ~$ O! ?) U7 r- ?
return $sql;
5 ~9 j: }& E) l
}
~1 ^* c2 d: q" R+ X" V
2 `- l" m" e0 f1 _ \
总结:
0 J P5 u0 n; Q* x. W9 P
不要过分依赖TP的底层SQL过滤,程序员要做好安全检查
# y. M. }7 V. O% K: t3 a
不建议直接用$_GET,$_POST
7 Q" k/ B& c6 K9 o" D
[/td][/tr]
& j6 j2 H3 l; n( O8 B/ m9 M! h
[/table]+1
, H9 W0 k6 l; C% i! l" b$ ^
- w% W4 [" u& ^3 j
% b' q% A6 I- u1 o8 Z) {5 G0 n: G: k( E
欢迎光临 中国网络渗透测试联盟 (https://www.cobjon.com/)
Powered by Discuz! X3.2