NahamCon CTF 2024-Moblie
Guitar - Easy
Description
Author: @matlac
Have you ever wanted to play the guitar on your phone? Here’s a free app, with all guitar strings included for free!
Download the file(s) below.
Attachments:
com.nahamcon2024.guitar.apk
Solution
First, I installed com.nahamcon2024.guitar.apk
on Android Virtual Device and tried to use the app but there is nothing in the app. So I decided to extract the APK file by using JADX-GUI and went straight forward to resources. Look at res/values/strings.xml
, I tried to find strings in the app that seem interesting and I found it at line 65
1
<string name="secret_string">VGhlIGZsYWcgaXM6IGZsYWd7NDZhZmQ0ZjhkMmNhNTk1YzA5ZTRhYTI5N2I4NGFjYzF9Lg==</string>
Decode secret_strings
as base64 with CyberChef
Result: The flag is: flag{46afd4f8d2ca595c09e4aa297b84acc1}.
Flag: flag{46afd4f8d2ca595c09e4aa297b84acc1}
Kitty Kitty Bang Bang - Easy
Description
Author: @matlac
I found a cool android app to play with a cowboy cat! There’s has to be more going on with the app I can’t see on my screen…
Download the file(s) below.
Attachments:
com.nahamcon2024.kittykittybangbang.apk
Solution
Again, I used JADX-GUI and went to the MainActivity source code. At line 28-35 , It looks like when I tap the screen in the app, the app will print messages including the flag in the log. So I just use ADB Platform-tools to see the messages log.
1
2
3
4
$ adb shell pidof -s com.nahamcon2024.kittykittybangbang
# This command will give PID of the app so I can use it to filter log messages.
$ adb logcat --pid=4831 *:I
# This command use to see log messages.
Flag: flag{f9028245dd46eedbf9b4f8861d73ae0f}
Buggy Jumper 1 - Easy
Description
Author: @matlac
Buggy Jumper is a new mobile game that can be enjoyable for both gamers and hackers! There’s a lot going on, can you get some of game’s source code to see whats happening behind the scenes?
Download the file(s) below.
Attachments:
com.nahamcon2024.buggyjumper.apk
Solution
I opened the APK file by JADX-GUI and I found this is a game made by Godot Engine. So I searched, is there a way to decompile Godot APK and I found Godot RE Tools.
Extract APK with Godot RE Tools. There is an interesting folder which is scripts
and inside the folder, there is a flag.gd
file.
Flag: flag{c2d5a0c9cae9857a3cfa662cd2869835}
Buggy Jumper 2 - Medium
Description
Author: @matlac
Buggy really wants the drip in the shop… Can you buy it for them?
Use the same file from Buggy Jumper 1.
Solution
Back to scripts
folder shop and take a look at shop.gd
. In the files, There are _on_Buy_pressed()
and _on_request_completed()
functions. It seems like when I press the buy button, The app will send a request to a server with /verify
endpoint and ?value=
parameter.
And then _on_request_completed()
will check if
- The response gets 200 code
- The point (locally) >= 73317331
- There is a “flag” in the message from the response
The idea is to trick the server that we have 73317331 points or more so the server will give us the flag.
- Set up proxy on Android Virtual Device and point it to BurpSuite.
- Press the buy button and edit the value of
value
parameter to73317331
and forward. - Look at the server response.
Flag: flag{a31e44ba4df9789ed5491dc43fa22de3}
shop.gd
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
extends Control
var points_label
var owned_label
var bought_label
var poor_label
var flag_label
func _ready():
points_label = get_node("pointsLabel")
owned_label = get_node("ownedLabel")
bought_label = get_node("boughtLabel")
poor_label = get_node("poorLabel")
flag_label = get_node("flagLabel")
points_label.text = "POINTS: " + str(Global.points)
owned_label.visible = false
bought_label.visible = false
poor_label.visible = false
func _on_Main_Menu_pressed():
get_tree().change_scene_to(load("res://MainScene.tscn"))
func _on_Buy_pressed():
var http_request = HTTPRequest.new()
add_child(http_request)
http_request.connect("request_completed", self, "_on_request_completed")
var headers = ["Content-Type: application/json", "Authorization: " + Global.auth_token]
var error = http_request.request(Global.url + "/verify?value=" + str(Global.points), headers)
print(headers)
print(Global.url + "/verify?value=" + str(Global.points))
if error != OK:
pass
func _on_request_completed(result, response_code, headers, body):
if response_code == 200:
var json = JSON.parse(body.get_string_from_utf8())
if json.error == OK:
var message = json.result["message"]
if not Global.has_drippy:
if Global.points >= 73317331 and "flag" in message:
flag_label.text = message
Global.has_drippy = true
bought_label.visible = true
yield (get_tree().create_timer(3.0), "timeout")
bought_label.visible = false
else :
poor_label.visible = true
yield (get_tree().create_timer(3.0), "timeout")
poor_label.visible = false
else :
if "flag" in message:
flag_label.text = message
owned_label.visible = true
yield (get_tree().create_timer(3.0), "timeout")
owned_label.visible = false
else :
pass
else :
pass
Fly Away! 1 - Medium
Description
Author: @matlac
Lenny Kravitz lovers, this new app cleverly named “Fly Away!” can give you random lines from one of his most popular songs. Can you figure out how the songs are being sent to the app?
Download the file(s) below.
Attachments:
com.nahamcon2024.flyaway.apk
Solution
According to Clue, I think the app sends a request to a server, and then the server responds back with lyrics. So I just used the same idea from Buggy Jumper 2
I’m not sure if the app does check about proxy or not but the way I do is to open the app first and then set up the proxy later.
Flag: flag{5949f48d478612cc78a32a71a6643922}