androad逆向啥时候能入个门…

frida

frida的安装

虚拟环境的安装

建议在python虚拟环境中安装frida.关于conda虚拟环境,可以看我的另一篇博客

我将frida环境安装在了python3.8的名为py38虚拟环境中

frida的下载

以下命令默认是安装最新版的frida。有了虚拟环境,就不会报错了,避免走了很多坑

1
2
3
4
5
6
//启动虚拟环境
conda activate py38

//安装frida等
pip install frida
pip install frida-tools

连接模拟器

adb连接模拟器

本人使用的模拟器为夜神模拟器(不同模拟器使用的端口都是不一致的,可以自行百度)

在命令提示符界面中键入命令:

1
2
adb connect 127.0.0.1:62001
//adb disconnect 为取消链接

然后再输入命令:

1
adb devices

使用以下命令查看模拟器cpu架构,先记一下,后面需要根据此来下载对应的frida-server

1
getprop ro.product.cpu.abi

frida-server的下载与使用

参考博客

查看pip安装目录

1
pip list

查看frida的版本

下载地址,选择firda对应版本以及模拟器的cpu架构下载。经过几次测试,发现适合本机模拟器的是以下的版本

我的frida-server文件再E:\Anroid目录下,使用adb将frida-server文件push到模拟器的data/local/tmp目录下

1
adb push E:\Anroid\frida-server-15.1.22-android-x86 data/local/tmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
adb shell
su
cd data/local/tmp
chmod 777 frida-server-15.1.22-android-x86

//运行文件
./frida-server-15.1.22-android-x86
//如果运行失败,则需要更换版本

//进行端口转发
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

//查看 Android 进程列表
frida-ps -R

运行之后,在另一个窗口输入以下命令,进行端口转发

1
adb forward tcp:27042 tcp:27042

frida的基本使用

pass

XCTF anroid 新手区刷题记录

easyjava

app1

用jadx-gui查看

onClick中可以看到主要的对比函数,是异或运算

双击上面的APPLICATION_ID可以跳转到这里

1
2
3
4
5
6
7
version_code = 15
version_name = "X<cP[?PHNB<P?aj"
flag = ""
for i in range(len(version_name)):
flag+=chr(version_code^ord(version_name[i]))
print(flag)
# W3l_T0_GAM3_0ne

app2

(说实话真不太熟悉java,代码审计的功底基本为0……orz)

可以看到这边有个SecondActivity函数

仔细阅读代码,此处应该是stringExtra和stringExtra2字符串经过连接,加密之后需要和左边的字符串相等,继续跟进

分析so文件

loadLibrary()函数,载入外部的模块,有了之前的教训,可以知道so文件放在lib目录下

在cmd环境中使用apktool解包apk文件

1
apktool d app2.apk

奇怪,lib目录下有三个文件夹,里面有三个同名的so文件……

大同小异,我用ida反汇编第二个文件夹中的so文件,可以看到其中的加密函数

可以从函数名称中得知是AES加密,key是”thisisatestkey==”

通过神器cyberchef,可以解密出来(试了好久……)

以为账号试aimage,密码是tencent,就会弹出flag,是我太年轻了……

再回jadx-gui中查看

这边也有和上面一样加密的字符串,cyberchef解密

服了……没想到解出来的就是flag,看来题目就没想过会弹出flag,有点反常规

app3

题目就给出了一个.ab文件,使用010查看一下文件头

看雪大佬博客中说,这边是none,说明是没有加密的意思

转换ab文件

这边使用的是github上的abe工具来将.ab文件转换成jar文件

下载之后,我将abe.jar和app3.ab放在了同一个文件夹中,运行以下命令:

1
java -jar abe.jar unpack  app3.ab app3.tar

解压之后可以看到文件中的apk文件,在模拟器中安装

在同目录下,还有一个db文件中,其中有个Demo.db文件

使用sqlitebrowser打开Demo.db文件

打开之后发现需要密码

用jadx-gui分析base.apk文件,貌似中间就是关键的加密函数了

说实话这边很绕,需要改类名和方法名

class1和class2的定义:

调用:

“Stra1234”(”Stranger”字符串和”123456”各取前四位)md5加密之后,与字符串”Stra1234”和”yaphetshan”(注意方法class1_fun3)结合,也就是”Stra123444e2e4457d4e252ca5b9fe9d20b3fea5yaphetshan”进行SHA-1加密

下面是伪代码:

1
sha1("Stra1234" + md5("Stra1234") + "yaphetshan")[0:7]

“ae56f99”

当然也可以用python、java实现,Java我不是很熟悉,看的我一愣一愣的……

sqlitebrowser打开.db文件

打开后:

很奇怪,是不是我没有执行apk,没有进行下面的语句执行,所有flag没有生成??

easy-dex

这一题真的是见世面了……

hasCode = false , name = Nativeactivity

看大佬博客说,入口点在so文件中的anroid_main函数中

可以看到程序的主逻辑了,当摇动手机到100次的时候,就会生成真正的dex文件,然后删除,我们需要根据它的加密方法,换源dex文件

先把off_43A18数据dump出来

1
2
3
4
5
6
7
import idaapi
start_address=0x7004
data_length=0x3ca10
data=idaapi.get_bytes(start_address, data_length)
fp = open('dump', 'wb')
fp.write(data)
fp.close()

dump出来,然后把加密形式用python实现,代码来源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import zlib

with open('dump', 'rb') as f:
data = list(f.read())
size = 0x3ca10
times = 0
while True:
if times <= 0x59:
t = int(times / 10)
if times % 10 == 9:
s = int(size / 10)
x = (t + 1) * s
if s * t < x:
c = 0
for _ in range(s):
data[s * t + c] = data[s * t + c] ^ times
c += 1
if times == 0x59:
while x < size:
data[x] = data[x] ^ 89
x += 1
break
times += 1

fbytes = bytes(data)
with open('easydex.dex', 'wb') as f1:
f1.write(zlib.decompress(fbytes))

生成的easydex.dex文件用jadx-gui打开

在原apk文件中找到了two_fish字符,可以推断是two_fish加密了

1
I have a male fish and a female fish.

网上的twofish加密是base64解密的,所以我们把easydex.dex中的数组先用base64加密一下

1
2
3
4
5
6
7
import base64
flag = [-120, 77, -14, -38, 17, 5, -42, 44, -32, 109, 85, 31, 24, -91, -112, -83, 64, -83, -128, 84, 5, -94, -98, -30, 18, 70, -26, 71, 5, -99, -62, -58, 117, 29, -44, 6, 112, -4, 81, 84, 9, 22, -51, 95, -34, 12, 47, 77]
data = []
for i in flag:
data.append(i&0xff)
print(base64.b64encode(bytes(data)))
# iE3y2hEF1izgbVUfGKWQrUCtgFQFop7iEkbmRwWdwsZ1HdQGcPxRVAkWzV/eDC9N

qwb{TH3y_Io<e_EACh_OTh3r_FOrEUER}

哪里easy啊…… 。゚ヽ(゚´Д`)ノ゚。

easy-so

用jadx-gui打开,发现加载了so文件,但是发现没有在jadx-gui中发现lib文件夹,把我一慌……

好吧是我瞎了……

还是用老套路,用apktool

1
apktool d easy-so.apk

去lib文件夹下,然后用ida分析一下so文件:

在这边就很清晰了,上脚本:

1
2
3
4
5
6
7
string = "f72c5a36569418a20907b55be5bf95ad"
string1 = ""
for i in range(0,len(string),2):
string1 += string[i+1]
string1 += string[i]
print(string1[16:]+string1[:16])
# 90705bb55efb59da7fc2a5636549812a

flag{90705bb55efb59da7fc2a5636549812a}

基础anroid

有点非预期解的感觉……

用jadx-gui打开之后,发现有压缩包,然后貌似和jpg有关

apktool解包之后,找到这个压缩包,把后缀改成jpg,打开

我这个做法还是挺拉跨的,如果对齐进行了混淆,那就……

看wp之后,发现了一般的做法:

MainAcitvity中有个checkPassword,跟进函数

我用的是爆破:

1
2
3
4
5
6
7
8
flag = ""
for len in range(12):
for t in range(128):
if chr(255 - len - 100 - t) == '0' :
flag += chr(t)
break
print(flag)
# kjihgfedcba`

输入之后,发现还没有完……

验证成功后就到了MainActivity2,发送了一个广播

接受广播器只有一个,接着会启动NextContent这个活动

跟进函数功能就是读取timg_2.zip的内容,然后输入到img.jpg中

androidminifest中有广播内容,也就是”android.is.very.fun”

出来了!!!

anroid 2.0

用jadx-gui打开

还是熟悉的套路,用apktool解包apk之后,在lib文件加下,找到so文件

用ida分析

注意这边有坑点, i!=4,也就是i<4,只对前4位进行了运算

查看Init()函数,大概就是把15位的字符串,分成了三份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
v5 = []
c5 = "LN^dl"
for i in range(len(c5)-1):
v5.append((ord(c5[i])^0x80)//2)
v5.append(ord(c5[4]))
# print(v5)

c6 = [32, 53, 45, 22, 97]
v6 = []

for i in range(len(c6)-1):
v6.append(c6[i]^ord(c5[i]))
v6.append(c6[4])
# print(v6)

c7 = "AFBo}"
v7 = []
for i in range(len(c7)-1):
v7.append(ord(c7[i])^c6[i])
v7.append(ord(c7[4]))
# print(v7)

flag = ""
for i in range(5):
flag += chr(v5[i]) + chr(v6[i]) + chr(v7[i])
print(flag)

APK逆向

题目的意思还是不难理解的,将字符串”Tenshine”md5加密之后,每两位取第一位字符

用cmd5网站加密的时候,看成下面的m5_middle了,纠结了挺久……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib

str = 'Tenshine'

hl = hashlib.md5()

hl.update(str.encode(encoding='utf-8'))
print('"%s" MD5加密后为 :'%str + hl.hexdigest())

string = hl.hexdigest()

for i in range(len(string)):
if i%2 == 0:
print(string[i],end = "")
# bc72f242a6af3857