[CISCN 2022 东北]crackme_Android
整个分析如下图所示:
很简单。就是将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搜索出来):
同理其他字符串也可以通过这种方法搜索出来,后续不再提及。
密码验证这一块进行了加密处理:
很容易逆出来,这里直接贴代码:
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 += hex(each + 1)[2:].zfill(2) print(md5)
|
当然,直接修改smali语言也可以绕过登录验证,可以修改条件跳转指令,也可以修改checkUsername和checkPasswd方法的返回值(在return v2前面加一个赋值语句:const/4 ,0x1)。有兴趣的可以试试。
账号密码验证通过后,还会调用getKeyAndRedirect
方法,主要是开辟线程,这个线程会调用lambda$getKeyAndRedirect$0$MainActivity
方法远程获取key
(需要注意的是,要在samil语言上修改socket
的ip
和port
为nssctf给的),然后通过Intent
开启CheckFlagActivity
活动并传入key
。
跟进CheckFlagActivity
,该活动主要是通过Intent获取key
参数,然后获取我们输入的flag,然后调用checkFlag
方法验证 flag。
这里调用了EncodeUtils.encode
方法对 flag 进行了加密,再与encodeFlag
字符串对比,该字符串通过搜索可知是3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P
。
接下来查看EncodeUtils.encode
方法:
其实就是一个base64加密,只不过base64表通过服务器给出。
整个过程理清楚之后,我们就需要动调来获取base64表,因此在EncodeUtils.encode
方法被调用处下断点(当然你如果觉得不太靠谱,可以往前几步再下断点,因为smali语言的操作都是经过寄存器来进行的,过多执行几步的话里面的数据就可能被更改了)(jadx需要在smali语言中按F2
下断点),然后进行动调。
在转smail语言时,tab键好像不会定位到对应代码,不过我们可以通过方法名按ctrl+F定位
获取到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"); }
|
那么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)
|