1
2
| $ file *
SpeedyQuizy.apk: Zip archive data, at least v0.0 to extract
|
Introduction#
This is an android mobile application file apk
. We can use jadx to easily analyze the code.
Analysis#
The main package is com.example.speedyquizy
. The MainActivity
is empty and just starts the StartQuiz
activity, so we will
focus on it.
All StartQuiz
is doing is setting up a connection to www2.wargames.my:8080
, receives from the server
and forward it to the UI, and receives input from the user and sends it back to the server. So actually we will stop android reversing
because this is all there is to it and focus on www2.wargames.my:8080
inner workings.
The quiz server#
When connecting to www2.wargames.my:8080
we get:
1
2
3
4
5
| [2020-12-06 04:44:41pm] You are to answer 3 question in 4 seconds.
Any incorrect attempt will require you to start again.
If not sure, just answer in small letter.
Type 'ok' to proceed, or 'quit' to end
|
We can also see in the app that it sends ok
automatically if it detects this message, doing so:
1
2
| [2020-12-06 04:45:45pm] Question No 1
> Divide 35772 with 18137. Round to the nearest whole number.
|
Let’s answer anything:
1
2
3
4
5
6
| 999
[2020-12-06 04:45:49pm] You answered 999 for question no 1
INCORRECT!
Please try again. Closing connection.
|
So we need to build a script that solves questions for us fast.
Running it multiple times, we can get collection of questions:
1
2
3
4
5
6
7
| > Biggest port number possible
> Reverse of doof is ...
> Given 98249 - 71052 = x and y=2+x. Find y.
> Multiply 51243 and 7036.
> Can you add 81837 to 75642?
> DNS zone transfer occurs on port 53. (Of course you know that). But, it is TCP or UDP?
...
|
There are two types of questions, math and not math. For math questions they involve random numbers, so
if you got Multiply....
question the numbers will be different, but for non math questions they are always the same,
like DNS zone transfer...
.
Solution#
We can build a small python script to solve it for us
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
80
81
82
83
84
85
| import socket
import re
HOST = 'www2.wargames.my'
PORT = 8080
# map to store all solutions got from the user until now
solutions = {}
# tries to find questions that contain randomness and solves them
# Note: the code is not the best, but works
def try_solve(data):
s = re.findall(b'Multiply (\d*) and (\d*)', data)
if s:
s = s[0]
return int(s[0]) * int(s[1])
s = re.findall(b'Given (\d*) - (\d*)', data)
if s:
s = s[0]
return int(s[0]) - int(s[1]) + 2
s = re.findall(b'Can you add (\d*) to (\d*)', data)
if s:
s = s[0]
return int(s[0]) + int(s[1])
s = re.findall(b'Divide (\d*) with (\d*)', data)
if s:
s = s[0]
return round(int(s[0]) / int(s[1]))
return None
def process(s):
while True:
# recive from the server
data = s.recv(1024)
# split into lines, as sometimes half of it is received
for line in data.split(b'\n'):
# print for debugging
print(line)
# if its empty, ignore this line and go to the next line
if not line:
continue
# if we are starting, send `ok`
if b'to proceed' in line:
s.sendall(b'ok')
# if the connection is closing, return and connect again
elif b'Closing' in line:
return
# if the connection is closing, return and connect again
elif b'faster' in line:
return
# This is a question line
elif line[0] == b'>'[0]:
# Try to solve it using the smart way
d = try_solve(line)
# If there is a solution send it
if d:
s.sendall(str(d).encode())
continue
# If we have a previously recorded solution from the user, use it
if line in solutions:
print("found in solutions")
s.sendall(solutions[line])
else:
# ask the user for a solution
r = input().encode()
# record it and send it
solutions[line] = r
try:
s.sendall(r)
except:
# the server shutdown on us
break
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
process(s)
|
Using this script, some questions I have to solve manually, but they will be saved if they came in the future,
after some tries we get the flag:
1
| wgmy{418b3ea849ff3b93def86cfbc90440c1}
|