鸽了好久了

app1

WP区的大佬可能是觉得太简单了,所以写得比较简单,但是对我这种纯小白来说,有些难以理解。

安装dex2jar

下载地址:https://sourceforge.net/projects/dex2jar/

1574779131402

反编译

解压apk,将其中的classes.dex反编译成.jar文件。

1574779030360

在当前目录下生成classes.jar。(修正错误:其实只有一个参数,即.dex。后面的的.jar参数是无效的,并不会命名为输入的jar,而是统一命名为classes-dex2jar.jar)

使用jd-gui查看classes.jar代码

下载地址: http://jd.benow.ca/

点击com.example.yaphetshan.tencentgreat->MainActivity.class

1574779290585

判断的关键代码

if (str1.charAt(b) != (str2.charAt(b) ^ i))

str1是输入字符串,str2是packageInfo.versionName,i是packageInfo.versionCode,后两者的值在BuildConfig.class中找到。

1574779386552

写出解密脚本

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中:

1574782486140

点击跳转至SecondActivity.class

1574782539789

所以就是两个字符串拼接加密后等于后面的字符串。

跳转至Encryto.doRawData

1574782647468

发现没有详细的代码,原因是这是动态链接。

来到apk解压后的文件夹,进入lib,发现armeabi,armeabi-v7a,x86三个文件夹,进入x86文件夹,看到一个libJNIEncrypt.so文件。

1574782815304

使用ida分析,找到doRawData函数。

1574782894941

发现就是个AES加密,key为thisisatestkey==,函数的名字提示了加密模式为ECB,填充为pkcs5,数据块为128。

加密网站:http://tool.chacuo.net/cryptaes

1574782996608

账号和密码拼接后是aimagetencent,尝试各种组合均不正确。

然后又在jar中发现了一个函数FileDataActivit.class

1574783093950

这个Encryto.decode也是AES加密,在ida中可以看出。

解密后为Cas3_0f_A_CAK3,这就是flag。

WP区的大佬说这个程序根本就没想登录后给你flag,因为FileDataActivity这个函数根本就没调用。

easy-apk

主函数

1574831509520

加密函数

1574831531432

我看了好久没看明白,看了题解才知道这其实就是base64的算法,只不过码表换了一下。

参考:Base64及其Python实现

#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

主函数:

1574849597412

a.class:

其实就是换了码表的base64,和easy-apk的算法一样。

1574849632511

主函数涂色的那一行,先使用a.class加密,再使用ncheck加密,此函数位于动态链接中的:

1574849767248

使用ida分析。

对a.class加密后的字符串,先前16位字符和后16位字符交换,再0,1交换,2,3交换...30,31交换。最后与密文比较。

1574849846111

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文件中。

1575385722656

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

1575387617712

这是MISC吧!!脑洞不小。

Last modification:September 9th, 2020 at 03:28 pm