Protobuf 协议安全测试

栏目: 服务器 · 发布时间: 7年前

内容简介:1. Protobuf 是什么Protobuf 是 google 开源的一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信和数据存储。

本文将介绍 Protobuf 协议在安卓 APP 中的应用,以及如何开展相关接口的安全测试。 文中用到的 vuls 漏洞应用代码及应用可以在https://github.com/AndroidAppSec/vuls/releases/tag/v4.1 下载。

前言

在对安卓 APP 的网络请求进行安全测试的时候,经常会遇到不同的数据传输协议,比如基于 XML 的、基于 JSON 的、甚至是基于二进制流的。本文将介绍一种常用的数据传输协议-- Protobuf 的安全测试方法

1. Protobuf 是什么  

Protobuf 是 google 开源的一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信和数据存储。

其具有体积小、序列化和传输速度快、维护简单的特点,被越来越多的安卓 APP 使用。

其目前最新的版本为 proto3,相较于之前的版本支持更多的语言,语法也更为简洁。本文主要是以 proto3 为讨论对象。

2. Protobuf 语法  

Protobuf 数据结构文件 一般是以  .proto 结尾的文本文件。 拿官方文档中的例子来简单介绍一下。 以下是一个定义搜索请求消息的案例:

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

文件的第一行指定了协议版本,如果不定义则默认为 proto2。这必须是文件的第一个非空的非注释行。

message 定义了 SearchRequest 消息,并指定了三个字段(以分号分割)。每一个字段中指定了字段数据类型、字段名称和字段编号。

更多内容请查看官方文档(https://developers.google.com/protocol-buffers/docs/proto3)。

3. 在 Android Studio 中使用 Protobuf

3.1 搭建开发环境

  • 在 Project/build.gradle 中加入 protobuf 插件

classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.6'

Protobuf 协议安全测试

  • 在 app/build.gradle 中加入如下配置,头部加上:

apply plugin: 'com.google.protobuf'

Protobuf 协议安全测试

  • android{ } 中加入

sourceSets { 
    main { 
        // 定义 java 文件目录 
        java { 
            srcDir 'src/main/java' 
        } 
        // 定义proto文件目录 
        proto { 
            srcDir 'src/main/proto' 
        } 
    } 
}

Protobuf 协议安全测试

  • android{ } 同级中加入

protobuf { 
    //配置protoc编译器 
    protoc { 
        artifact = 'com.google.protobuf:protoc:3.5.1' 
    } 
    //这里配置生成目录,编译后会在build的目录下生成对应的java文件 
    generateProtoTasks { 
        all().each { task -> 
            task.builtins { 
                remove java 
            } 
            task.builtins { 
                java {} 
            } 
        } 
    } 
}

Protobuf 协议安全测试

  • dependencies 中加入 protobuf 相关依赖

implementation 'com.google.protobuf:protobuf-java:3.6.1'
implementation 'com.google.protobuf:protoc:3.6.1'

Protobuf 协议安全测试

  • 安装 Protobuf Support 插件

Protobuf 协议安全测试

插件安装完成后需重启 Android Studio。

3.2 编写 proto 文件

这里我们打算用 protobuf 来实现登录的功能。

在 src/main 下建立 proto 文件夹,建立 LoginRequest.proto 文件,内容如下:

syntax = "proto3"; 
import public "Message.proto";

//登录请求结构体
message LoginRequest {
string username = 1;
string password = 2;
}

//登录响应结构体
message LoginResponse {
int32 code = 1;
Message msg = 2;
}

Message.proto 文件,内容如下:

syntax = "proto3"; 

// 返回消息体
message Message {
int32 id = 2;
string content = 1;
}

3.3 生成对应的 Java 文件

Sync Project 或者  Build-->Clean Project,会在 \app\build\generated\source\proto 中生成对应的 Java 文件。

Protobuf 协议安全测试

4. 编写测试应用

4.1 编写安卓客户端 登录功能代码

将生成的 Java 文件拷贝到 src 目录下:

Protobuf 协议安全测试

登录功能的主要代码如下:

public void login(View view){ 
    username = ((EditText) findViewById(R.id.et_ac_username)).getText().toString(); 
    password = ((EditText) findViewById(R.id.et_ac_password)).getText().toString(); 
    String url = "http://192.168.8.233/pblogin"; 
    final LoginRequestOuterClass.LoginRequest loginRequest = LoginRequestOuterClass.LoginRequest .newBuilder() .setUsername(username) .setPassword(password) .build(); 
    OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); 
    RequestBody requestBody = RequestBody.create( MediaType.parse("application/pb"), loginRequest.toByteArray()); 
    Request request = new Request.Builder().url(url).post(requestBody).build(); 
    Call call = okHttpClient.newCall(request); 
    call.enqueue(new Callback() { 
        @Override 
        public void onFailure(Call call, IOException e) { 
        e.printStackTrace(); 
        runOnUiThread(new Runnable() { 
            @Override 
            public void run() { 
                Toast.makeText(ProtoActivity.this, "请求失败", Toast.LENGTH_LONG).show(); 
            } 
        }); 
    } 
        @Override 
        public void onResponse(Call call, Response response) throws IOException { 
            ResponseBody body = response.body(); 
            LoginRequestOuterClass.LoginResponse loginResponse = LoginRequestOuterClass.LoginResponse.parseFrom(body.bytes()); 
            final int code = loginResponse.getCode(); 
            MessageOuterClass.Message responseMsg = loginResponse.getMsg(); 
            final int id = responseMsg.getId(); 
            final String content = responseMsg.getContent(); 
            runOnUiThread(new Runnable() { 
                @Override 
                public void run() { 
                    if (id == 1){ 
                        Toast.makeText(ProtoActivity.this, content, Toast.LENGTH_LONG).show(); 
                    }else { 
                        Toast.makeText(ProtoActivity.this, content + code, Toast.LENGTH_LONG).show(); 
                    }
                } 
            }); 
        } 
    }); 
}

4.2 编写服务端代码

服务端使用 Springboot 框架,在 pom 文件中加入 protobuf 依赖:

<dependency> 
    <groupId>com.google.protobuf</groupId> 
    <artifactId>protobuf-java</artifactId> 
    <version>3.6.1</version> 
</dependency>

Controller 逻辑代码如下:

@RequestMapping("/pblogin") 
public void login(HttpServletRequest request, HttpServletResponse response) throws IOException { 
    request.setCharacterEncoding("utf-8"); 
    response.setCharacterEncoding("utf-8"); 
    LoginRequestOuterClass.LoginRequest loginRequest = LoginRequestOuterClass.LoginRequest .parseFrom(request.getInputStream()); 
    String username = loginRequest.getUsername(); 
    String password = loginRequest.getPassword(); 
    LoginRequestOuterClass.LoginResponse.Builder builder = LoginRequestOuterClass.LoginResponse.newBuilder(); 
    MessageOuterClass.Message.Builder messageBuilder = MessageOuterClass.Message.newBuilder(); 
    if ("admin".equals(username) && "12345".equals(password)){ 
        builder.setCode(200); 
        messageBuilder.setId(1); 
        messageBuilder.setContent("登录成功!"); 
        builder.setMsg(messageBuilder.build()); 
    }else { 
        builder.setCode(200); 
        messageBuilder.setId(-1); 
        messageBuilder.setContent("用户名或密码错误!"); 
        builder.setMsg(messageBuilder.build()); 
    } 
    builder.build().writeTo(response.getOutputStream()); 
}

原生应用是指开发的安卓应用,H5 是指通过 WebView 加载的 web 应用。很多情况下原

5. 抓包测试

5.1 启动服务端

执行命令 java -jar server-1.1.jar

5.2 配置手机代理为 burp

5.3 登录

Protobuf 协议安全测试

5.4 burp 抓包请求如下

Protobuf 协议安全测试

以 hex 方式查看一下,就知道 请求与普通的 http 请求还是不同的,是基于二进制序列化的。

Protobuf 协议安全测试

将请求发送到 repeter,然后修改参数,会报错,提示协议解析错误。

Protobuf 协议安全测试

6. BlackBox Protobuf Burp Extension

6.1 介绍

nccgroup 开源了一个 burp 插件专门用来做 protobuf 协议的安全测试,叫做 BlackBox,地址 https://github.com/nccgroup/blackboxprotobuf。

6.2 安装

  • 安装 Jpython

  • 依次运行命令

    git clone https://github.com/nccgroup/blackboxprotobuf

    cd blackboxprotobuf

git submodule update --init

  • 在 Burp 的 Extender 标签中安装插件

Protobuf 协议安全测试

  • 安装成功后会出现 “Protobuf Type Editor” 标签页

Protobuf 协议安全测试

6.3 使用

插件安装成功之后,burp 再抓取到 protobuf 协议数据时候,会自动添加 protobuf 标签,提供浏览和修改请求数据的功能 。

Protobuf 协议安全测试

Protobuf 协议安全测试

注:

  • BlackBox Protobuf 插件是通过 HTTP 请求头的 Content-Type 来判断数据是否为 protobuf 协议的。也就是说如果要插件去自动分析 protobuf 协议,需要将对应的  Content-Type 值 加入到 BlackBox Protobuf 插件的分析列表中。可以在  blackboxprotobuf/blackboxprotobuf/burp/editor.py 中进行添加。

Protobuf 协议安全测试

  • BlackBox Protobuf 插件可以在 Proxy 和 Repeater 中使用,但是在 Intruder 中无效。

7. 逆向 Protobuf 协议格式

对于 Protobuf 协议来说,只要能获取到一个数据结构体中的字段信息,就可以去生成相应的数据。字段信息包括: 字段数据类型、字段名称和字段编号。

使用 Jadx 打开 vuls 应用,找到对应的代码如下:

Protobuf 协议安全测试

上面的红框中,可以获取到字段 password(string类型)和 username(string类型)。

Protobuf 协议安全测试

上面的红框中,可以获取到字段 password 编码为 2,username编码为 1。

这样就可以还原出 LoginRequest 的请求结构体

//登录请求结构体 
message LoginRequest { 
    string username = 1; 
    string password = 2; 
} 

之后,就可以按照前面讲的自行生成对应的 java 类,然后编写程序进行安全测试。

8. 参考

https://github.com/huangdali/Android_ProtoBuf_Demo

https://developers.google.com/protocol-buffers/docs/overview

https://www.jianshu.com/p/2265f56805fa

https://developers.google.com/protocol-buffers/docs/proto3

https://github.com/nccgroup/blackboxprotobuf

https://www.kaifaxueyuan.com/basic/protobuf3.html

https://blog.csdn.net/kpioneer123/article/details/51491739

- End -


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art and Science of CSS

The Art and Science of CSS

Jonathan Snooks、Steve Smith、Jina Bolton、Cameron Adams、David Johnson / SitePoint / March 9, 2007 / $39.95

Want to take your CSS designs to the next level? will show you how to create dozens of CSS-based Website components. You'll discover how to: # Format calendars, menus and table of contents usin......一起来看看 《The Art and Science of CSS》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器