July 2, 2022 at 6:52 AM
Since people are asking about my Python script, I will post the whole script here.
A few things to note:
- Configure /etc/hosts as mentioned in the main method. Reason being is that chat.response.htb is hard-coded in one of the server's JS files. Opening http://127.0.0.1 in Firefox will not work properly.
- At first, I used HTTPServer(). I noticed there were a few request which took about 10 seconds to complete. This made it really slow to interact with the chat application. So I built in multithreading.
- Login as guest:guest (these credentials can be found in the ZIP file)
A few things to note:
- Configure /etc/hosts as mentioned in the main method. Reason being is that chat.response.htb is hard-coded in one of the server's JS files. Opening http://127.0.0.1 in Firefox will not work properly.
- At first, I used HTTPServer(). I noticed there were a few request which took about 10 seconds to complete. This made it really slow to interact with the chat application. So I built in multithreading.
- Login as guest:guest (these credentials can be found in the ZIP file)
import base64
from http.server import BaseHTTPRequestHandler, HTTPServer
import random
import re
import requests
from socketserver import ThreadingMixIn
import sys
import threading
import time
hostName = "0.0.0.0"
serverPort = 80
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.request_handler('GET')
def do_POST(self):
self.request_handler('POST')
def request_handler(self, method):
self.random_number = random.randint(100000,999999)
path = self.path
myurl = 'http://chat.response.htb' + path
print(f"[{self.random_number}] {method} {myurl}")
if method == 'POST':
content_len = int(self.headers.get('Content-Length'))
post_body = self.rfile.read(content_len)
print(f"[{self.random_number}] body: {post_body}")
else:
post_body = None
digest = self.get_digest(myurl)
data = self.send_request_to_proxy(myurl, method, digest, post_body)
self.send_response(200)
if path.endswith('.js'):
self.send_header("Content-type", "application/javascript")
elif path.endswith('.css'):
self.send_header("Content-type", "text/css")
else:
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(data)
def get_digest(self, myurl):
url = 'http://www.response.htb/status/main.js.php'
cookies = {'PHPSESSID': myurl}
response = requests.get(url, cookies=cookies)
response.raise_for_status()
assert 'session_digest' in response.text
session_digest = re.search(r'\'session_digest\':\'([^\']+)', response.text).group(1)
#print(f"[{self.random_number}] digest: {session_digest}")
return session_digest
def send_request_to_proxy(self, myurl, method, digest, body=None):
url = 'http://proxy.response.htb/fetch'
data = {'url': myurl,
'url_digest': digest,
'method': method,
'session': '1a5455b829845168770cb337f1a05507',
'session_digest': 'd27e297b494df599e72985e6e9a166751d7de74136df9d74468aac0818c29125'}
if method == 'POST':
data['body'] = base64.b64encode(body)
response = requests.post(url, json=data)
response.raise_for_status()
assert 'body' in response.text and 'status_code' in response.text
body = response.json()['body']
status_code = response.json()['status_code']
print(f"[{self.random_number}] status_code from proxy: {status_code}; length of body: {len(body)}")
decoded_string = base64.b64decode(body)
return decoded_string
# This part is for multithreaing.
# See https://stackoverflow.com/questions/14088294/multithreaded-web-server-in-python
# Multithreading is necessary because a lot of requests are made when opening the chat application.
# Some requests take several seconds to complete. I don't want these requests to hold back the other ones.
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
def main():
print("Edit your /etc/hosts like this:")
print("10.10.11.163 www.response.htb proxy.response.htb # HTB machine IP")
print("10.10.14.13 chat.response.htb # my VPN IP")
print("While runing this script, open http://chat.response.htb/ in the web browser
")
# Without multithreading:
#webServer = HTTPServer((hostName, serverPort), MyServer)
# With multithreading (choose one or the other):
webServer = ThreadedHTTPServer((hostName, serverPort), MyServer)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
if __name__ == "__main__":
main()


