nssctf-mobile专题(一)

[CISCN 2022 东北]crackme_Android

整个分析如下图所示:

NSSIMAGE

很简单。就是将38bytes的flag去掉格式后,每4bytes一组进行md5加密,得到的结果组成一个字符串,并于已知字符串比较。
所以我们只需要将已知字符串分好组拿到https://www.cmd5.org/上解密即可。分组代码如下:

1
2
3
4
5
6
7
8
md5string = '8393931a16db5a00f464a24abe24b17a9040b57d9cb2cbfa6bdc61d12e9b51f2789e8a8ae9406c969118e75e9bc65c4327fbc7c3accdf2c54675b0ddf3e0a6099b1b81046d525495e3a14ff6eae76eddfa1740cd6bd483da0f7684b2e4ec84b371f07bf95f0113eefab12552181dd832af8d1eb220186400c494db7091e402b0'
flaglen = 38 - 6
group = flaglen / 4
eachmd5len = len(md5string) // 8

for i in range(0, len(md5string), eachmd5len):
eachmd5 = md5string[i:i+eachmd5len]
print(eachmd5)

[HGAME 2022 week1]flagchecker

题目清晰明了,太简单了,就贴个脚本。

1
2
3
4
5
6
7
8
9
10
11
12
from base64 import b64decode
from Crypto.Cipher import ARC4

base64cipher = "mg6CITV6GEaFDTYnObFmENOAVjKcQmGncF90WhqvCFyhhsyqq1s="
RC4cipher = b64decode(base64cipher)
print(RC4cipher)
key = "carol"

rc4 = ARC4.new(key.encode())
plaintext = rc4.decrypt(RC4cipher)
print(plaintext)

[羊城杯 2021]Ez_android

利用jadx工具分析,MainActivity中主要是登录验证。真实的账号字符串可以文本搜索出来(当然也可以使用MT根据资源id搜索出来):

NSSIMAGE

同理其他字符串也可以通过这种方法搜索出来,后续不再提及。

密码验证这一块进行了加密处理:

NSSIMAGE

很容易逆出来,这里直接贴代码:

1
2
3
4
5
6
7
8
9
from binascii import hexlify, unhexlify

passwdCipher = "c232666f1410b3f5010dc51cec341f58"
bytePasswdCipher = unhexlify(passwdCipher.encode())
md5 = ''
for each in bytePasswdCipher:
# md5 += chr(each + 1).encode()#有的会变成两个字节???!
md5 += hex(each + 1)[2:].zfill(2)
print(md5)

当然,直接修改smali语言也可以绕过登录验证,可以修改条件跳转指令,也可以修改checkUsername和checkPasswd方法的返回值(在return v2前面加一个赋值语句:const/4 ,0x1)。有兴趣的可以试试。

账号密码验证通过后,还会调用getKeyAndRedirect方法,主要是开辟线程,这个线程会调用lambda$getKeyAndRedirect$0$MainActivity方法远程获取key(需要注意的是,要在samil语言上修改socketipport为nssctf给的),然后通过Intent开启CheckFlagActivity活动并传入key

跟进CheckFlagActivity,该活动主要是通过Intent获取key参数,然后获取我们输入的flag,然后调用checkFlag方法验证 flag。

NSSIMAGE

这里调用了EncodeUtils.encode方法对 flag 进行了加密,再与encodeFlag字符串对比,该字符串通过搜索可知是3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P

接下来查看EncodeUtils.encode方法:

NSSIMAGE

其实就是一个base64加密,只不过base64表通过服务器给出。

整个过程理清楚之后,我们就需要动调来获取base64表,因此在EncodeUtils.encode方法被调用处下断点(当然你如果觉得不太靠谱,可以往前几步再下断点,因为smali语言的操作都是经过寄存器来进行的,过多执行几步的话里面的数据就可能被更改了)(jadx需要在smali语言中按F2下断点),然后进行动调。

在转smail语言时,tab键好像不会定位到对应代码,不过我们可以通过方法名按ctrl+F定位

NSSIMAGE

获取到base64表后,就是解密了,对应脚本如下:

1
2
3
4
5
6
7
8
9
from base64 import b64decode
from string import ascii_uppercase, ascii_lowercase, digits

table1 = 'TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom'
table2 = ascii_uppercase + ascii_lowercase + digits + '+/'
tarnstable = str.maketrans(table1, table2)
cipher = '3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P'
plaintext = b64decode(cipher.translate(tarnstable))
print(plaintext)

[鹏城杯 2022]baby_re

jadx分析,该应用调用baby_xor方法对我们输入的flag进行了加密,而该方法是通过native层实现的,对应的加载so文件代码如下:

1
2
3
4
static {
System.loadLibrary("createso"); // 加载so文件!!!
}

那么IDA分析so文件咯,直接找该函数名(对应的so函数名命名是有规则的)。

一个简简单单的异或。但是单单这样拿去解肯定解不出来,因为他还给密钥进行了加密:

后面那几个dword_xxxx其实就是key[i]

1
2
3
4
5
6
7
8
9
10
11
12
13
cipher = [119, 9, 40, 44, 106, 83, 126, 123, 33, 87, 113, 123, 112, 93, 125, 127, 41, 82, 44, 127, 39, 3, 126, 125, 119, 87, 47, 125, 33, 6, 44, 127, 112, 0, 126, 123, 115, 24]
key = [0x56, 0x57, 0x58, 0x59]

key[0] ^= 0x47
key[1] ^= 0x32
key[2] ^= 0x11
key[3] ^= 0x12

flag = ''
for i in range(len(cipher)):
flag += chr(cipher[i] ^ key[i % 4])

print(flag)

nssctf-mobile专题(一)
http://example.com/2023/09/07/CTF/nssctf-mobile专题(一)/
作者
gla2xy
发布于
2023年9月7日
许可协议