猿人学-app逆向比赛第四题grpc题解

admin 2025年2月15日23:00:53评论8 views字数 3603阅读12分0秒阅读模式
猿人学-app逆向比赛第四题grpc题解

周五晚8点参加了猿人学的app逆向比赛,和我的队友"duoduo"兄一起把这道题做出来了,于是简单分享一下思路和过程。

猿人学-app逆向比赛第四题grpc题解
 目录

一 .什么是grpc

二.什么是protobuf

三.数据包协议分析

四.sign加密与python代码实现

五.总结

一 .什么是grpc

gRPC 是一个现代开源的高性能远程过程调用 (RPC) 框架,可以在任何环境中运行。它可以通过对负载平衡、跟踪、健康检查和身份验证的可插拔支持有效地连接数据中心内和跨数据中心的服务。它也适用于分布式计算的最后一英里,将设备、移动应用程序和浏览器连接到后端服务。

gRPC基于 HTTP/2协议传输。

客户端传递函数进去,然后服务端执行成功后给客户端结果。

二.什么是protobuf

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

可以简单理解为,是一种跨语言、跨平台的数据传输格式。与json的功能类似,但是无论是性能,还是数据大小都比json要好很多。

protobuf之所以可以跨语言,就是因为数据定义的格式为.proto格式,需要基于protoc编译为对应的语言。

三.数据包协议分析

初看java层

猿人学-app逆向比赛第四题grpc题解

主要的逻辑是:把时间戳和每次下拉之后页数自动加1后的数据放入到函数中去执行,java层被混淆的面目全非,中间用了一个sign 为native的方法,于是换种思路从数据包上面开始分析。

 3.1抓包

拿到这道题的时候受前面几道题目的影响以为直接可以抓到包,使用Drony转发到charle上后发现没有这道题的数据包,初步怀疑使用了其他的协议,然后在pc打开wireshark进行数据包的拦截,同时开启frida hook 第四题中的sign。

猿人学-app逆向比赛第四题grpc题解

发现 frida hook的值和wireshark抓到的数据包相同,这也就坐实了这个数据包为第四题的发包函数。

然后我就想着能不能再找到收到的响应呢?

在wireshark输入过滤条件

猿人学-app逆向比赛第四题grpc题解

然后一个一个包来看

猿人学-app逆向比赛第四题grpc题解

确实找到了返回数据。

3.2数据包分析

猿人学-app逆向比赛第四题grpc题解

于是找来两个不同时间发送的数据包来对比下差异

猿人学-app逆向比赛第四题grpc题解

也就是说结尾位置的为一些重要的参数,我们能够伪造到然后加上前面的数据段不久可以请求服务器产生数据了?

那么如何伪造这些参数呢?

猿人学-app逆向比赛第四题grpc题解

在数据的hexdump中只能看到sign的身影,那么page和时间戳的身影跑哪去了,经过了查阅资料后发现grpc数据的传送经过了protobuf的编码,字符串在这里可以显现,但是时间戳在hexdump里面并没有被显现出来。

那么开始编写protobuf文件吧

syntax = "proto3";//指定版本为proto3,默认为proto2message SearchRequest {  uint32 page =1; uint64  time = 2; string sign =3;}

 然后执行:protoc --proto_path=./ --python_out=./ test.proto     

def bytes2hex(byte_arr: bytes) -> str:    return byte_arr.hex()import test_pb2# 实例化协议对象ser = test_pb2.SearchRequest()ser.page = 1ser.time = 1652580021332ser.sign ="b94a543f66e23656"# 对数据进行序列化data = ser.SerializeToString()print(type(data))print(bytes2hex(data))

猿人学-app逆向比赛第四题grpc题解

这个时候当事人1和当事人2都非常开心,是不是就可以解决了?解决了就可以睡大觉了

猿人学-app逆向比赛第四题grpc题解

然后十分钟:连接服务器 把tcp头部和数据拼接起来发给服务器。。。。。经过实验 失败,服务器会莫名断开连接。

四.sign加密与python代码实现

于是想了下python如何grpc的请求和服务器交互,说干就干.经过了一番查阅资:需要以下条件

服务器的地址和端口(废话),前文中我们提到grpc 那么就有要被执行的函数,有被执行的函数就得有接受函数执行完的结构。

于是乎 下面的代码就出来了

syntax = "proto3";package challenge;message app4 { uint32 page =1; uint64  time = 2; string sign =3;}message HelloReply {  repeated string message = 1;}service Challenge{ rpc SayHello (app4) returns (HelloReply) {}}
# -*- coding: utf-8 -*-import grpcimport data_pb2,data_pb2_grpc_HOST = '180.76.60.***'_PORT = '9901'def run():     conn = grpc.insecure_channel(_HOST + ':' + _PORT)     client = data_pb2_grpc.ChallengeStub(channel=conn)     page_time = "1:1652586112285"     sign = "92979f42250a942b"     page_time = "4:1652593296974"     sign = "f9f5c6fe5b3da911"     page = page_time.split(":")[0]     time = page_time.split(":")[1]     response = client.SayHello(data_pb2.app4(page = int(page),sign = sign,time =int(time)))     print( str(response))if __name__ == '__main__':    run()

在终端下执行:

#python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. data.proto

即可生成grpc和probuf协议的文件。

run一下

猿人学-app逆向比赛第四题grpc题解

发现返回的数据结构怎么这么多位,服务器抽风了还是我的程序抽风了,后来"duoduo"兄说前面的004说明后面有四个值是对的。

于是协议模拟的问题告一段落。

要让整个算法跑出来算100页的数据,还需要sign参数

frida 代码如下

        var signclass1 = Java.use("com.yuanrenxue.match2022.fragment.challenge.ChallengeFourFragment");        signclass1.sign.implementation = function (arg1,arg2) {            console.log("");            console.log("page_time= ""+arg1+""");              console.log("sign= ""+this.sign(arg1,arg2)+""");            return this.sign(arg1,arg2);        }

发现sign :

第一个参数为page:时间戳。第二个参数就是时间就是时间戳

由于比赛原因 谁先搞完就能排名高,掏出unidbg(也想还原来着,那么短时间不太现实)

写unidbg调用

猿人学-app逆向比赛第四题grpc题解

主要代码如下

    public String callsign(String input,long j){        List<Object> list=new ArrayList<>(10);        list.add(vm.getJNIEnv());        list.add(0);        list.add(vm.addLocalObject(new StringObject(vm,input)));        list.add(j);        //Number number=module.callFunction(emulator,0xdf0,list.toArray())[0];        Number number = module.callFunction(emulator, "Java_com_yuanrenxue_match2022_fragment_challenge_ChallengeFourFragment_sign", list.toArray());        return vm.getObject(number.intValue()).getValue().toString();    }

然后排名上升两名  end。

五.总结

要去看更多的东西才能扩宽自己的眼界,有些技术不是难,而是没接触过(hhh接触过也不一定会),还有"duoduo"兄 yyds。

我是BestToYou,分享工作或日常学习中关于二进制逆向和分析的一些思路和一些自己闲暇时刻调试的一些程序,文中若有错误的地方,恳请大家联系我批评指正。

猿人学-app逆向比赛第四题grpc题解

原文始发于微信公众号(二进制科学):猿人学-app逆向比赛第四题grpc题解

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月15日23:00:53
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   猿人学-app逆向比赛第四题grpc题解https://cn-sec.com/archives/1886666.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息