代码审计:如何在全新编程语言中发现漏洞?
字数 1354 2025-08-12 11:34:21

全新编程语言中的漏洞发现与代码审计指南

一、安全标准不一致问题

1.1 中间件与应用程序标准不一致

案例:WSGI与中间件解析差异

  • 当中间件(如nginx)和应用程序桥接器(如gunicorn)对请求解析标准不同时
  • 攻击示例:构造/privateHTTP/1.1/../../public
    • nginx解析为访问/public并放行
    • gunicorn解析为两个请求(/private/public)
    • 绕过安全检查

1.2 数据类型安全标准不一致

案例:NoSQL注入

  • 不同语言对数据类型的处理方式不同
  • 攻击示例:/login?username=admin&password['$ne']=1
    • 被解析为MongoDB查询:db.Users.find({username:'admin',password:{'$ne':'1'}})
    • $ne操作符使密码不为1即可登录成功

1.3 多种注入防御机制冲突

案例:XSS与SQL防御冲突

  • XSS防御:删除所有HTML标签
  • SQL防御:删除黑名单关键字
  • 绕过方法:在关键字中插入<a>标签
    • 例如:<a>SELECT<a>可能绕过两种防御

二、代码与数据边界问题

2.1 不安全的模板渲染

案例:模板注入

  • 开发者已对每个变量进行安全限制
  • 攻击方法:
    • 在user变量输入:)/*
    • 在punc变量输入:*/任意无字母数字shell?>
    • 使punc从数据变为可执行代码

2.2 跨语言数据传递漏洞

案例:YAML反序列化

  • YAML用于存储配置或跨语言数据传输
  • 攻击方法:覆盖YAML文件为恶意内容
    • 示例:构造反弹shell的YAML配置

三、可预测的安全处理方式

3.1 输入矫正漏洞

案例:CVE-2022-30333(unRAR漏洞)

  • 安全限制:阻止../等目录穿越
  • 漏洞成因:将\转换为/的人性化处理
    • ..\被转换为../绕过检查
    • 导致任意目录文件写入

3.2 不安全过滤机制

案例:SQL注入过滤绕过

  • 双写绕过:oorr被过滤为or后仍有效
  • 输入示例:' oorr 1=1#

3.3 可预测的密钥

案例:Flask session密钥

  • 使用主机名作为加密密钥
  • 攻击者获取主机名后可伪造任意session
  • 导致全面控制用户和管理员账户

四、意外的可控变量

4.1 变量存储位置问题

案例:二次注入

  • 变量存储在多个位置(如数据库和session)
  • 攻击方法:
    • 在session中存储' or 1=1#
    • 绕过安全检查修改所有用户密码

4.2 误判变量可控性

案例:User-Agent注入

  • 开发者认为User-Agent不可控
  • 实际可通过HTTP头修改
  • 导致注入漏洞

审计方法论总结

  1. 检查接口标准一致性:关注语言与中间件、数据库等交互时的解析差异
  2. 验证数据与代码边界:特别关注模板渲染、序列化/反序列化过程
  3. 测试安全处理可预测性:尝试绕过过滤和矫正机制
  4. 寻找隐藏的可控点:检查所有可能的输入源,包括非常规变量

关键审计技巧

  • 构造边界测试用例(如../..\)
  • 测试数据类型转换行为(如字符串到数组)
  • 验证所有防御机制的交互效果
  • 检查变量存储的多个位置
  • 测试非常规输入点(User-Agent等)
全新编程语言中的漏洞发现与代码审计指南 一、安全标准不一致问题 1.1 中间件与应用程序标准不一致 案例:WSGI与中间件解析差异 当中间件(如nginx)和应用程序桥接器(如gunicorn)对请求解析标准不同时 攻击示例:构造 /privateHTTP/1.1/../../public nginx解析为访问 /public 并放行 gunicorn解析为两个请求( /private 和 /public ) 绕过安全检查 1.2 数据类型安全标准不一致 案例:NoSQL注入 不同语言对数据类型的处理方式不同 攻击示例: /login?username=admin&password['$ne']=1 被解析为MongoDB查询: db.Users.find({username:'admin',password:{'$ne':'1'}}) $ne 操作符使密码不为1即可登录成功 1.3 多种注入防御机制冲突 案例:XSS与SQL防御冲突 XSS防御:删除所有HTML标签 SQL防御:删除黑名单关键字 绕过方法:在关键字中插入 <a> 标签 例如: <a>SELECT<a> 可能绕过两种防御 二、代码与数据边界问题 2.1 不安全的模板渲染 案例:模板注入 开发者已对每个变量进行安全限制 攻击方法: 在user变量输入: )/* 在punc变量输入: */任意无字母数字shell?> 使punc从数据变为可执行代码 2.2 跨语言数据传递漏洞 案例:YAML反序列化 YAML用于存储配置或跨语言数据传输 攻击方法:覆盖YAML文件为恶意内容 示例:构造反弹shell的YAML配置 三、可预测的安全处理方式 3.1 输入矫正漏洞 案例:CVE-2022-30333(unRAR漏洞) 安全限制:阻止 ../ 等目录穿越 漏洞成因:将 \ 转换为 / 的人性化处理 ..\ 被转换为 ../ 绕过检查 导致任意目录文件写入 3.2 不安全过滤机制 案例:SQL注入过滤绕过 双写绕过: oorr 被过滤为 or 后仍有效 输入示例: ' oorr 1=1# 3.3 可预测的密钥 案例:Flask session密钥 使用主机名作为加密密钥 攻击者获取主机名后可伪造任意session 导致全面控制用户和管理员账户 四、意外的可控变量 4.1 变量存储位置问题 案例:二次注入 变量存储在多个位置(如数据库和session) 攻击方法: 在session中存储 ' or 1=1# 绕过安全检查修改所有用户密码 4.2 误判变量可控性 案例:User-Agent注入 开发者认为User-Agent不可控 实际可通过HTTP头修改 导致注入漏洞 审计方法论总结 检查接口标准一致性 :关注语言与中间件、数据库等交互时的解析差异 验证数据与代码边界 :特别关注模板渲染、序列化/反序列化过程 测试安全处理可预测性 :尝试绕过过滤和矫正机制 寻找隐藏的可控点 :检查所有可能的输入源,包括非常规变量 关键审计技巧 构造边界测试用例(如 ../ 与 ..\ ) 测试数据类型转换行为(如字符串到数组) 验证所有防御机制的交互效果 检查变量存储的多个位置 测试非常规输入点(User-Agent等)