1234下一页
返回列表 发新帖

【逆向思路】悉尼大学逆向题目分析

  [复制链接]

14

主题

964

回帖

3725

积分

大学生

Rank: 5Rank: 5

金币
2467
好评
11
信誉
88

考神MT论坛新人

发表于 2026-5-29 16:04:05 来自手机  | 显示全部楼层 | 阅读模式  来自 广东
本帖最后由 嘈杂 于 2026-5-29 16:04 编辑

前 言

朋友最近搞悉尼大学的题目,目标是找出隐藏的API密钥。结果他卡住了,请求我的帮忙。记录一下过程。

样本就不发了,毕竟是人家的作业






一、基本信息

MT管理器看APK,包名nz.ac.auckland.cs702.tartarus,应用名Tartarus。jadx反编译后代码混淆,类名全是G1、A0、r2这种,不过业务类名保留了几个关键的:


  1. com.example.playground.MainActivity
  2. com.example.playground.network.ImagePipeline
  3. com.example.playground.network.AssetProbe
  4. com.example.playground.network.FrameAssembler
  5. com.example.playground.network.AssetWarmup
  6. com.example.playground.network.PaletteProbe
  7. com.example.playground.util.RuntimeProbe
复制代码


MT管理器看lib目录,有个5.42MB的native库:libtartarus_core.so,静态链接了libcurl和openssl。直觉告诉我密钥可能藏在里面。




二、XOR字符串解码

jadx定位到ImagePipeline$Companion类,全是XOR混淆。核心解码方法:


  1. public static String h(int[] arr, int key) {
  2.     StringBuilder sb = new StringBuilder();
  3.     for (int v : arr) sb.append((char)(v ^ key));
  4.     return sb.toString();
  5. }
复制代码


写个Python脚本批量解:


  1. def d(arr, key): return ''.join(chr(x ^ key) for x in arr)

  2. print(d([0x6b,0x5f,0x5e,0x42,0x45,0x58,0x43,0x50,
  3.          0x4b,0x5e,0x43,0x45,0x44], 0x2a))

  4. print(d([0x44,0x0c,0x0e,0x05,0x0e,0x19,0x0a,0x1f,
  5.          0x0e,0x34,0x02,0x06,0x0a,0x0c,0x0e], 0x6b))

  6. print(d([0x52,0x4e,0x4e,0x4a,0x49,0x00,0x15,0x15,0x5b,0x53,
  7.          0x14,0x5f,0x56,0x56,0x53,0x55,0x4e,0x4e,0x4d,0x5f,
  8.          0x54,0x14,0x53,0x54,0x5c,0x55], 0x3a))

  9. print(d([0x54,0x4f,0x46,0x15,0x12,0x11,0x08,0x49,0x1e,0x42,
  10.          0x65,0x71,0x65,0x16,0x16,0x45,0x57,0x54,0x1e,0x68,
  11.          0x5d,0x68,0x53,0x11,0x60,0x17,0x16,0x64,0x6d,0x53,
  12.          0x70,0x73,0x6b,0x6e,0x41,0x41,0x57,0x13,0x63,0x55,
  13.          0x6f,0x49,0x62,0x4c,0x43,0x51,0x6b,0x77,0x5f,0x72,
  14.          0x1a], 0x27))
复制代码


跑一下:


  1. $ python3 decode.py
  2. Authorization
  3. /generate_image
  4. https://ai.elliottwen.info
  5. sha256/n9eBVB11bps9OzOt6G01CJtWTLIffp4DrHnEkdvLPxU=
复制代码


其他解码结果:a()=Authorization, b()=/generate_image, c()=application/json; charset=utf-8, d()=signature, i()=https://ai.elliottwen.info, j()=证书哈希。AssetProbe里还有key=0x41→"https://ai.elliotwen.info"(少一个t)。

API配置全部拿到了,但API密钥不在Java层。




三、发现native层隐藏

于是又注意到AssetProbe类有两个private native方法:


  1. .method private final native probeEndpoint()Ljava/lang/String;
  2. .method private final native probeGate()Ljava/lang/String;
复制代码


ImagePipeline$Companion也有两个:


  1. .method private final native routeBase(Ljava/lang/String;)Ljava/lang/String;
  2. .method private final native checkPeer(Ljava/lang/String;Ljava/lang/String;)Z
复制代码


特别是probeGate()这个名字——感觉就是用来返回API密钥的。




四、IDA静态分析so

提取so丢进IDA:


  1. JNI_OnLoad            0x1007A4
  2. JNI_OnUnload          0x10048C
复制代码


只有两个导出符号!所有native方法通过RegisterNatives动态注册。

JNI_OnLoad反汇编出来全是垃圾指令:


  1. .text:001007D8  MVN     X11, X9
  2. .text:001007DC  ADD     X12, X9, #1
  3. .text:001007E0  ADD     X11, X12, X11,LSL#1
  4. .text:001007E4  ORR     X13, X11, X10
  5. .text:001007E8  ORN     X14, X10, X11
  6. .text:001007EC  AND     X15, X13, X12
  7. .text:001007F0  ADD     X11, X11, X12
  8. .text:001007F4  EOR     X12, X13, X12
  9. .text:001007F8  ADD     X11, X11, X14
  10. .text:001007FC  ADD     X12, X12, X15,LSL#1
  11. .text:00100800  NEG     X13, X10
  12. .text:00100804  SUB     X11, X11, X12
  13. ... (后面全是类似的无意义运算)
复制代码


IDA Strings搜probeEndpoint、probeGate:0 results。证实通过RegisterNatives注册。

但是.data段发现可疑数据,尝试解密看看:


  1. $ python3 -c "
  2. data=open('libtartarus_core.so','rb').read()
  3. enc = data[0x5650c0:0x5650c0+0x11]
  4. print(bytes(b ^ 0x5a for b in enc))
  5. "
  6. b'arena.key.slot.c\x00'
复制代码


配置键名,不是密钥。静态分析走不通,上Frida。




五、Frida动态提取

APP有完整反调试(su路径、Xposed包名、/proc扫描、frida端口、Debug检测等)。这里就不细说了,有感兴趣的我再发一篇完整绕过检测的帖子

第一轮:抓XOR解码 + HTTP头


  1. Java.perform(function() {
  2.     var C = Java.use("com.example.playground.network.ImagePipeline$Companion");
  3.     C.h.implementation = function(arr, key) {
  4.         var r = this.h(arr, key);
  5.         console.log("[XOR] key=0x" + key.toString(16) + " => " + r);
  6.         return r;
  7.     };
  8.     var RB = Java.use("A0.p");
  9.     RB.m.overloads.forEach(function(ov) {
  10.         ov.implementation = function(name, value) {
  11.             if (name === "Authorization")
  12.                 console.log("[KEY] Authorization = " + value);
  13.             return ov.call(this, name, value);
  14.         };
  15.     });
  16.     var G1j = Java.use("G1.j");
  17.     G1j.b.implementation = function() {
  18.         var t = this.b();
  19.         console.log("[TOKEN] " + t);
  20.         return t;
  21.     };
  22. });
复制代码


Frida输出(关键部分):


  1. [XOR] key=0x3a => "https://ai.elliottwen.info"
  2. [ROUTE] in=https://ai.elliottwen.info → out=https://ai.elliotwen.info
  3. [XOR] key=0x57 => "/auth"
  4. [TOKEN] cae9edce9e9819bf01044dbacdd05e2e...
  5. [KEY] Authorization = cae9edce9e9819bf01044dbacdd05e2e...
  6. URL: POST https://ai.elliotwen.info/auth
  7.   HDR: Content-Length = 0
  8.   HDR: Host = ai.elliotwen.info
  9.   HDR: User-Agent = okhttp/4.12.0

  10. [XOR] key=0x2a => "Authorization"
  11. URL: POST https://ai.elliotwen.info/generate_image
  12.   HDR: Content-Type = application/json; charset=utf-8
复制代码


发现两个端点用不同Authorization!
• /auth → G1.j.b()生成的随机128位hex token
• /generate_image → 固定值

第二轮:反射调用native方法


  1. Java.perform(function() {
  2.     var AP = Java.use("com.example.playground.utils.AssetProbe");
  3.     var inst = AP.$new();
  4.     var cls = inst.getClass();

  5.     var m1 = cls.getDeclaredMethod("probeEndpoint", []);
  6.     m1.setAccessible(true);
  7.     console.log("[KEY] probeEndpoint = " + m1.invoke(inst, []));

  8.     var m2 = cls.getDeclaredMethod("probeGate", []);
  9.     m2.setAccessible(true);
  10.     console.log("[KEY] probeGate = " + m2.invoke(inst, []));
  11. });
复制代码


Frida输出:


  1. [KEY] probeEndpoint = https://ai.elliotwen.info/generate_image
  2. [KEY] probeGate = c238eb9410fd73a12ab1ec56e70d4bc53f87a6ddfbde50168c93e84271ae3fd01e25b7a18d3f50acb6a42f13f968d7bc7ed0c514be928da73bc48e01563d41ab
复制代码


拿到了!另外还有:

  1. warmupNative → 368b663f3c47dc8bcd75bb0aceb
  2. readPalette  → 08a041dac
复制代码





六、完整api流程



七、验证


  1. import urllib.request, ssl, json
  2. ctx = ssl.create_default_context()
  3. ctx.check_hostname = False
  4. ctx.verify_mode = ssl.CERT_NONE
  5. body = json.dumps({'signature': '', 'prompt': 'a cute cat wearing sunglasses'}).encode()
  6. req = urllib.request.Request(
  7.     'https://ai.elliotwen.info/generate_image', data=body,
  8.     headers={
  9.         'Authorization': 'c238eb9410fd73a12ab1ec56e70d4bc53f87a6ddfbde50168c93e84271ae3fd01e25b7a18d3f50acb6a42f13f968d7bc7ed0c514be928da73bc48e01563d41ab',
  10.         'Content-Type': 'application/json; charset=utf-8',
  11.         'User-Agent': 'okhttp/4.12.0'
  12.     }, method='POST')
  13. print(urllib.request.urlopen(req, context=ctx, timeout=30).read().decode())
复制代码


输出:


  1. $ python3 test.py
  2. "/images/ead5cc01-491c-ee15-2640-0b6b90e31f05.jpeg"
复制代码


HTTP 200,成功!而且发现/generate_image端点不校验signature参数,空字符串也能过。




八、汇总

项目
API密钥c238eb9410fd73a12ab1ec56e70d4bc53f87a6ddfbde50168c93e84271ae3fd01e25b7a18d3f50acb6a42f13f968d7bc7ed0c514be928da73bc48e01563d41ab
长度128 hex = 64字节 = 512bit
位置libtartarus_core.so .data段
端点POST https://ai.elliotwen.info/generate_image
认证Authorization头直传 无Bearer前缀





九、总结

应用保护思路是"藏"不是"加密"。XOR混淆只防静态分析,运行时内存全是明文。知道方法名,Java反射一把过,不用啃ARM64指令。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

341

主题

2339

回帖

7972

积分

硕士生

Rank: 6Rank: 6

金币
1050
好评
9
信誉
101
发表于 2026-5-29 16:06:44 来自手机  | 显示全部楼层  来自 浙江
看看
回复

使用道具 举报

10

主题

740

回帖

4624

积分

大学生

Rank: 5Rank: 5

金币
235
好评
21
信誉
101
发表于 2026-5-29 16:09:31 来自手机  | 显示全部楼层  来自 福建
牛逼牛逼
回复

使用道具 举报

51

主题

2972

回帖

8674

积分

硕士生

看看

Rank: 6Rank: 6

金币
132
好评
8
信誉
140

考神MT论坛帅哥MT论坛最佳新人MT论坛新人MT论坛活跃会员

发表于 2026-5-29 16:12:04 来自手机  | 显示全部楼层  来自 河南
看看
回复

使用道具 举报

9

主题

190

回帖

603

积分

初中生

Rank: 3Rank: 3

金币
316
好评
0
信誉
100
发表于 2026-5-29 16:13:01 来自手机  | 显示全部楼层  来自 山东
看看
回复

使用道具 举报

20

主题

4551

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
7615
好评
3
信誉
100

MT论坛新人MT论坛帅哥考神MT论坛最佳新人

发表于 2026-5-29 16:17:10 | 显示全部楼层  来自 广东
看看内容
回复

使用道具 举报

12

主题

951

回帖

3367

积分

大学生

Rank: 5Rank: 5

金币
1411
好评
9
信誉
110
发表于 2026-5-29 16:18:02 来自手机  | 显示全部楼层  来自 广东
看看隐藏
回复

使用道具 举报

27

主题

991

回帖

5931

积分

硕士生

Rank: 6Rank: 6

金币
2377
好评
70
信誉
100

考神MT论坛新人MT论坛帅哥MT论坛最佳新人

QQ
发表于 2026-5-29 16:18:56 | 显示全部楼层  来自 广东
看看
回复

使用道具 举报

66

主题

5346

回帖

2万

积分

博士后

Rank: 8Rank: 8

金币
1835
好评
196
信誉
109

考神MT论坛活跃会员MT论坛最佳新人MT论坛帅哥MT论坛侠客挂机大佬

发表于 2026-5-29 16:19:26 来自手机  | 显示全部楼层  来自 山东
看下分析
回复

使用道具 举报

27

主题

1094

回帖

3770

积分

大学生

Rank: 5Rank: 5

金币
1822
好评
7
信誉
122
发表于 2026-5-29 16:23:37 来自手机  | 显示全部楼层  来自 新疆
看看隐藏
回复

使用道具 举报

3

主题

253

回帖

866

积分

高中生

Rank: 4

金币
331
好评
0
信誉
70
发表于 2026-5-29 16:33:16 来自手机  | 显示全部楼层  来自 新疆
6666666666
回复

使用道具 举报

0

主题

4537

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
5480
好评
0
信誉
96
发表于 2026-5-29 16:33:57 来自手机  | 显示全部楼层  来自 吉林
看看隐藏
回复

使用道具 举报

6

主题

4078

回帖

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
6706
好评
0
信誉
100
发表于 2026-5-29 16:48:52 来自手机  | 显示全部楼层  来自 江苏
不错,谢谢分享
回复

使用道具 举报

12

主题

1872

回帖

6266

积分

硕士生

Rank: 6Rank: 6

金币
4252
好评
1
信誉
97

MT论坛新人考神MT论坛最佳新人

发表于 2026-5-29 16:58:53 来自手机  | 显示全部楼层  来自 广东
看看隐藏
回复

使用道具 举报

64

主题

3259

回帖

9177

积分

硕士生

Rank: 6Rank: 6

金币
2194
好评
21
信誉
104

MT论坛帅哥MT论坛新人考神MT论坛最佳新人

发表于 2026-5-29 17:07:01 来自手机  | 显示全部楼层  来自 江苏
看看隐藏
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表