赞
踩
简介: 指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入
补充: mysql_escape_string()函数,该函数和mysql_real_escape_string一样可以转移特殊字符,但不同的是经过mysql_escape_string处理的参数在存入数据库时会被还原成原来的数据
场景: 设想在登录页面username和password都经过了mysql_real_escape_string函数的转义,无法造成SQL注入。但注册页面使用的是mysql_escape_string函数,那么我们注册一个名为admin’#的用户,密码设为123456,登录该用户后,在修改密码页面修改密码为666666,这时admin’#的密码没有被修改,反而是admin的密码被修改了。
原理: 后端数据库执行的命令为,UPDATE users SET PASSWORD=‘666666’ where username=‘admin’#’ and password=‘123456’,等价于,UPDATE users SET PASSWORD=‘666666’ where username=‘admin’
前言:
- 当某字符的大小为一个字节时,称其字符为窄字节
- 当某字符的大小为两个字节时,称其字符为宽字节
- 所有英文默认占一个字节,汉字占两个字节
- 常见的宽字节编码:GB2312,GBK,GB18030,BIG5,Shift_JIS
原理: MySQL数据库编码与PHP编码不同导致,如MySQL数据库使用GBK编码而PHP编码为UTF8。MySQL认为两个字符是一个汉字(前一个字符ascii码要大于128,如%df),而当我们输入%df和单引号(%df’)时,MySQL会调用转义函数如addslashes,将单引号转义(添加 \ )后整个为 %df’ ,其中 \ 的十六进制是%5c,即 %df%5c’ ,而MySQL的GBK编码会认为%df%5c是一个汉字(運),而此时单引号仍然存在,可以实现闭合,从而造成SQL注入。
参考链接: 渗透测试-SQL注入之宽字节注入
比如这段PHP代码
$id=$_POST['id'];
if (preg_match('/and|select|insert|insert|update|[A-Za-z]|/d+:/i', $id)) {
die('stop hacking!');
} else {
echo 'good';
}
比如这段PHP代码
String query="select password from users where username='?' ";
$query="INSERT INTO myCity (Name,CountryCode,District) VALUES (?,?,?)";
$stmt=$mysqli->prepare($query);
$stmt->bind_param("sss",$val1,$val2,$val3);
$val1="Stuttgart";
$val2="DEU";
$val3="Baden";
//execute the statement
$stmt->execute();
即使攻击者插入类似 admin’ or 1=1# 的字符串,预编译会将传入的 admin’ or 1=1# 当做纯字符串的形式作为username执行,避免了类似sql语句拼接、闭合等非法操作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。