Skip to content

Commit

Permalink
update auth bypass
Browse files Browse the repository at this point in the history
  • Loading branch information
zardus committed Sep 1, 2024
1 parent 361811a commit 2193576
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
9 changes: 9 additions & 0 deletions web-security/level-3/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Of course, web applications can have security vulnerabilities that have nothing to do with the shell.
A common type of vulnerability is an _Authentication Bypass_, where an attacker can bypass the typical authentication logic of an application and log in without knowing the necessary user credentials.

This level challenges you to explore one such scenario.
The goal here is not only to let you experience how such vulnerabilites might arise, but to familiarize you with _databases_: places where web applications stored structured data.
As you'll see in this level, data is stored into and read from these databases using a language called the _Structured Query Language_, or SQL (often pronounced like "sequel") for short.
SQL will become incredibly relevant later, but for now, it is an incidental part of the challenge.

Anyways, go and bypass this authentication to log in as the `admin` user and get the flag!
1 change: 0 additions & 1 deletion web-security/level-3/run

This file was deleted.

71 changes: 71 additions & 0 deletions web-security/level-3/server
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/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 IF NOT EXISTS users AS SELECT "admin" AS username, ? as password""", [os.urandom(8).decode('latin1')])
# 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")

user = db.execute("SELECT rowid, * FROM users WHERE username = ? AND password = ?", (username, password)).fetchone()
if not user:
flask.abort(403, "Invalid username or password")

return flask.redirect(f"""{flask.request.path}?session_user_id={int(user["rowid"])}""")


@app.route("/", methods=["GET"])
def challenge_get():
if "session_user_id" not in flask.request.args:
return """
<html><body>
Welcome to the login service! Please log in as admin to get the flag.
<form method=post>
User:<input type=text name=username>Pass:<input type=text name=password><input type=submit value=Submit>
</form>
</body></html>
"""

user_id = int(flask.request.args["session_user_id"])
user = db.execute("SELECT * FROM users WHERE rowid = ?", (user_id,)).fetchone()
if not user:
flask.abort(403, "No such user")

username = user["username"]
page = f"<html><body>Hello, {username}!"
if username == "admin":
page += "<br>Here is your flag: " + open("/flag").read()
page += "</body></html>"
return page


os.setuid(os.geteuid())
app.secret_key = os.urandom(8)
app.run("challenge.localhost", int(os.environ.get("HTTP_PORT", 80)))

0 comments on commit 2193576

Please sign in to comment.