Author: Ephvuln
Category: Mobile, Web
Points: 280
Solves: 44
We are given an apk and a wordlist containing UUIDs (Universally Unique Identifier)
First, we need to provide the Current Instance IP and Port to the application
Looking at the analysis,
The challenge has 2 API endpoints,
/api/v1/acc/pass/and/api/v1/sec/In the application, they have 2 EditText fields, one for Password and another for SecretText
In
/api/v1/acc/pass/, it will verify the password we entered by comparing the hash returned by the server for the correspoding UUID
with the SHA256 Hash of the concatenated stringLbhXabjVaCenpgvprFnygfNerHavdhrylTrarengrqSbeRirelCnffOhgVzGbbYnmlGbPbqrGung:)and the password we entered
So, first we need to determine the valid UUIDs and their corresponding hash with the given attachment wordlist.
1
2
3
4
5
6
7
8
9
10
11import requests
with open("wordlist.txt","r") as f:
data = f.readlines()
for i in data:
i = i.strip()
r = requests.get(f"url/api/v1/acc/pass/{i}", headers={"X-MOBISEC":"ef75826d9de13292593aa57f82a7763d","Accept":"application/json"})
d = r.json()
if d['secret']['hash'] != "":
print(d,i)We got
1
2
3{'secret': {'hash': '77518b39e620ac271bfc58639796160cb3984af0a3e5f4367230ad768855e8e7'}} c8d8a726-a7c2-4b13-98a4-15f9c3831ef4
{'secret': {'hash': '87bcb0554d72bd277ae6c2795b8e09e03c56ed4314352449c3d371b70cdc1ea8'}} f79dd76f-2ce4-420f-bf46-f0ba82af04fb
{'secret': {'hash': 'e045171f3d3d93ee538b4673f7b5184bfd7d9eaa200f29f81ae1b7123a32ebca'}} 4d1713c1-ef9e-46b1-9fee-9ac57d4180b8Now, we need to find the password associated with these hashes by bruteforcing with rockyou.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import hashlib
with open("rockyou.txt", 'r', encoding='utf-8', errors='ignore') as f:
data = f.readlines()
count = 0
for i in data:
i = i.strip()
combine = "LbhXabjVaCenpgvprFnygfNerHavdhrylTrarengrqSbeRirelCnffOhgVzGbbYnmlGbPbqrGung:)"+i
hs = hashlib.sha256(combine.encode()).hexdigest()
if hs == "77518b39e620ac271bfc58639796160cb3984af0a3e5f4367230ad768855e8e7" or hs == "87bcb0554d72bd277ae6c2795b8e09e03c56ed4314352449c3d371b70cdc1ea8" or hs == "e045171f3d3d93ee538b4673f7b5184bfd7d9eaa200f29f81ae1b7123a32ebca":
print(i,hs)
count+=1
if count == 3:
breakWe got
1
2
3killerpink007 e045171f3d3d93ee538b4673f7b5184bfd7d9eaa200f29f81ae1b7123a32ebca
SHALLOWgrounds13 87bcb0554d72bd277ae6c2795b8e09e03c56ed4314352449c3d371b70cdc1ea8
86390627 77518b39e620ac271bfc58639796160cb3984af0a3e5f4367230ad768855e8e7Now, on checking what the server provides us at
/api/v1/sec/, we will get an encrypted text.

- Here are the encrypted texts corresponding to the UUIDs.
1
2
3c8d8a726-a7c2-4b13-98a4-15f9c3831ef4 -> 0SlT+QWWG+6A3gxxUey87oIUHxmB2Hpex4cB2kDZz6ONVLCYHgJBuNgfIWceh0WF8VUGkUhOkDemH4XcSyYRFdtwXzHE6EkkEbGu
f79dd76f-2ce4-420f-bf46-f0ba82af04fb -> xk9xj6E3f5pSHQjsmBOe2DoYegnOMyk1ej90DJrkBLKQjugbyaC0pG8Pb2xn5W//Q4fg/pt6nmj8wjlGkYAJGahbzwSoX+NGShZFivYLfkb4Zs7TY9HKs96p5KuzEY/GxUo67vg=
4d1713c1-ef9e-46b1-9fee-9ac57d4180b8 -> 2mLZZaw/Wq6Ppo1E6uyDeRioC/RpLk2Hj+t0/+F+lFJyc3GnTwjeBqAHFIQS8q4lzFE=- Inorder to decrypt them, the challenge description mentions how the encrypted text is split into
nonce, tag, ciphertext = encrypted_data[:16], encrypted_data[16:32], encrypted_data[32:] - On using the text and password pair,
SHALLOWgrounds13andxk9xj6E3f5pSHQjsmBOe2DoYegnOMyk1ej90DJrkBLKQjugbyaC0pG8Pb2xn5W//Q4fg/pt6nmj8wjlGkYAJGahbzwSoX+NGShZFivYLfkb4Zs7TY9HKs96p5KuzEY/GxUo67vg=, we get the flag
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
28from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256
from Crypto.Random import get_random_bytes
import hashlib
import base64
def J(password, data):
salt = b"0123456789abcdef"
key = PBKDF2(password, salt, dkLen=32, count=100000)
nonce = data[:16]
ciphertext_and_tag = data[16:]
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext_and_tag[16:], ciphertext_and_tag[:16])
return plaintext
password = b"SHALLOWgrounds13"
ciphertext = base64.b64decode("xk9xj6E3f5pSHQjsmBOe2DoYegnOMyk1ej90DJrkBLKQjugbyaC0pG8Pb2xn5W//Q4fg/pt6nmj8wjlGkYAJGahbzwSoX+NGShZFivYLfkb4Zs7TY9HKs96p5KuzEY/GxUo67vg=")
try:
decrypted_data = J(password, ciphertext)
print(decrypted_data)
except Exception as e:
print(f"Decryption failed: {e}")Flag:
CTF{77cd55d22ef0d516a45ed0e238fbc5dbc4c93b0824047ea3e0a0509a5a9735ac}