【攻防世界】Moblie系列之Easy-app

【攻防世界】Mobile系列之Easy-app

分析

该app也是一个登录验证逻辑

使用jadx反汇编该app,调用了native层的native-lib.so文件对字符串进行检验

使用ida打开native-lib.so文件,找到MainActivity_check方法,看到一长串的伪代码如下

想通过上面的伪代码去得到逻辑关系是比较困难,反正我有点不想看。外面再通过字符串来对伪代码进行理解,在IDA中查看该so文件用到的字符串,如下

check函数进行第一次转换,去掉flag格式,将输入分成两组,一组16个字符。

将前十六位的高四位和后十六位的低四位组合存放到后十六位,将后十六位的高四位和前十六位的低四位组合存放到前十六位。

之后在分成4组进行tea加密,key这里运行时候被修改了,正确的应该是0x42,0x37,0x2c,0x21。

之后进行换表base64加密,这个有一个点就是,base64_encode中不止包括了base64加密,还有移位操作。将编码之后的base64,每三位循环向左移动,第四位做分隔符不变。从文件中找base64的表为abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ+/,所有算法反推回去就是flag。

逆向代码

将移位后的base64编码进行还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#coding:utf8

base64_out="e)n*pNe%PQy!^oS(@HtkUu+Cd$#hmmK&ieytiWwYkIA="
print(len(base64_out))#44
base64_ok=""
temp=""
for i in range(len(base64_out)):
if i%4==0:
temp=base64_out[i:i+4]
#print(temp)
base64_ok+=temp[2]
base64_ok+=temp[0]
base64_ok+=temp[1]
base64_ok+=temp[3]
else:
print("")
print(base64_ok)

#ne)*epN%yPQ!S^o(t@Hk+UuC#d$hKmm&yietwiWYAkI=

对上方的字符串进行base64解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import base64
import string
import binascii
base64_ok="ne)*epN%yPQ!S^o(t@Hk+UuC#d$hKmm&yietwiWYAkI="

outtab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
intab = "abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ+/"

teaout=(base64.b64decode(base64_ok.translate(base64_ok.maketrans(intab,outtab))))#b'4H\xe1\x10\xfc^c=\x1a\xd9\xf3\xa2M\xba\xca\xfb\x85&p7G\xb8\xc3 `\x81\x13X\x8e\xbc\x90\xab'
print(teaout)
print(type(teaout))
tea_out=binascii.hexlify(teaout).decode('utf-8')#https://www.delftstack.com/zh/howto/python/python-convert-hex-to-byte/
print(tea_out)


3448e110fc5e633d1ad9f3a24dbacafb8526703747b8c320608113588ebc90ab

然后再进行tea解密

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
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
#include <string.h>

void decrypt(unsigned int *v, unsigned int *k)
{
unsigned int v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;
unsigned int delta = 0x9e3779b9;
unsigned int k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++)
{
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main(){
int i=0;
unsigned int v[2] = {0, 0}, k[4] = {66, 55, 44, 33};

char tea_out[64]="\x34\x48\xe1\x10\xfc\x5e\x63\x3d\x1a\xd9\xf3\xa2\x4d\xba\xca\xfb\x85\x26\x70\x37\x47\xb8\xc3\x20\x60\x81\x13\x58\x8e\xbc\x90\xab";

for(i=0;i<strlen(tea_out);i+=8){
unsigned int *v=(unsigned int *)&tea_out[i];
//printf("%x %x\n", v[0], v[1]);
decrypt(v, k);
printf("%x %x\n", v[0], v[1]);
}
return 0;
}

/*
36346065 38673534
65353537 62303531
61333232 34363160
63316239 35356761
即6560343634356738373535653135306232323361603136343962316361673535
*/

然后进行高位计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tea="6560343634356738373535653135306232323361603136343962316361673535"
tea1=tea[::2]#从0都结束 每step2进行取值 https://blog.csdn.net/Evan123mg/article/details/49232089
tea2=tea[1::2]#从1都结束 每step2进行取值
print(tea1)#6633336333363336 3336633336366633
print(tea2)#50464578755515022231016492131755

temp=tea1[16:]+tea1[:16] #3336633336366633 6633336333363336 高16位和低16位换位置
print(temp)
flag=""
for i in range(len(temp)):
flag+=temp[i]+tea2[i]
print(flag)#3530346664353738376535656165303262623331303166343932316331373565
print(bytes.fromhex(flag))

b'504fd5787e5eae02bb3101f4921c175e'

最后得到

1
flag{504fd5787e5eae02bb3101f4921c175e}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信