您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
6-1 sql注入的攻击方式
发布时间:2023-05-01 01:45:34编辑:雪饮阅读()
-
主要是分三阶段
第一阶段就是sql注入的常规实现与解决方案
实例如:
<?php
namespace app\controllers;
use yii\web\Controller;
class HelloController extends Controller{
public function actionIndex(){
/*step1
* 这是一条正常查询的sql
* */
echo "step1<br/>";
$key = "MurphyPendleton";
$sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'";
echo $sql;
echo "<hr/>";
}
public function actionIndex2(){
/*step2
* 利用单引号封闭了部分查询以及使用or建立新的查询条件,
* 并使用mysql的注释符-- (注意,是两个减号和一个空格)注释掉后面的查询条件
* 使得该sql查询得满足条件的数据变的更多,达到了sql注入的目标
* */
echo "step2<br/>";
$key = "' or 1=1 -- ";
$sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'";
echo $sql;
echo "<hr/>";
}
public function actionIndex3(){
/*step3
* 同上面道理一样,只是or也可以使用||来代替
* */
echo "step3<br/>";
$key = "' || 1=1 -- ";
$sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'";
echo $sql;
echo "<hr/>";
}
public function actionIndex4(){
/*step4
* 问题的解决:将敏感字符转义
* 因为使用转义字符后,则单引号没有了关闭前面部分查询条件的能力,则后面的or以及-- 的注释功能连同单引号都被看做是一个整体了
* 这么一个整体去查询则肯定是没有符合条件的数据了
* */
echo "step4<br/>";
$key = "\' || 1=1 -- ";
$sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'";
echo $sql;
echo "<hr/>";
}
public function actionIndex5(){
/*step5
* 问题的解决:将敏感字符转义(addslashes)
* 同样是转义,但可以更优雅的使用addslashes函数来做
* */
echo "step5<br/>";
$key = addslashes("' || 1=1 -- ");
$sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'";
echo $sql;
echo "<hr/>";
}
}
这第二阶段就是在使用转义字符的解决方案时候对于不同编码(utf8与gbk)时候导致的sql注入防范成功与失败的局面。
实例1如:index.php
<?php /*新的问题: *chr() 函数从指定 ASCII 值返回字符。 ASCII 值可被指定为十进制值、八进制值或十六进制值。 八进制值被定义为带前置 0,十六进制值被定义为带前置 0x。 chr(0xdf): ß 参考http://ascii.wjccx.com/十进制值为223时候的符号 * * */ header('Content-Type: text/html; charset=UTF-8'); $key = chr(0xdf)."'|| 1=1 -- "; $key = addslashes($key); echo $key; echo "<br/>"; $sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'"; echo $sql; ?>实例2如:index2.php
<?php /*新的问题: *chr() 函数从指定 ASCII 值返回字符。 ASCII 值可被指定为十进制值、八进制值或十六进制值。 八进制值被定义为带前置 0,十六进制值被定义为带前置 0x。 chr(0xdf): ß 参考http://ascii.wjccx.com/十进制值为223时候的符号 * * */ header('Content-Type: text/html; charset=GBK'); $key = chr(0xdf)."'|| 1=1 -- "; /* * 0xdf就是df *单引号'的16进制为27 * */ $key = addslashes($key); /* * 经过转义后单引号前面还有一个反斜杠\,这个反斜杠的16进制就是5c * 那么最前面三个字符就是: * ß\' * 对应df 5c 27 * 如果使用utf8,一个汉字占用3个字节,如果是英文就是一个字节 * GBK一个汉字占用两个字节 * 这里我说不清原因,反正老师意思是这里如果使用gbk,就是df和5c一起编码 然后27单独编码 * 那么就又回到了利用单引号关闭左侧,因为单引号已经和第一个奇怪的字符合并成一个汉字了。。。 * 大概就是这样吧 * */ echo $key; echo "<br/>"; $sql = "select * from wp_posts where ID<60 and post_title like '%" . $key . "%'"; echo $sql;那么最后一阶段说是可以在数据库层面
如果mysql_query(‘set names gbk’)类似这样,则仍然可以设置不同的编码,这里大概就是指utf8和gbk。应该也是有影响的,老师这里没有实践罢了。
关键字词:sql,注入