挖掘经验:sql注入经常出现在登录界面、获取HTTP请求头、订单处理等地方。而登录界面的注入现在来说大多是发生在HTTP头里面的client-ip和x-forward-for,一般用来记录登录的ip地址。
 
普通注入:
这里说的普通注入是指最容易利用的sql注入漏洞,比如通过注入union查询就可以查询数据库。源码如下:
<?php
$con=mysqli_connect("localhost","root","123456","test");
// 检测连接
if (mysqli_connect_errno())
{
    echo "连接失败: " . mysqli_connect_error();
}
$id = $_GET['id'];
$result = mysqli_query($con,"select * from users where `id`=".$id);
while($row = mysqli_fetch_array($result))
{
    echo $row['username'] . ": " . $row['address'];
    echo "<br>";
}
?>
含有普通注入漏洞的数据库操作存在一些关键字,比如select from、mysql_connect、mysql_query、mysql_fetch_row等,数据库的查询方式还有update、insert、delete,我们在做白盒审计时,只需要查找这些关键字,即可定向挖掘SQL注入漏洞。
常用语句注释:
mysql_connect() 函数打开非持久的 MySQL 连接。mysql_connect(server,user,pwd,newlink,clientflag)
mysql_query() 函数执行一条 MySQL 查询。
mysql_query(query,connection)
参数
描述
query
必需。规定要发送的 SQL 查询。注释:查询字符串不应以分号结束。
connection
可选。规定 SQL 连接标识符。如果未规定,则使用上一个打开的连接。
mysql_fetch_row() 函数从结果集中取得一行作为数字数组。

语法

mysql_fetch_row(data)
参数
描述
data
必需。要使用的数据指针。该数据指针是从 mysql_query() 返回的结果。

编码注入:

1.宽字节注入:关于编码的小知识
尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范。但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如gbk,作为自己默认的编码类型。也有一些cms为了考虑老用户,所以出了gbk和utf-8两个版本。
 
以gbk字符编码为例,gbk是一种多字符编码
通常来说,一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节。
在php中,我们可以通过输出 echo strlen("我"); 来测试。当将页面编码保存为gbk时输出2,utf-8时输出3。
宽字节注入原理
1、数据库编码(GBK)与PHP编码(utf-8)不一致
2、PHP中使用了用于转义特殊字符的函数:
在mysql中,用于转义(即在字符串中的符号如单引号 ' ,双引号 " 反斜杠 \ 和 NULL 字符前加上"\")的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc(即魔术引号开关),不过高版本的PHP将去除这个特性。
在使用Php连接mysql数据库时,当设置“set character set client=gbk”时会导致一个编码转换的注入问题,也就是宽字节注入。当存在宽字节注入时,注入参数里带入%df%27,即可把程序中过滤的\(%5c)吃掉。魔术引号:https://www.cnblogs.com/i-honey/p/7905953.html
 
出现这个漏洞的原因是在PHP连接Mysql的时候执行了如下设置:
set character_set_client=gbk
解决方法:在执行查询前先执行SET NAMES 'gbk',character_set_client=binary设置character_set_client为binary
测试代码:
?php
 
$conn = mysql_connect('localhost', 'root', '123456') or die('bad!');
mysql_select_db('test', $conn) OR emMsg("数据库连接失败");
mysql_query("SET NAMES 'gbk'",$conn);
 
$id = addslashes($_GET['id']);
$sql="SELECT * FROM kuanzifu WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql, $conn) or die(mysql_error());
$row = mysql_fetch_array($result);
 
    if($row)
    {
      echo $row['username'] . $row['address'];
      }
    else
    {
    print_r(mysql_error());
    }
 
?>
</font>
<?php
 
echo "<br>The Query String is : ".$sql ."<br>";
 
?>
对宽字节注入的挖掘方法也比较简单,只要搜索如下几个关键字即可:
SET NAMES         character_set_client=gbk      mysql_set_charset('gbk')
二次urldecode注入
只要字符被进行转换就有可能产生漏洞,现在的web程序大多都会进行参数过滤,通常使用addslashes()、mysql_real_escape_string()、mysql_escape_string()函数或者开启GPC的方式来防止注入,也就是给单引号(')、双引号(")、反斜杠(\)和NULL加上反斜杠转义。
如果某处使用了urldecode或者rawurldecode函数,则会导致二次解码生成单引号引发注入。原理是我们提交参数到webserver时,webserver会自动解码一次,假设目标开启GPC,我们提交了/1.php?id=1%2527,因为我们提交的参数里面没有单引号,所以第一次解码后的结果为id=1%27,%25解码的结果为%,如果程序里面使用了urldecode或者rawurldecode函数来解码id函数,则解码后的结果为id=1',单引号成功出现引发注入。
既然知道了原理主要是由于urldecode使用不当造成的,那我们就可以通过搜索urldecode和rawurldecode函数来挖掘urldecode注入漏洞。
 
 
 
总结:SQL注入漏洞的防范
在PHP中可以通过魔术引号来防范,不过魔术引号在PHP5.4后被取消,并且gpc在遇到int类型的注入时显得不那么给力了,所以通常用得多的还是过滤函数和类。当然最好的解决方案是利用预编译的方式。
1.gpc/runtime魔术引号
magic_quotos_gpc负责对GET、POST、COOKIE的值进行过滤,magic_quotos_runtime对从数据库或者文件中获取的数据进行过滤。通常在开启2个选项后能防止部分SQL注入漏洞,但在int类型是没多大用。
2.addslashes函数
addslashes函数过滤的值范围和GPC是一样的。他只是一个简单的检查的参数的函数,大多数程序使用它是在程序的入口,进行判断如果没有开启GPC,则使用它对$_POST/$_GET等变量进行过滤,不过它的参数必须是string类型。
3.mysql_[real_]escape_string函数
这两个函数都是对字符串进行过滤,在PHP4.0.3以上版本才存在。区别在于mysq_real_escape_string接受的是一个连接句柄并根据当前字符集转义字符串,所以推荐使用mysql_real_escape_string。
4.intval等字符进行转换
上面提到的过滤方式,在int类型注入时效果并不好,比如可以通过报错或者盲注等方式绕过,这时候intval等函数就起作用了,intval的作用是将变量转换为int类型。这里举例intval是要表达一种方式,一种利用参数类型白名单的方式来防止漏洞。
<?php
$id=intval("1 union select  ");
echo $id;
?>
以上代码输出:1
5.过滤危险字符:多数cms都采用过滤危险字符的方式,例如,采用正则表达式匹配union、sleep、load_file等关键字,如果匹配到,就退出程序。
6.PDO 预编译语句
预编译:指的是预先编译SQL的结构的一种执行SQL的方法。具体见:https://www.cnblogs.com/xiaoyoucai/p/7397163.html
其实使用PDO预编译语句,需要注意的是,不要将变量直接拼接到PDO语句中,而是使用占位符进行数据库的增加、删除、修改、查询。

最新文章

  1. vim vi Ubuntu
  2. [UCSD白板题] Maximum Pairwise Product
  3. paip.2013年技术趋势以及热点 v2.0 cae
  4. adb 服务端口2037被占,导致adb和appium无法工作
  5. ASP.NET实现大文件下载
  6. couchbase单向同步
  7. fwite写入文件
  8. xcode编译错误总结
  9. 《Gulp 入门指南》 : 使用 gulp 压缩 JS
  10. C# attribute_特性
  11. uml系列图(一)——与uml的第一次约会
  12. 这一次带你彻底了解Cookie
  13. [array] leetcode - 31. Next Permutation - Medium
  14. Oracle总结【视图、索引、事务、用户权限、批量操作】
  15. boost asio allocation
  16. Java调用第三方http接口的方式
  17. JAVA BigDecimal 用法
  18. springAop @AfterReturning注解 获取返回值
  19. please select android sdk
  20. cocos JS 定时器

热门文章

  1. 【C语言】计算N名同学的某门功课的平均成绩
  2. 【C语言】找出1000以内的水仙花数
  3. MYSQL命令练习及跳过数据库密码进行密码重新设置
  4. chrome 2行换行省略号 ... text-ellipse
  5. nginx-cache
  6. LNMP环境搭建(PHP7.4.0)
  7. rsync安装与配置使用 数据同步方案(centos6.5)
  8. 吴裕雄--天生自然Numpy库学习笔记:Numpy 数组操作
  9. Attributes for Slot
  10. 洛谷P1060开心的金明(滚动数组优化)