鸽了好久了
app1
WP区的大佬可能是觉得太简单了,所以写得比较简单,但是对我这种纯小白来说,有些难以理解。
安装dex2jar
下载地址:https://sourceforge.net/projects/dex2jar/
反编译
解压apk,将其中的classes.dex反编译成.jar文件。
在当前目录下生成classes.jar。(修正错误:其实只有一个参数,即.dex。后面的的.jar参数是无效的,并不会命名为输入的jar,而是统一命名为classes-dex2jar.jar)
使用jd-gui查看classes.jar代码
下载地址: http://jd.benow.ca/
点击com.example.yaphetshan.tencentgreat
->MainActivity.class
判断的关键代码
if (str1.charAt(b) != (str2.charAt(b) ^ i))
str1是输入字符串,str2是packageInfo.versionName
,i是packageInfo.versionCode
,后两者的值在BuildConfig.class中找到。
写出解密脚本
s = 'X<cP[?PHNB<P?aj'
i = 15
flag = ''
for c in s:
flag += chr(ord(c) ^ i)
print(flag)
app2
按照app1的流程,反编译得到.jar。
MainActivity.class
中:
点击跳转至SecondActivity.class
:
所以就是两个字符串拼接加密后等于后面的字符串。
跳转至Encryto.doRawData
:
发现没有详细的代码,原因是这是动态链接。
来到apk解压后的文件夹,进入lib,发现armeabi
,armeabi-v7a
,x86
三个文件夹,进入x86
文件夹,看到一个libJNIEncrypt.so
文件。
使用ida分析,找到doRawData
函数。
发现就是个AES加密,key为thisisatestkey==
,函数的名字提示了加密模式为ECB,填充为pkcs5,数据块为128。
加密网站:http://tool.chacuo.net/cryptaes
账号和密码拼接后是aimagetencent,尝试各种组合均不正确。
然后又在jar中发现了一个函数FileDataActivit.class
这个Encryto.decode也是AES加密,在ida中可以看出。
解密后为Cas3_0f_A_CAK3,这就是flag。
WP区的大佬说这个程序根本就没想登录后给你flag,因为FileDataActivity这个函数根本就没调用。
easy-apk
主函数
加密函数
我看了好久没看明白,看了题解才知道这其实就是base64的算法,只不过码表换了一下。
#import string
#base64_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/'
base64_charset = ['v', 'w', 'x', 'r', 's', 't', 'u', 'o', 'p', 'q',
'3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'y', 'z', '0', '1', '2',
'P', 'Q', 'R', 'S', 'T', 'K', 'L', 'M', 'N', 'O',
'Z', 'a', 'b', 'c', 'd', 'U', 'V', 'W', 'X', 'Y',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'8', '9', '+', '/' ]
base64_charset = "".join(base64_charset)
print(base64_charset)
def Base64NewDecode(string):
base64_bytes = ["{:0>6}".format(str(bin(base64_charset.index(c))).replace('0b', '')) for c in string if c != '=']
base64_bytes_str = ''.join(base64_bytes)
print(base64_bytes_str)
for i in range(len(base64_bytes_str)//8):
byte = base64_bytes_str[i*8:i*8+8]
print(chr(int(byte, 2)),end='')
Base64NewDecode('5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=')
得到的05397c42f9b6da593a3644162d36eb01加上flag{}
本题跟Android关系不大,主要是Java逆向,关键是看出加密算法是base64.
easyjni
主函数:
a.class:
其实就是换了码表的base64,和easy-apk的算法一样。
主函数涂色的那一行,先使用a.class加密,再使用ncheck加密,此函数位于动态链接中的:
使用ida分析。
对a.class加密后的字符串,先前16位字符和后16位字符交换,再0,1交换,2,3交换...30,31交换。最后与密文比较。
s = list('MbT3sQgX039i3g==AQOoMQFPskB1Bsc7')
for i in range(0, len(s), 2):
s[i], s[i+1] = s[i+1], s[i]
print(''.join(s))
for i in range(len(s)//2):
s[i], s[16+i] = s[16+i], s[i]
print(''.join(s))
base64_charset = ['i', '5', 'j', 'L', 'W', '7', 'S', '0', 'G', 'X',
'6', 'u', 'f', '1', 'c', 'v', '3', 'n', 'y', '4',
'q', '8', 'e', 's', '2', 'Q', '+', 'b', 'd', 'k',
'Y', 'g', 'K', 'O', 'I', 'T', '/', 't', 'A', 'x',
'U', 'r', 'F', 'l', 'V', 'P', 'z', 'h', 'm', 'o',
'w', '9', 'B', 'H', 'C', 'M', 'D', 'p', 'E', 'a',
'J', 'R', 'Z', 'N']
base64_charset = "".join(base64_charset)
print(base64_charset)
def Base64NewDecode(string):
base64_bytes = ["{:0>6}".format(str(bin(base64_charset.index(c))).replace('0b', '')) for c in string if c != '=']
base64_bytes_str = ''.join(base64_bytes)
print(base64_bytes_str)
for i in range(len(base64_bytes_str)//8):
byte = base64_bytes_str[i*8:i*8+8]
print(chr(int(byte, 2)),end='')
Base64NewDecode(s)
easy-so
加密代码在so文件中。
s = list('f72c5a36569418a20907b55be5bf95ad')
for i in range(16):
s[i*2], s[i*2+1] = s[i*2+1], s[i*2]
for i in range(16):
s[i+16], s[i] = s[i], s[i+16]
print(''.join(s))
带上flag{}提交
RememberOther
提示说这题只是跟安卓沾边。
dex反编译很轻松看出就是对输入的字符串取md5,并与 <string name="successed">md5:b3241668ecbeb19921fdac5ac1aafa69</string>
比较。
cmd5网站解密这个要收费,大佬的题解中安利了一个网站:http://www.chamd5.org/
解出YOU_KNOW_
这只是flag的全半段。
然后在FoundItFun.docx
的属性中找到后半段:ANDROID
这是MISC吧!!脑洞不小。