python-3.xgetpython-requestsburphostheaders

How can I specify the exact http method with python requests?


In Burp Suite the first line of a captured request is usually GET / HTTP/1.1. However, I am currently practicing Host Header injection using the method of supplying an absolute URL in order to something like this:

GET https://vulnerable-website.com/ HTTP/1.1
Host: bad-stuff-here

In python I am using the requests library and am unable to specify the exact GET request I need.

import requests

burp0_url = "https://vulnerable-website.com:443/"
burp0_cookies = {[redacted]}
burp0_headers = {"Host": "bad-stuff-here", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Referer": "https://vulnerable-website.com/", "Connection": "close", "Upgrade-Insecure-Requests": "1"}

output = requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies)

print(output, output.text)

I have tried specifying the GET request in the header dictionary (header = {"GET":" / HTTP/1.1", ...}), however this only results in a GET Header not r Request on the 6th line being sent:

GET / HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: close
GET: /
Host: bad-stuff-here
Accept-Language: en-US,en;q=0.5
Referer: https://vulnerable-website.com/
Upgrade-Insecure-Requests: 1
Cookie: [redacted]

This is a very specific problem and I'm not sure if anyone has had the same issues but any help is appreciated. Maybe a workaround with urllib or something I'm missing. Thanks.


Solution

  • requests uses urllib3 under the hood. You have to craft the request yourself because of non of the clients [urlib, requests, http.client] won't allow you to insert a control character by design.

    You can use a plain socket for this

    msg = 'GET / HTTP/1.1\r\n\r\n'
    s = socket.create_connection(("vulnerable-website.com", 80))
    with closing(s):
        s.send(msg)
        buf = ''.join(iter(partial(s.recv, 4096), ''))