A forgotten CTF Writeup

Foreword

This is my first ever CTF writeup I ever done in my life, since I ever delved into the rabbit hole of CTF and cybersecurity.

The challenge is from the CTFFlag Asia Junior

I’ll put a link here if you want to learn more:
CTFFlag Asia Junior

(I never feel so dumb myself UwU.)

The Kid Protocol - an UDP based application Protocol

From the challenge description:

Kid Protocol is an application-layer protocol that has just been created based on the UDP protocol.
The Python code below is the source code of the server running the Kid Protocol. If you have. Can you read this protocol and write a program to communicate with the server?

Access information:

1
2
Server IP: 178.128.19.56 (Probably outdated, not working anymore)
UDP Port: 3108

Overview

Here’s an overview of the kid protocol server code provided by the challenge

kid_server.pyview raw
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
86
87
88
89
90
#!/usr/bin/python3
import socket
import json
import struct
import logging

# Cấu hình tập tin lưu log của server
logging.basicConfig(filename='./log/kid_server.log', format='%(asctime)s %(message)s')

class KidServer:
def __init__(self, host, port):
# Khởi tạo UDP socket và lắng nghe kết nối
self.socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
self.socket.bind((host, port))
self.fileList = ["intro.txt", "flag.txt"]

def start(self):
# Vòng lặp vô hạn xử lý các gói tin nhận được
while(True):
try:
rawPacket, clientIP = self.socket.recvfrom(4096)
data = self.handle(rawPacket)
self.response(data, clientIP)
except KeyboardInterrupt:
exit()
except:
logging.exception("")

# Xử lý gói tin nhận được
def handle(self, rawPacket):
try:
kidPacket = KidPacket(rawPacket)
action = getValue(kidPacket.body, "action")
inputFile = getValue(kidPacket.body, "file")

if action == "read":
if inputFile in self.fileList:
file = inputFile
else:
file = "intro.txt"

with open(file, "r") as f:
return f.read()

return "Wrong action"
except Exception as e:
return str(e)

# Gửi phản hồi về cho client
def response(self, data, clientIP):
self.socket.sendto(bytes(data, encoding="utf8"), clientIP)

def getValue(object, key):
try:
return object[key]
except KeyError:
raise Exception("Missing '%s' param" % key)

class KidPacket:
def __init__(self, rawPacket):
self.parse(rawPacket)

# Hàm xử lý / kiểm tra cấu trúc gói tin
def parse(self, rawPacket):
#
# Dòng code bên dưới đang chuyển đổi 2 bytes đầu của gói tin
# từ dạng little endian về dạng số, đây là phần contentLength.
# Em có thể tìm hiểu thêm hàm struct.pack(), nó sẽ giúp em
# chuyển đổi theo chiều ngược lại.
#
self.contentLength = struct.unpack("<H", rawPacket[0:2])[0]

# Các bytes còn lại của gói tin được xem là phần dữ liệu
data = rawPacket[2:]

if self.contentLength != len(data):
raise Exception("Bad content-length")

# Chuyển đổi dữ liệu nhận được thành JSON object
try:
self.body = json.loads(data)
except:
raise Exception("Bad format")

def main():
# Khởi tạo server lắng nghe trên 0.0.0.0:3108
server = KidServer("0.0.0.0", 3108)
server.start()

main()