大家好,我是TheWeiJun,欢迎来到我的公众号。在现代互联网中,某些网站、App会使用gRPC进行数据传输,以加强数据的安全性和保密性。然而,逆向加密算法并不是一件简单的事情。本文将探讨如何逆向猿人学App的gRPC协议,向读者介绍这一过程中所涉及的技术和工具,并提供详细的步骤和示例代码,以帮助读者更好地理解和掌握gRPC原理与实现。
特别声明:本公众号文章只作为学术研究,不作为其他不法用途;如有侵权请联系作者删除。
目录
一、前言介绍
二、APP分析
三、抓包分析
四、算法还原
五、思路总结
趣味模块
依依是一名热爱编程的小女孩,最近她开始对gRPC逆向分析产生了浓厚的兴趣。一天,她在网络上找到了一份开源的gRPC框架代码,决定用自己的方式来分析它。在分析的过程中,依依遇到了无数的困难和挑战,但是她从不放弃,一直努力地学习和尝试。最终,她成功地找到了一个漏洞,并向开发团队提出了修复建议。通过这次经历,依依不仅学会了更多的编程技能,还培养了自己的解决问题的能力。她深深意识到,只要有足够的热情和毅力,就能克服任何难关,实现自己的梦想。依依公众号如下:
逆向与爬虫的故事
专注于网络爬虫、JS逆向、APP逆向、安全攻防实战经验分享及总结。
一、前言介绍
1、什么是gRPC?
gRPC 是一个高性能、开源和通用的 RPC 框架,面向服务端和移动端,基于 HTTP/2 设计。架构如下:
2、gRPC特点
-
语言中立,支持多种语言;
-
基于 IDL 文件定义服务,通过 proto3 工具生成指定语言的数据结构、服务端接口以及客户端 Stub;
-
通信协议基于标准的 HTTP/2 设计,支持双向流、消息头压缩、单 TCP 的多路复用、服务端推送等特性,这些特性使得 gRPC 在移动端设备上更加省电和节省网络流量;
-
序列化支持 PB(Protocol Buffer)和 JSON,PB 是一种语言无关的高性能序列化框架,基于 HTTP/2 + PB, 保障了 RPC 调用的高性能。
3、gRPC代码生成
-
所有gRPC框架都为代码生成提供了一流的支持。gRPC的开发核心是*.proto文件,它定义了gRPC服务和消息的约定。根据这个文件,gRP框架将生成服务基类,消息和完整的客户端代码。
-
通过在服务器和客户端之间共享*.proto文件,可以从端到端生成消息和客户端代码。客户端的代码生成消除了客户端和服务器上的重复消息,并为您创建了一个强类型的客户端。无需编写客户端代码,可在具有许多服务和应用程序中节省大量开发时间。
二、APP分析
1、使用jadx打开猿人学APP进行分析,截图如下:
2、直接搜索第四题,定位java代码位置,截图如下:
总结:和前面的题sign加密一致,主要的逻辑是将时间戳及当前页数放入到函数中去执行,java层被混淆了。我们可以看到红色箭头部分调用了native的方法,接下来我们抓包分析下整个过程吧。
三、抓包分析
1、和前面的题流程一样,我们使用drony设置代理,再使用charles进行抓包,打开APP后发现看不到任何数据包。网上搜索gRPC框架的信息后,看到都是使用wireshark进行抓包分析,接下来我们使用wireshark进行抓包分析。
2、我们先安装一个tcpdump,并将tcpdump放置到手机/data/local/tmp目录中,下载地址和相关命令如下:
下载路径:http://www.strazzere.com/android/tcpdump
adb push tcpdump /data/local/tmp/
添加执行权限
➜ ~ adb shell
polaris:/ $ su
polaris:/ # cd data/local/tmp/
polaris:/data/local/tmp # ls
frida-server-14.2.8-android-arm64 system
re.frida.server tcpdump
1|polaris:/data/local/tmp # chmod 777 tcpdump
3、执行上面命令后,运行截图如下所示:
4、接下来使用tcpdump静态抓取分析,手机抓取pacp格式数据文件,使用如下命令启动抓包工具:
tcpdump -p -vv -s0 -w ./capture.pcap
5、然后我们刷新第四题进行数据包加载,看到本地生成capture.pcap文件后,截图如下所示:(然后我们关闭tcpdump静态抓包分析)
6、接下来我们使用wireshark工具打开刚刚生成的capture.pcap文件,并搜索指定ip端口9901(端口和ip在后面的分析中会用到),截图如下所示:
7、通过查看关键字grpc定位到指定的链接,然后执行如下图所示转换,即可将tcp请求转为grpc协议的数据:
8、转换完成后,我们能够查看到发包请求体,截图如下:
总结:上图中的Field(1)即为页数,Field(2)为时间戳,Field(3)为sign参数,我们都能够和frida hook到的值进行一一对应了。接下来我们分析下response,来找找规律吧。
9、我们打开response响应区域,截图如下所示:
总结:我们通过分析图中红色的箭头,能够看到一组数字,这个就是gRPC响应给我们的数据,拿到他以后,我们就能够将每一页的数据相加完成答题了。接下来,我们进入grpc源码编写环节。
四、算法还原
1、在GoLand中根据上面提供的有用信息,编写proto文件,完整代码如下:
syntax = "proto3";
option go_package = ".;protobuf";
package protobuf;
message GreetingRequest {
int32 page = 1;
int64 time_str = 2;
string sign = 3;
}
message StreamResData {
// repeated是用来存放n个相同内容类型,类似于数组slices
repeated string message = 1;
}
service StreamReqData {
rpc SayHello (GreetingRequest) returns (StreamResData){};
}
总结:page、time_str、sign分别和上面截图的类型一一对应,而message我们使用repeated类型用来存放多个相同内容。方法StreamReqData是gRPC的固定写法。
2、接下来,我们使用protoc生成go调用格式和grpc服务接口,命令如下:
protoc -I ./ --go_out=plugins=grpc:proto game_grpc.pb.go
3、遗憾的是,报错了,截图如下所示:
4、紧接着,使用如下两行命令解决了这个报错问题:
protoc --go_out=. game.proto
protoc --go-grpc_out=. game.proto
5、执行上面的命令后,截图如下所示:
6、接下来,我们根据官方提供的gRPC用法,快速编辑代码进行测试,代码如下:
package main
import (
"common-data/protobuf"
"context"
"fmt"
"google.golang.org/grpc"
"log"
)
func main() {
conn, err := grpc.Dial("180.76.60.244:9901", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := protobuf.NewStreamReqDataClient(conn)
request := new(protobuf.GreetingRequest)
request.Page = 1
request.Sign = "0f9273bf79fd4ffa"
request.TimeStr = 1652857605572
resp, err := c.SayHello(context.Background(), request)
if err != nil {
log.Fatalf("could not resp: %v", err)
return
}
for _, message := range resp.Message {
fmt.Println(message)
}
}
7、迫不及待的想看下认证结果了,运行代码后结果报错了,截图如下:
总结:这个错误是找不到远程的protobuf.StreamReqData/SayHello方法,再次分析之前wireshark抓包的响应体,我们发现远程方法为:/challenge.Challenge/SayHello。接下来我们在game_grpc.pb.go文件中配置远程方法!
8、在game_grpc.pb.go文件中,我们修改StreamReqData_SayHello_FullMethodName变量为/challenge.Challenge/SayHello,修改后截图如下所示:
9、代码修改完成后,我们再次运行代码,成功打印截图如下所示:
总结:此刻我们对比wireshark工具中response返回的数据和GoLand输出的数据能够一一对应,修改页数后,即可看到新的数字内容。本题对sign参数没有校验,考察的是gRPC的抓包和组包。我们将每页的数字进行相加后,第四题完美通关。
想看Python版本请移步我兄弟公众号:猿人学-app逆向比赛第四题grpc题解
五、思路总结
回顾整个分析流程,本次难点主要概括为以下几点:
-
熟悉gRPC的基本使用
-
构建proto格式文件
-
熟悉使用tcpdump
-
熟悉使用wireshark
-
grpc在go语言中的使用
本篇分享到这里就结束了,欢迎大家关注下期,我们不见不散☀️☀️😊
往期推荐
DX滑块验证码别乱捅!一不小心就反爬了。
某安网别逆向,一不小心就......
微信自动聊天机器狗,配置chatGPT,比Siri还智能!
被魔改md5加密坑了?某网站魔改md5加密逆向还原 (多种语言还原)
某游戏社区App | So层逆向分析
爬虫最快框架collyx,今天开源了...
某站弹幕Protobuf协议逆向分析 | Go语言版本
作者简介
我是TheWeiJun,有着执着的追求,信奉终身成长,不定义自己,热爱技术但不拘泥于技术,爱好分享,喜欢读书和乐于结交朋友,欢迎扫我微信与我交朋友💕
分享日常学习中关于爬虫及逆向分析的一些思路,文中若有错误的地方,欢迎大家多多交流指正💕
文章来源:逆向与爬虫的故事
原文链接:猿人学逆向比赛第四题-gRPC题解 | Go版本
微信搜公众号:逆向与爬虫的故事;给我一个关注!