您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
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,注入