Re-WP(更新中…)

Logindemo

一开始用jadx看的,给我看傻逼了说是,带了比较抽象的混淆,然后导致我看了好久才理清楚逻辑

image-20241001213128258

后面用JEB看就舒服多了,从最后由网络行为发出去的签名往回推即可,锁定secretKey这个变量

image-20241001213851019

这里secretKey往回的第一个函数有点迷,拷打了一下gpt,说是反射的dex_class.dex这个文件中的say_hello方法

image-20241001214349109

跟进这个方法之后发现就是一个异或

image-20241001214443555

从给的另一个附件中锁定关键数据,解出secretKey

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

table='S0C0Z0Y0W'
encoded_str = "YgNxAGMDawJjZQR6B2IGYANiYQVxAG8JYQhkawZ3AW8JagluYAN2Am4GbQRmZAR6AWwBbQNlZANxCWsCaAlhZQRxAm4CbgRkZgl1AWIIawhmYAh3B2MBaAJmaghwAWoEbwliYgBwCWkIbQNuawlyAW0FYAhuYgB1Am8CawRuYAJxCG8CbgRgZAF3BWgJYQlhZwFzAGsJbwFlagV0CW0FawhgawNyCGkAbQNjYQh3Bm4FbwNkYAJ6A2IDaANmYwl2A2sEaQRlaglyAm0HaARmYQZ7AWsIbwZhYwB0B2sIYAlvYgN2AWsHYQJiZAByAGgDYANmYQB0BmwJYABhZwl1CGkEaQlmZQJzBm0IYQdjYwh6A20BbwVhZQl3CGoIaABmYAN1AW0IbQFvYAN0B2gFYAVhZAF1BW8HYQZvagZ6A20CaAhjZAl6BWkCYQhvZAN1AGgDaQJhYQZzCW8BYABjZAN0AW8BbQViZwVyA28JagJiagd1CGgDawhvYQJwB28GagNvYwd6AG0BYQFuawVyBGoBaQFkZAV1A24HbgdlYgd1AWwIYQNkagV6BW0DbglvZAl0A2kFaAhjawB3AmwAbwZgZwV3BGMEaQllYAhzAGsEYAFhYAJ6Bm4GaQdkagl6A20DawdkZgd3BW0JbgRgYQZyB2kJbANnZgdwA2gFaQFnYAh7BW4GbAdhYgd7Bm4DawJmawN0CWMDbgJgYwh0AmwGYQRiYQN2BmIGaAVkYwh2BmsDbAFhaglzB2kAbQBjZwJ1BGkCaghiZgByAWkJaAhhagZ3AG0JaghiYQVwAmMIaAFjYgVzBGh0dHA6Ly80Ny4xMDkuMTA2LjYyOjkwOTB7Im5hbWUiOiJTQ1RGIiwicGFzc3dvcmQiOiI4ODg4ODg4OCJ9"

decoded_bytes = base64.b64decode(encoded_str)

str_index = decoded_bytes.index(b"http")
decoded_bytes = bytearray(decoded_bytes[:str_index])
#print(decoded_bytes.decode('utf-8'))

de_data=[]
for i in range(len(decoded_bytes)):
de_data.append(chr(decoded_bytes[i]^ord(table[i%len(table)])))

decrypted_str = ''.join(de_data)
print("after_invoke:", decrypted_str)

异或完之后接着往回逆,逻辑倒过来的话那就是先解native层的Getstr.getNothing,然后是LoginActivity.transform,最后是GoodCard.anything

image-20241001214800294

先跟进Getstr.getNothing,比赛的时候太着急了,当时看到65537迟钝了一秒,感觉好熟悉,但是就死活没想起来是RSA加密,反编译之后直接锁定到关键的取值函数,从一坨数字中取出RSA的q和p

image-20241001215241524

用下面的RSA板子直接解

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def modular_exponentiation(base, exp, mod):
"""
快速模幂运算,计算 (base^exp) % mod
使用指数的二进制展开方法以加速大整数运算。
"""
result = 1
base = base % mod # 确保 base 小于 mod
while exp > 0:
if exp % 2 == 1: # 如果 exp 是奇数
result = (result * base) % mod
exp = exp >> 1 # exp //= 2
base = (base * base) % mod # base 的平方
return result

def rsa_decrypt(ciphertext, d, n):
"""
使用 RSA 私钥指数 d 和模数 n 解密密文。

:param ciphertext: 加密后的密文 (整数形式)
:param d: 私钥指数
:param n: 模数
:return: 解密后的明文 (整数形式)
"""
return modular_exponentiation(ciphertext, d, n)

def rsa_keygen(p, q, e):
"""
给定质数 p 和 q 以及公钥指数 e,生成 RSA 密钥对。

:param p: 质数 p
:param q: 质数 q
:param e: 公钥指数 e
:return: (n, e, d) 三元组,分别是模数 n,公钥指数 e 和私钥指数 d
"""
# 计算模数 n
n = p * q
# 计算欧拉函数 φ(n)
phi = (p - 1) * (q - 1)
# 计算私钥指数 d
d = mod_inverse(e, phi)
return n, e, d

def extended_gcd(a, b):
"""
扩展欧几里得算法,计算 a 和 b 的最大公约数,并找到 a 的模逆元。
返回 gcd, x, y,其中 gcd 是 a 和 b 的最大公约数,x 和 y 满足 gcd = a * x + b * y。
"""
if a == 0:
return b, 0, 1
gcd, x1, y1 = extended_gcd(b % a, a)
x = y1 - (b // a) * x1
y = x1
return gcd, x, y

def mod_inverse(e, phi):
"""
计算 e 关于 φ(n) 的模逆元 d,使得 (d * e) % phi == 1。
"""
gcd, x, y = extended_gcd(e, phi)
if gcd != 1:
raise ValueError("e 和 φ(n) 不是互质的,无法计算模逆元")
else:
return x % phi

if __name__ == "__main__":
# 给定的质数 p 和 q
p = 106697219132480173106064317148705638676529121742557567770857687729397446898790451577487723991083173010242416863238099716044775658681981821407922722052778958942891831033512463262741053961681512908218003840408526915629689432111480588966800949428079015682624591636010678691927285321708935076221951173426894836169
q = 144819424465842307806353672547344125290716753535239658417883828941232509622838692761917211806963011168822281666033695157426515864265527046213326145174398018859056439431422867957079149967592078894410082695714160599647180947207504108618794637872261572262805565517756922288320779308895819726074229154002310375209
e = 65537

n, e, d = rsa_keygen(p, q, e)

ciphertext = 1320932246497869352520598838641593993352464417491614327329121966422427435961882813847911219831046951039384398911759891062522493228527477145298964100196129579752878318304342846456333293831310953140429912771412681186660077189981351178257010239312076699064968340916206788740893716566948081013361784183377259567165578689693721847995328887360230262609519047371514554513593259768232882237563380790718198514010137563477721761688339595737987973351848042606674544940923800149163296460739993732735745797472617395305733250103885465761786432218379937270872668452356861530856135169907304044264323855011391869640793852532981141504

decrypted_message = rsa_decrypt(ciphertext, d, n)

print(f"{decrypted_message}")
#12100119001160011500550010400117001090010600530010400540010300

再看下一层,transform就是给ascll码乘100,用上述解出来的结果除回去即可得到121 119 116 115 55 104 117 109 106 53 104 54 103

image-20241001215520989

然后最后一层就是一堆混乱排序的操作,一开始想逆,搓了一会儿脚本感觉脑子要缺氧了,反正现在已经有密文了,长度也是知道的,直接模拟一下怎么打乱的不就好了

image-20241001215825635

上面的打乱顺序的java代码用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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class MyMath:
@staticmethod
def swap(a, i, j):
a[i], a[j] = a[j], a[i]

class GoodCard:
@staticmethod
def anything(s):
card = list(s)
to = len(card) - 1
GoodCard.perfect(card, 0, to, (to + 1) // 2)
return ''.join(card)

@staticmethod
def circle(a, start, i, n2):
k = (i * 2) % n2
while k != i:
temp = a[i + start]
a[i + start] = a[k + start]
a[k + start] = temp
k = (k * 2) % n2

@staticmethod
def perfect(a, start, end, n):
if start >= end:
return

if start == end - 1:
MyMath.swap(a, start, end)
return

k = 0
p = n * 2 + 1
k_3 = 1
while k_3 <= p // 3:
k += 1
k_3 *= 3

m = (k_3 - 1) // 2
GoodCard.right_circle(a, start + m, start + n + m - 1, m)

i = 0
t = 1
while i < k:
GoodCard.circle(a, start - 1, t, m * 2 + 1)
t *= 3
i += 1

GoodCard.perfect(a, m * 2 + start, end, (end - (m * 2 + start) + 1) // 2)

@staticmethod
def reverse(a, start, end):
while start < end:
MyMath.swap(a, start, end)
start += 1
end -= 1

@staticmethod
def right_circle(a, start, end, n):
m = n % (end - start + 1)
GoodCard.reverse(a, end - m + 1, end)
GoodCard.reverse(a, start, end - m)
GoodCard.reverse(a, start, end)

# Example usage
result = GoodCard.anything("abcdefghijklm")

table = "abcdefghijklm"
flag = "ywts7humj5h6g"#121 119 116 115 55 104 117 109 106 53 104 54 103
for i in range(len(flag)):
print(flag[result.index(table[i])],end="")