go-pwn中的protobuf
字数 1468 2025-08-20 18:17:53

Go Pwn中的Protobuf分析与利用

1. Protobuf基础

1.1 Protobuf在Go Pwn中的作用

在Go Pwn的堆题中,结构体通常通过Protobuf来传递。Protobuf是一种轻量级的数据交换格式,常用于网络通信和数据存储。

1.2 Protobuf类型定义

Protobuf定义了多种数据类型,每种类型对应一个枚举值:

typedef enum {
    PROTOBUF_C_TYPE_INT32,     // 0 - int32
    PROTOBUF_C_TYPE_SINT32,    // 1 - signed int32
    PROTOBUF_C_TYPE_SFIXED32,  // 2 - signed int32 (4 bytes)
    PROTOBUF_C_TYPE_INT64,     // 3 - int64
    PROTOBUF_C_TYPE_SINT64,    // 4 - signed int64
    PROTOBUF_C_TYPE_SFIXED64,  // 5 - signed int64 (8 bytes)
    PROTOBUF_C_TYPE_UINT32,    // 6 - unsigned int32
    PROTOBUF_C_TYPE_FIXED32,   // 7 - unsigned int32 (4 bytes)
    PROTOBUF_C_TYPE_UINT64,    // 8 - unsigned int64
    PROTOBUF_C_TYPE_FIXED64,   // 9 - unsigned int64 (8 bytes)
    PROTOBUF_C_TYPE_FLOAT,     // 10 - float
    PROTOBUF_C_TYPE_DOUBLE,    // 11 - double
    PROTOBUF_C_TYPE_BOOL,      // 12 - boolean
    PROTOBUF_C_TYPE_ENUM,      // 13 - enumerated type
    PROTOBUF_C_TYPE_STRING,    // 14 - UTF-8 or ASCII string
    PROTOBUF_C_TYPE_BYTES,     // 15 - arbitrary byte sequence
    PROTOBUF_C_TYPE_MESSAGE    // 16 - nested message
} ProtobufCType;

1.3 关键偏移量

在分析Protobuf结构时,有几个关键偏移量需要注意:

  • 第一个字节是变量的初值
  • +8偏移处决定Protobuf中的变量类型(参考上表)
  • 0x10偏移处对应着这个偏移

2. 工具准备

2.1 安装pbtk工具

pbtk是一个用于分析Protobuf的工具:

sudo apt install python3-pip git openjdk-11-jre libqt5x11extras5 python3-pyqt5.qtwebengine python3-pyqt5
sudo pip3 install protobuf pyqt5 pyqtwebengine requests websocket-client
git clone https://github.com/marin-m/pbtk
cd pbtk

2.2 使用pbtk提取Protobuf定义

有两种使用方式:

  1. GUI模式:./gui.py
  2. 命令行模式:
./extractors/from_binary.py [-h] input_file [output_dir]

提取后生成.proto文件,然后可以生成对应的Python文件:

protoc --python_out=./ ./devicemsg.proto

3. 案例分析

3.1 CISCN2024初赛 ezbuf

3.1.1 题目分析

  • 需要手动分析提取Protobuf定义
  • 关键结构:
    syntax = "proto2";
    message devicemsg {
        required bytes whatcon = 1;
        required sint64 whattodo = 2;
        required sint64 whatidx = 3;
        required sint64 whatsize= 4;
        required uint32 whatsthis= 5;
    }
    

3.1.2 功能分析

  • add: 数据(msg)在堆上,根据大小申请相应堆块
  • delete: 存在UAF,可以double free,但有次数限制
  • show: 可以泄露信息,但show三次会关闭标准输出
  • clean: 看似无操作,实际会处理输入的msg并申请堆块

3.1.3 利用思路

  1. 泄露heapbase和libcbase
  2. 通过有限的delete次数实现多次任意地址申请
  3. 利用tcache_perthread结构进行攻击
  4. 通过打stdout泄露stack,最后实现ORW

3.2 CISCN2024初赛 SuperHeap

3.2.1 题目特点

  • 可以直接用pbtk提取Protobuf定义
  • 使用一个堆块存储其他堆块信息

3.2.2 逆向分析

  • add函数:对输入数据进行base32解密,再对解密后的date,title,author,isbn进行protobuf获取数据,再进行base64解密
  • delete函数:检查有无UAF
  • edit函数:没有长度限制,可以任意写
  • show函数:常规打印功能

3.2.3 利用思路

  1. 利用edit函数的无长度限制特性实现任意写
  2. 构造IO链进行攻击
  3. 布置ROP链实现最终利用

4. 利用技巧

4.1 堆布局技巧

  • 通过多次add和delete创造理想的堆布局
  • 利用smallbin和unsorted bin泄露libc地址
  • 通过tcache poisoning实现任意地址写

4.2 泄露技巧

  • 通过show函数泄露heap和libc地址
  • 当标准输出被关闭时,可以通过IO结构体泄露信息
  • 利用environ变量泄露栈地址

4.3 最终利用

  • 构造ROP链实现ORW (Open-Read-Write)
  • 利用setcontext进行栈迁移
  • 通过文件描述符操作读取flag

5. 防御与绕过

5.1 常见防御

  • Protobuf标志抹除
  • 堆操作次数限制
  • 标准输出关闭

5.2 绕过方法

  • 手动分析Protobuf结构
  • 精心设计堆布局以最大化利用有限的操作次数
  • 通过其他方式(如IO结构体)实现信息泄露

6. 总结

Go Pwn中的Protobuf分析需要结合逆向工程和堆利用技巧。关键点包括:

  1. 正确识别和提取Protobuf结构
  2. 理解题目中的堆管理机制
  3. 在有限的操作次数内实现信息泄露和任意写
  4. 最终构造有效的利用链

通过案例分析和工具使用,可以系统性地掌握这类题目的解题方法。

Go Pwn中的Protobuf分析与利用 1. Protobuf基础 1.1 Protobuf在Go Pwn中的作用 在Go Pwn的堆题中,结构体通常通过Protobuf来传递。Protobuf是一种轻量级的数据交换格式,常用于网络通信和数据存储。 1.2 Protobuf类型定义 Protobuf定义了多种数据类型,每种类型对应一个枚举值: 1.3 关键偏移量 在分析Protobuf结构时,有几个关键偏移量需要注意: 第一个字节是变量的初值 +8偏移处决定Protobuf中的变量类型(参考上表) 0x10偏移处对应着这个偏移 2. 工具准备 2.1 安装pbtk工具 pbtk是一个用于分析Protobuf的工具: 2.2 使用pbtk提取Protobuf定义 有两种使用方式: GUI模式: ./gui.py 命令行模式: 提取后生成.proto文件,然后可以生成对应的Python文件: 3. 案例分析 3.1 CISCN2024初赛 ezbuf 3.1.1 题目分析 需要手动分析提取Protobuf定义 关键结构: 3.1.2 功能分析 add: 数据(msg)在堆上,根据大小申请相应堆块 delete: 存在UAF,可以double free,但有次数限制 show: 可以泄露信息,但show三次会关闭标准输出 clean: 看似无操作,实际会处理输入的msg并申请堆块 3.1.3 利用思路 泄露heapbase和libcbase 通过有限的delete次数实现多次任意地址申请 利用tcache_ perthread结构进行攻击 通过打stdout泄露stack,最后实现ORW 3.2 CISCN2024初赛 SuperHeap 3.2.1 题目特点 可以直接用pbtk提取Protobuf定义 使用一个堆块存储其他堆块信息 3.2.2 逆向分析 add函数:对输入数据进行base32解密,再对解密后的date,title,author,isbn进行protobuf获取数据,再进行base64解密 delete函数:检查有无UAF edit函数:没有长度限制,可以任意写 show函数:常规打印功能 3.2.3 利用思路 利用edit函数的无长度限制特性实现任意写 构造IO链进行攻击 布置ROP链实现最终利用 4. 利用技巧 4.1 堆布局技巧 通过多次add和delete创造理想的堆布局 利用smallbin和unsorted bin泄露libc地址 通过tcache poisoning实现任意地址写 4.2 泄露技巧 通过show函数泄露heap和libc地址 当标准输出被关闭时,可以通过IO结构体泄露信息 利用environ变量泄露栈地址 4.3 最终利用 构造ROP链实现ORW (Open-Read-Write) 利用setcontext进行栈迁移 通过文件描述符操作读取flag 5. 防御与绕过 5.1 常见防御 Protobuf标志抹除 堆操作次数限制 标准输出关闭 5.2 绕过方法 手动分析Protobuf结构 精心设计堆布局以最大化利用有限的操作次数 通过其他方式(如IO结构体)实现信息泄露 6. 总结 Go Pwn中的Protobuf分析需要结合逆向工程和堆利用技巧。关键点包括: 正确识别和提取Protobuf结构 理解题目中的堆管理机制 在有限的操作次数内实现信息泄露和任意写 最终构造有效的利用链 通过案例分析和工具使用,可以系统性地掌握这类题目的解题方法。