neilwu 发表于 2020-8-11 10:08

wmctf2020 reverse easy_apk

本帖最后由 neilwu 于 2020-11-12 18:20 编辑

### 题目
wmctf2020 reverse easy_apk
题目地址:
```
https://adworld.xctf.org.cn/match/contest_challenge?event=146&hash=684a58cc-1140-4937-99f2-ef347d777d9f.event
```
##### 考查知识点:
##### 1、算法识别
##### 2、动态调试

```
这道题我在看雪发过,https://bbs.pediy.com/thread-261372.htm
这里记录一下个人做题的过程和遇到的问题,不喜勿喷。
```

### 解题过程
##### 1、java层
###### jadx

###### jeb

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


##### 2、native层
##### (1)check方法定位
###### 方法一
静态分析 jnionload
修复前

修复后

查看methods


```
check->sub_10F00
```
###### 方法二
使用frida动态hook 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 = * 16
    iv = * 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算法

附上样本




Linshengqiang 发表于 2020-8-11 10:19

不懂 看到这么多密密麻麻的字符头晕

neilwu 发表于 2020-8-12 11:35

chenshiyiya 发表于 2020-8-11 20:08
想问下,新建android工程那里,只能用面具嘛,无真机怎么弄

这个题lib是arm64 v8a的 你要是用虚拟机调试的话可能不行 最好用真机进行调试

Ye_Kong 发表于 2020-8-11 10:47

看见伪代码就头疼

linjzy 发表于 2020-8-11 17:14

用心讨论,共获提升

CrazyHuan 发表于 2020-8-11 17:26

顶帖留痕{:1_893:}   顺便吐槽下,你们这么搞,让我们这些只做一般混淆与加壳的怎么活 :'(weeqw

pumishuo 发表于 2020-8-11 17:56

CrazyHuan 发表于 2020-8-11 17:26
顶帖留痕   顺便吐槽下,你们这么搞,让我们这些只做一般混淆与加壳的怎么活

你以为加强壳和强混淆就不会被破解了?

csw曾哥 发表于 2020-8-11 18:08

楼主这个实力也是可以的,学习到姿势了,我本身也是打CTF的,谢谢楼主分享

lhywa 发表于 2020-8-11 18:55

涨姿势了,祖冲之加密算法。{:1_921:}

chenshiyiya 发表于 2020-8-11 20:08

想问下,新建android工程那里,只能用面具嘛,无真机怎么弄

fengbolee 发表于 2020-8-11 21:14

不自禁的我又为这排版工整的技术分享贴送分来了。
页: [1] 2 3 4 5 6
查看完整版本: wmctf2020 reverse easy_apk