首页
论坛
课程
招聘
[原创]记一道Android CTF题
2020-8-10 20:19 4609

[原创]记一道Android CTF题

2020-8-10 20:19
4609

一、题目

wmctf2020 reverse easy_apk
题目地址:

https://adworld.xctf.org.cn/match/contest_challenge?event=146&hash=684a58cc-1140-4937-99f2-ef347d777d9f.event
考查知识点:
1、算法识别
2、动态调试
这道题之前有大佬在论坛发过,但是后来看不到了,这里记录一下个人做题的过程和遇到的问题,不喜勿喷。

二、解题过程

1、java层
jadx
 

jeb
 

手机上有面具的可以新建个android工程,引入so进行调试

2、native层
(1)check方法定位
方法一
 

静态分析 jnionload
修复前(未导入jni.h)

修复后(导入jni.h)

查看methods

check->sub_10F00
方法二
 

使用frida动态hook RegisterNatives

[RegisterNatives] java_class: com.WM.one.Native name: check sig: (Ljava/lang/String;)Z fnPtr: 0x72afe26f00 module_name: libnative-lib.so module_base: 0x72afe16000 offset: 0x10f00
(2)init_array


sub_D994中会kill进程

unsigned __int64 __fastcall sub_D994(__pid_t a1, int a2)
{
  unsigned __int64 result; // x0
  unsigned __int8 v3; // cf
  bool v4; // zf

  result = linux_eabi_syscall(__NR_kill, a1, a2);
  v3 = __CFADD__(result, 0x1000LL);
  v4 = result == 0xFFFFFFFFFFFFF000LL;
  if ( result > 0xFFFFFFFFFFFFF000LL )
    result = !result;
  if ( !v4 & v3 )
  {
    *(_DWORD *)__errno() = result;
    result = 0xFFFFFFFFFFFFFFFFLL;
  }
  return result;
}
这里需要path so 让kill不成功,使用 RET C0 03 5F D6 让方法不执行或者nop方法体

path前

path后

F5

(3)算法识别

在sub_10F00中

这里调试的时候有固定的组数赋值

搜索了一下,百度告诉我们这是zuc算法

这是一个对称算法
(4)动态调试
sub_10D24对应是zuc的解密算法,由于是对称加密,可以使用加密后的字节进行解密获得flag,在网上看了一下zuc算法的计算过程,这里有py的实现 https://baike.baidu.com/item/%E7%A5%96%E5%86%B2%E4%B9%8B%E7%AE%97%E6%B3%95%E9%9B%86/7177910?fr=aladdin
if '__main__' == __name__:
    key = [0x00] * 16
    iv = [0x00] * 16
    zuc = ZUC(key, iv)
    # 加密过程
    out = zuc.zuc_encrypt(b"i love u")
    print("加密得到的字流", ["%08x" % e for e in out])
    # 解密过程
    zuc2 = ZUC(key, iv)
    out2 = zuc2.zuc_encrypt(out)
    print("解密得到的字流", ["%08x" % e for e in out2])
    print(bytes(out2))

根据算法,需要找到 IV KEY 加密字节 就可以得到flag

IV
 

KEY
 

0000007FF0435C00 IV
0000007FF0435C10 KEY
zuc_encrypt
 

zuc_encrypt(v7, (__int64)&key, 354339, 24, 1, 256, (unsigned __int64)&src, (unsigned __int64)&encode);

src 是 01234567890123456789012345678912

encode

然后再调试一边,用encode替换src,看看是否是原来的src,但是结果不正确,经过反复调试,发现IV是固定的,但是KEY是变化的,看了一下key赋值的过程,发现TracerPid是生成key的一部分


调试的时候TracerPid 不为0,正确的KEY是TracerPid = 0的时候算出来的
TracerPid 修改为0 得到正确的key

F2修改内存值

 

而最后要对比的字节应该是

    v11 = unk_296C0;
    v12 = unk_296D0;
    result = (unsigned int)sub_DB8C(&v11, &encode, 0x20LL) == 0;
0x2B, 0x31, 0xA9, 0x7F, 0x7A, 0x85, 0x71, 0xED, 0x06, 0x83, 0x72, 0xDB, 0x52, 0xC5, 0xC9, 0xCD,
0xC2, 0x2A, 0x66, 0xF0, 0x46, 0xAF, 0x9A, 0x5F, 0xA6, 0x5F, 0x63, 0xB2, 0x3B, 0x2E, 0x8B, 0xCA
按之前的思路,将加密字节当做src来调试

获得flag W3lcomeT0WMCTF!_*Fu2^_AnT1_32E3$

三、总结

1、算法识别这块搜索大法
2、学习了zuc算法


[看雪官方]《安卓高级研修班》线下班,网课(12月)班开始同步招生!!

最后于 2020-8-12 18:35 被neilwu编辑 ,原因:
收藏
点赞6
打赏
分享
最新回复 (8)
雪    币: 32
活跃值: 活跃值 (78)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6otest 活跃值 2020-8-10 21:46
2
0
学习一下
雪    币: 3032
活跃值: 活跃值 (323)
能力值: (RANK:110 )
在线值:
发帖
回帖
粉丝
LowRebSwrd 活跃值 2 2020-8-11 13:09
3
0
不错,直接百度出来zuc算法
雪    币: 5651
活跃值: 活跃值 (1907)
能力值: ( LV7,RANK:108 )
在线值:
发帖
回帖
粉丝
neilwu 活跃值 2020-8-11 14:05
4
0
LowRebSwrd 不错[em_63],直接百度出来zuc算法
哈哈 大佬见笑啦 我也是和论坛里的大佬学到的 
雪    币: 164
活跃值: 活跃值 (53)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
chenshiyi 活跃值 2020-8-12 02:13
5
0
大佬用的什么牌子手机调试的
雪    币: 5651
活跃值: 活跃值 (1907)
能力值: ( LV7,RANK:108 )
在线值:
发帖
回帖
粉丝
neilwu 活跃值 2020-8-12 08:51
6
0
chenshiyi 大佬用的什么牌子手机调试的
皮鞋1
雪    币: 453
活跃值: 活跃值 (39)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ChengQing 活跃值 2020-8-12 10:55
7
0
Nick Job
雪    币: 288
活跃值: 活跃值 (65)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
切丝怕怕 活跃值 2020-8-12 18:17
8
0
建议 native层-静态分析 jnionload 中的修复前、修复后,能改成导入.h前,导入.h后,说修复,不太具体也可能造成误解(对,就是我[捂脸])
雪    币: 5651
活跃值: 活跃值 (1907)
能力值: ( LV7,RANK:108 )
在线值:
发帖
回帖
粉丝
neilwu 活跃值 2020-8-12 18:34
9
1
切丝怕怕 建议 native层-静态分析 jnionload 中的修复前、修复后,能改成导入.h前,导入.h后,说修复,不太具体也可能造成误解(对,就是我[捂脸])
ok
游客
登录 | 注册 方可回帖
返回