前言

我们都知道,学安全,懂SQL注入是重中之重,因为即使是现在SQL注入漏洞依然存在,只是相对于之前现在挖SQL注入变的困难了。而且知识点比较多,所以在这里总结一下。通过构造有缺陷的代码,来理解常见的几种SQL注入。本文只是讲解几种注入原理,没有详细的利用过程。

如果想要了解Access的详细手工注入过程,可以看我的这篇文章https://www.cnblogs.com/lxfweb/p/12643011.html

如果想要了解MySQL的详细手工注入过程,可以看我的这篇文章https://www.cnblogs.com/lxfweb/p/12655316.html

如果想要了解SQL server的详细手工注入过程,可以看我的这篇文章https://www.cnblogs.com/lxfweb/p/12675023.html

SQL注入原理

SQL注入漏洞的产生需要满足两个条件

  1. 参数用户可控:前端传给后端的参数内容是用户可以控制的。
  2. 参数带入数据库查询:传入的参数拼接到SQL语句并带入数据库查询。

    所以在实际环境中开发者要秉持“外部参数皆不可信原则”进行开发。

几种常见的SQL注入攻击

union注入攻击

先看代码

<?php
$con=mysqli_connect("localhost","root","XFAICL1314","dvwa"); #连接数据库,我这里直接连接了dvwa的数据库
if(mysqli_connect_error())
{
echo "连接失败:" .mysqli_connect_error();
}
$id=$_GET['id'];
$result=mysqli_query($con,"select * from users where `user_id`=".$id);
$row=mysqli_fetch_array($result);
echo $row['user'] . ":" . $row['password'];
echo "<br>";
?>

在union注入页面中,程序获取GET参数id,对用户传过来的id值没有进行过滤,直接拼接到SQL语句中,在数据库中查询id对应的内容,并将这一条查询结果中的user和password 输出到页面。进行union注入攻击前提是页面有回显。

然后就是注入的常规思路,判断类型,判断字段数,使用union查询相关数据。

布尔盲注攻击

先看代码

<?php
$con=mysqli_connect("localhost","root","XFAICL1314","dvwa");
if(mysqli_connect_error())
{
echo "连接失败:" .mysqli_connect_error();
}
$id=$_GET['id'];
if(preg_match("/union|sleep|benchmark/i",$id)){
exit("on");
}
$result=mysqli_query($con,"select * from users where `user_id`=".$id);
$row=mysqli_fetch_array($result);
if ($row) {
exit("yes");
}
else{
exit("no");
}
?>

在布尔盲注页面中,程序先获取GET参数id,通过preg_match()函数判断其中是否存在union sleep benchmark等危险字符。然后将参数id拼接到SQL语句,从数据库查询,如果有结果,返回yes,否则返回no。所以访问这个页面,代码根据查询结果返回只返回yes和no,不返回数据库中的任何结果,所以上一种的union注入在这里行不通。尝试利用布尔盲注。

布尔盲注是指构造SQL判断语句,通过查看页面的返回结果来推测哪些SQL判断是成立的。例如,我们可以判断数据库名的长度构造语句如下。

and length(database())>=1 #依次增加,查看返回结果





通过上面的语句我们可以猜到数据库名长度为4。

接着使用逐字符判断的方式获取数据库库名,数据库库名范围一般都是az,字母09。构造语句如下。

and substr(database(),1,1)=要猜解的字母(转换成16进制)

substr是截取的意思,构造语句的含义是,截取database()的值,从第一个开始,每次返回一个。这里要注意,要和limit语句区分开,limit从0开始排序,substr从1开始排序。因为我知道数据库的第一个字母是d,所以直接换成d,转换成16进制就是0x64。结果如下。



在真实环境中,自己手工的话,工作量有点大,可以借助burp的爆破功能爆破要猜解的字母。

同样,也可以利用substr()来猜解表名和字段。构造语句

and substr((select table_name from information_schema.tables where table_schema=库名 limit 0,1),1,1)=要猜解的字母(这里指表名)



用这样的方法,可以猜解出所有的表名和字段,手工会累死,可以借助burp或者sqlmap。

爆错注入攻击

先看代码

<?php
$con=mysqli_connect("localhost","root","XFAICL1314","dvwa");
if (mysqli_connect_error())
{
echo "连接失败:".mysqli_connect_error();
}
$id=$_GET['id'];
if($result=mysqli_query($con,"select *from users where `user_id`=".$id))
{
echo "ok";
}else{
echo mysqli_error($con);
}
?>

查看代码,在报错注入页面中,程序获取GET参数id后,将id拼接到SQL语句中查询,如果执行成功,就输出ok,如果出错,就通过echo mysqli_error($con)将错误信息输出到页面。我们可以利用这种错误回显,通过updatexml()、floor()等函数将我们要查询的内容显示到页面上。

例如,我们通过updatexml()获取user()的值,构造如下语句。

and updatexml(1,concat(0x7e,(select user()),0x7e),1) #0x7e是~16进制编码

发现查询出了user()的值



同样,我们也可以查询出database()的值

and updatexml(1,concat(0x7e,(select database()),0x7e),1) #0x7e是~16进制编码

查询出了数据库名



我们可以用这种方法查询出剩下的所有表名和字段,只需要构造相关的SQL语句就可以了。

时间盲注攻击

先看代码

<?php
$con=mysqli_connect("localhost","root","XFAICL1314","dvwa");
if (mysqli_connect_error())
{
echo "连接失败:".mysqli_error();
}
$id=$_GET['id'];
if (preg_match("/union/i",$id)){
exit("<html><body>no</body></html>");
}
$result=mysqli_query($con,"select * from users where `user_id`=".$id);
$row=mysqli_fetch_array($result);
if ($row){
exit("<html><body>yes</body></html>");
}
else{
exit("<html><body>no</body></html>");
}
?>

查看代码,在时间盲注页面中,程序获取GET参数id,通过preg_match()函数判断是否存在union危险字符,然后将id拼接到SQL语句中,并带入数据库查询。如果有结果返回yes,没有结果返回no。不返回数据库中的任何数据。

它与布尔盲注的不同在于,时间盲注是利用sleep()或benchmark()等函数让执行时间变长。一般和if(expr1,expr2,expr3)结合使用,这里的if语句的含义为如果expr1为真,则if()返回expr2,否则返回expr3。所以判断数据库的长度,咱们构造的语句如下

if (length(database())>3,sleep(5),1) #判断数据库长度,如果大于3,休眠5秒,否则查询1





由上面图片,我们通过时间可以判断出,数据库的长度为4。

得到长度后,通过substr()来查询数据库的第一个字母,这里和布尔盲注很类似,构造如下语句。

and if (substr(database(),1,1)=库的第一个字母,sleep(5),1)



依次进行猜解。依次类推,可以猜解出数据库完整的库名,表名,字段名和具体数据。手工的话依旧是一个浩大的工程,一般借助工具。

小结

今天对union注入、布尔盲注、报错注入、时间盲注的原理和代码进行了简单的分析。在第二篇文章中,会对堆叠注入、二次注入、宽字节注入、cookie注入等进行简单的分析。

参考文献:Web安全攻防

SQL注入原理及代码分析(一)的更多相关文章

  1. SQL注入原理及代码分析(二)

    前言 上一篇文章中,对union注入.报错注入.布尔盲注等进行了分析,接下来这篇文章,会对堆叠注入.宽字节注入.cookie注入等进行分析.第一篇文章地址:SQL注入原理及代码分析(一) 如果想要了解 ...

  2. XSS原理及代码分析

    前言 XSS又叫跨站脚本攻击,是一种对网站应用程序的安全漏洞攻击技术.它允许恶意用户将代码注入网页,其他用户在浏览网页时就会受到影响.XSS分为三种:反射型,存储型,和DOM型.下面我会构造有缺陷的代 ...

  3. SQL注入原理与解决方法代码示例

    一.什么是sql注入? 1.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网 ...

  4. SQL注入原理讲解,很不错!

    SQL注入原理讲解,很不错! 原文地址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html 1.1.1 摘要 日前,国内最大的程序员 ...

  5. Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

    前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程 ...

  6. 回头探索JDBC及PreparedStatement防SQL注入原理

    概述 JDBC在我们学习J2EE的时候已经接触到了,但是仅是照搬步骤书写,其中的PreparedStatement防sql注入原理也是一知半解,然后就想回头查资料及敲测试代码探索一下.再有就是我们在项 ...

  7. 网络对抗课题4.3.1 SQL注入原理与实践

    网络对抗课题4.3.1 SQL注入原理与实践 原理 SQL注入漏洞是指在Web应用对后台数据库查询语句处理存在的安全漏洞.也就是,在输入字符串中嵌入SQL指令,在设计程序中忽略对可能构成攻击的特殊字符 ...

  8. sql注入原理详解(一)

    我们围绕以下几个方面来看这个问题: 1.什么是sql注入? 2.为什么要sql注入? 3.怎样sql注入? 1.什么是sql注入? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或 ...

  9. 1.sql注入原理

    一.什么是sql注入呢?         所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露V ...

随机推荐

  1. Java动态规划实现最短路径问题

    问题描述 给定一个加权连通图(无向的或有向的),要求找出从每个定点到其他所有定点之间的最短路径以及最短路径的长度. 2.1 动态规划法原理简介 动态规划算法通常用于求解具有某种最优性质的问题.在这类问 ...

  2. java实现罗马数字转十进制

    古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了.之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原 ...

  3. Java实现 蓝桥杯 历届试题 连号区间数

    问题描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增 ...

  4. java代码(2)---Java8 Stream

    stream Java8新特性Stream流,那Stream表达式到底是什么呢,为什么可以使你的代码更加整洁而且对集合的操作效率也会大大提高? 一.概述 1.什么是Stream Stream是一种可供 ...

  5. dfs算法总结

    DFS 深度优先搜索 主要有两种实现方法:栈和递归 什么是DFS?说白了就是一直遍历元素的方式而已,我们可以把它看成是一条小蛇,在每个分叉路口随意选择一条路线走,直到撞到南墙,才会调头返回到上一个分叉 ...

  6. Linux系统调用和ANSI C文件操作的区别

    一.在Linux下对文件操作有两种方式:Linux系统调用和ANSI C文件操作. 1.Linux系统调用调用常用于I/O文件操作,系统调用常用的函数有open.close.read.write.ls ...

  7. android中shape的使用介绍-2环形

    匿名内部类不能修改外部类的临时变量,但属性变量可以访问 参考:http://blog.csdn.net/north1989/article/details/52939888

  8. Python 导入CSV、JSON、XML数据

    常见的机器可读格式包括: - 逗号分隔值(Comma-Separated Values,CSV)- 制表符分隔值(tab-separated values,TSV)- JavaScript 对象符号( ...

  9. router路由配置

    vue项目中router路由配置   介绍 路由:控制组件之间的跳转,不会实现请求.不用页面刷新,直接跳转-切换组件>>> 安装 本地环境安装路由插件vue-router:    c ...

  10. [转] C++项目中的extern "C" {}

    点击阅读原文 引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: #ifdef __cplusplus extern "C" { #endif /*...*/ #if ...