Skip to content
This repository was archived by the owner on Oct 24, 2021. It is now read-only.

Commit 316ed3b

Browse files
committed
magic octf 2020
1 parent c0f5d58 commit 316ed3b

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed

2020-MAGICoCTF/README.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# MAGIC oCTF 2020
2+
3+
b1c takes first! :)
4+
5+
## nortum_client
6+
No description here since the challenges locked after the CTF ended.
7+
8+
Basically we are given a binary called [nortum_client](nortum_client). We are supposed to implement a socket server, and we'll get the flag somehow.
9+
10+
The binary is compiled with nuitka, which makes decompiling pretty difficult.
11+
12+
The challenge description also gives us important clues:
13+
- We have to format our server messages as `<Line> <Line> <Data> [line] [line] [line] ...`
14+
- We have to bind our server to port 1228
15+
- We have to send 2 big or little endian unsigned ints to the server
16+
17+
It takes a bit to think of the right way to interpret it, but the correct way to send data is:
18+
19+
`\n\n<packed number><packed number>\n\n\n`
20+
21+
Now to analyze the binary, we can try running `strings` on the binary:
22+
```
23+
?127.0.0.1decodeAF_INETpackaged_answerabsdiffcombinedencodeosError preforming arithmetic function. Incorrect data type?utf-8IPUnknown error packing and sending reply.socketConnection to the server failed. Verify that the IP and port are correct.charscp437intsError unpacking data. Incorrect data type?sub__debug__Did not receive correct confirmation response.received_datatimeoutbuild_flagrecvsetblockingNo message was received before timeout.Sent flag.splitlinesitem>Istart_timeWaiting for welcoming message. . .
24+
TrueexitWaiting for boolean response. . .
25+
SOCK_STREAMnumconnect
26+
Received tuple: %smsgrecv_timeoutbytes_linestrstructsleepFalseprint_received_msgReceived message doesn't have the correct formatting.types
27+
Sending answer. (%s)syssendall<module>/root/Desktop/nortum_client_packed.pyappendReceived correct confirmation.PORT
28+
```
29+
30+
In the mess above we can see a `>I`, so we can most likely assume that's how the server is unpacking bytes we send, meaning it wants big endian (`>`) unsigned ints (`I`), according to Python's [struct documentation](https://docs.python.org/2/library/struct.html).
31+
32+
After some light guesswork, our binary does the following:
33+
- Connect to 127.0.0.1 on port 1228
34+
- Expect a welcome message
35+
- Validate a welcome message
36+
- Do some operations on the welcome message
37+
- Send something back
38+
- Wait a confirmation value back
39+
- Validate the confirmation value
40+
- Give the flag
41+
42+
We can implement a basic Python socket server:
43+
44+
```python
45+
import socket, struct
46+
47+
s = socket.socket()
48+
49+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
50+
print "ok"
51+
52+
port = 1228
53+
s.bind(("", port))
54+
55+
print "bound to 1228"
56+
57+
s.listen(5)
58+
59+
print "listening"
60+
61+
while True:
62+
c, addr = s.accept()
63+
print "conn from ", addr
64+
65+
c.sendall("\n\n" + struct.pack(">I", 1234) + struct.pack(">I", 1234) + "\n\n\n") # send two big endian unsigned ints
66+
67+
data = c.recv(4096) # receive response
68+
print struct.unpack(">I", data) # view response
69+
c.close()
70+
71+
s.shutdown()
72+
```
73+
74+
Running the server and then the client gives:
75+
76+
![](https://i.imgur.com/4TYQx9n.png)
77+
78+
![](https://i.imgur.com/54UKJwU.png)
79+
80+
So we need to send some sort of boolean response.
81+
We can't send an actual boolean, and sending 0x0, 0x1, or any other integer doesn't work.
82+
83+
However, from the `strings` mess above, we can see a `True` in there. So, we try to send a string, `"True"`:
84+
85+
![](https://i.imgur.com/RjmkdXd.png)
86+
87+
![](https://i.imgur.com/Zs2QNv9.png)
88+
89+
!! Nice!
90+
91+
We can just print the flag that the client sent with
92+
`print c.recv(4096)`.
93+
94+
Final [server script](server.py):
95+
```python
96+
import socket, struct
97+
98+
s = socket.socket()
99+
100+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
101+
print "ok"
102+
103+
port = 1228
104+
s.bind(("", port))
105+
106+
print "bound to 1228"
107+
108+
s.listen(5)
109+
110+
print "listening"
111+
112+
while True:
113+
c, addr = s.accept()
114+
print "conn from ", addr
115+
116+
c.sendall("\n\n" + struct.pack(">I", 1234) + struct.pack(">I", 1234) + "\n\n\n") # send two big endian unsigned ints
117+
118+
data = c.recv(4096) # receive response
119+
print struct.unpack(">I", data) # view response
120+
121+
c.sendall("True") # send "boolean" value
122+
print c.recv(4096) # receive flag
123+
c.close()
124+
125+
s.shutdown()
126+
```
127+
128+
Flag: `flag{sixty6}`
129+
130+
All credit goes to MAGIC for their challenge. This is just a writeup.

2020-MAGICoCTF/nortum_client

234 KB
Binary file not shown.

2020-MAGICoCTF/server.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import socket, struct
2+
3+
s = socket.socket()
4+
5+
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
6+
print "ok"
7+
8+
port = 1228
9+
s.bind(("", port))
10+
11+
print "bound to 1228"
12+
13+
s.listen(5)
14+
15+
print "listening"
16+
17+
while True:
18+
c, addr = s.accept()
19+
print "conn from ", addr
20+
21+
c.sendall("\n\n" + struct.pack(">I", 1234) + struct.pack(">I", 1234) + "\n\n\n")
22+
23+
data = c.recv(4096)
24+
print(struct.unpack(">I", data))
25+
data = struct.unpack(">I", data)
26+
c.sendall("True")
27+
print(c.recv(4096))
28+
c.close()
29+
s.shutdown()

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ This is where I store writeups for CTF challenges that I've either solved, helpe
2626
[Zh3r0 PreCTF](2020-Zh3r0PreCTF)
2727

2828
[SharkyCTF](2020-SharkyCTF)
29+
30+
[MAGIC oCTF](2020-MAGICoCTF)

0 commit comments

Comments
 (0)