某bip漏洞挖掘-从0day到1day的伤心之旅
字数 2475 2025-10-13 22:56:21
教学文档:从Protobuf反序列化到SQL注入漏洞的挖掘与分析
一、 漏洞背景与核心思想
本案例涉及一个名为bip的Java应用程序。漏洞挖掘的起点是一个程序异常,研究者通过逆向工程和动态调试,追踪到一个基于Google Protocol Buffers(Protobuf)的反序列化过程,并最终发现了一个SQL注入漏洞。
核心思想:程序使用Protobuf格式接收和处理客户端数据。在成功反序列化数据后,程序会从反序列化得到的对象中提取参数,并在未经过充分安全过滤的情况下,直接将参数拼接到SQL语句中执行,从而导致SQL注入漏洞。
二、 技术知识点详解
1. Protocol Buffers (Protobuf)
- 是什么:Google开发的一种语言中立、平台无关、可扩展的序列化数据结构的机制。它比XML/JSON更小、更快、更简单。
- 在漏洞中的作用:攻击载荷(Payload)是通过Protobuf格式序列化的。要构造有效的攻击数据,必须先理解目标程序期望的Protobuf数据结构,并能够生成合法的序列化字节流。
- 关键步骤:
- 定义.proto文件:这是一个蓝图文件,描述了你要序列化的数据的结构。
- 生成Java代码:使用Protobuf编译器(
protoc)根据.proto文件生成对应的Java类(如PBLoginInfo)。这些类提供了构建(Builder)、序列化(toByteArray())和反序列化(parseFrom())的方法。 - 序列化与反序列化:在客户端,使用生成的类构建对象并序列化成字节流发送。在服务端,接收字节流并反序列化回对象。
2. 漏洞触发流程分析
文章描述了清晰的漏洞触发链:
- 入口点:程序接收到经过Base64编码的Protobuf数据。
- 反序列化:程序调用
parseFrom方法(内部会调用parsePartialFrom和mergeFrom)对数据进行反序列化,将其转换成一个PBLoginInfoJava对象。 - 数据提取:反序列化成功后,程序执行到
this.loginContext.getAccountName().length()这一行。为了通过此处的逻辑检查(避免空指针异常或长度校验失败),需要确保PBLoginInfo对象中的accountName字段有值。 - 漏洞触发:程序调用
setInvocationInfo方法,在此方法内部,通过getUser()方法获取之前反序列化得到的用户信息(如accountName)。 - SQL注入:
getUser()方法内部,将用户输入的accountName直接拼接到SQL查询字符串中,形成了SQL注入漏洞。例如,拼接的代码可能类似于:String sql = "SELECT ... FROM ... WHERE account_name = '" + accountName + "'"; - 命令执行:在特定配置下(如SQL Server数据库且已开启
xp_cmdshell),攻击者可以通过SQL注入执行系统命令,从而完全控制服务器。
三、 漏洞复现详细步骤
步骤一:重构Protobuf数据结构
- 通过逆向分析或调试,推断出目标程序用于反序列化的
.proto文件结构。文中作者通过“拷打AI”得到了一个近似的数据结构定义(PBLoginInfo.proto)。 - 关键字段是
account_name(字段编号10),因为漏洞点正是使用这个字段的值。
步骤二:生成PoC数据
- 使用
protoc编译器,根据.proto文件生成Java类(ProtoBufferPractice.java)。 - 编写Java代码(
MakeTest.java),利用生成的类构建一个PBLoginInfo对象,并为关键字段(尤其是accountName)赋值。注意:accountName的值需要构造为SQL注入载荷。.setAccountName(ByteString.copyFromUtf8("bip' AND 1=@@VERSION;-- ")) - 将对象序列化为字节数组(
info.toByteArray()),然后进行Base64编码,得到最终的Payload。
步骤三:发送Payload进行利用
- 将生成的Base64字符串作为请求参数,发送给存在漏洞的应用程序接口。
- 应用程序会执行上述“漏洞触发流程”,将恶意载荷拼接到SQL语句中,导致注入的SQL代码被执行。
四、 后利用思路
文章简要提到了漏洞利用后的进一步操作:
- 获取路径:利用另一个文件读取接口,通过触发报错信息来泄露Web应用程序在服务器上的绝对路径。
- 写入Webshell:在能够执行系统命令的前提下(通过
xp_cmdshell),向泄露的绝对路径中写入一个JSP格式的Webshell文件。 - 控制服务器:通过访问这个Webshell,攻击者可以获得一个稳定的远程控制通道,进而完全控制服务器。
五、 关键总结与防御建议
关键点总结
- 漏洞根源:并非Protobuf本身有漏洞,而是程序在使用反序列化后的数据时存在不安全操作(直接拼接SQL字符串)。
- 技术难点:漏洞挖掘的难点在于逆向分析复杂的反序列化流程,并准确重构出Protobuf数据结构。一旦突破这个点,漏洞的利用就相对直接。
- 攻击链:
构造Protobuf数据 -> 序列化/编码 -> 发送 -> 服务端反序列化 -> 危险数据使用 -> SQL注入。
防御建议
- 永远不要信任用户输入:即使数据经过了复杂的序列化/反序列化过程,其内容仍然是用户可控的。
- 使用参数化查询(Prepared Statements):这是防止SQL注入最有效的方法。数据库驱动程序会正确处理参数,确保用户输入不会被解析为SQL代码。
- 对反序列化操作进行白名单校验:限制可以反序列化的类,避免反序列化漏洞。
- 最小权限原则:数据库连接账户应遵循最小权限原则,避免使用具有
sysadmin或类似高权限的账户,特别是不要轻易开启xp_cmdshell等危险功能。
这份文档详尽地解析了从Protobuf反序列化到SQL注入漏洞的完整知识链。希望它对您的学习有所帮助!