lgandx / Responder

Responder is a LLMNR, NBT-NS and MDNS poisoner, with built-in HTTP/SMB/MSSQL/FTP/LDAP rogue authentication server supporting NTLMv1/NTLMv2/LMv2, Extended Security NTLMSSP and Basic HTTP authentication.
GNU General Public License v3.0
5.49k stars 777 forks source link

Timeout in HTTP_Proxy.py throws an exception instead of correctly sending the client an error #252

Open TheraNinjaCat opened 1 year ago

TheraNinjaCat commented 1 year ago

When processing the socket errors in the HTTP proxy, when capturing the socket.error it attempts to index into the object, and if that fails (as it should always do for most error objects if my understanding is correct) then it will attempt to send the error object itself into self.send_error, however this method is expecting a single line string (i.e. "Not Found", "Bad Request", or "Internal Server Error") rather than an error object, so it attempts to use a string method (s.replace) which causes another error.

In this specific example it is also attempting to send a 404 response for a socket timeout, where potentially it should be sending a 504 Gateway Timeout (I'm not familiar with the code, but as this module is called HTTP_Proxy.py I'm assuming this error occurs when the upstream connection fails so this feels more accurate)

----------------------------------------
<ip> - - [05/Oct/2023 10:35:36] code 404, message [Errno 110] Connection timed out
<ip> - - [05/Oct/2023 10:35:36] "CONNECT mtalk.google.com:5228 HTTP/1.1" 404 -
----------------------------------------
Exception occurred during processing of request from ('<ip>', 60475, 0, 0)
Traceback (most recent call last):
  File "/usr/share/responder/servers/HTTP_Proxy.py", line 221, in _connect_to
    try: soc.connect(host_port)
         ^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: [Errno 110] Connection timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.11/socketserver.py", line 691, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python3.11/socketserver.py", line 361, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.11/socketserver.py", line 755, in __init__
    self.handle()
  File "/usr/share/responder/servers/HTTP_Proxy.py", line 213, in handle
    self.__base_handle()
  File "/usr/lib/python3.11/http/server.py", line 436, in handle
    self.handle_one_request()
  File "/usr/lib/python3.11/http/server.py", line 424, in handle_one_request
    method()
  File "/usr/share/responder/servers/HTTP_Proxy.py", line 248, in do_CONNECT
    if self._connect_to(self.path, soc):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/share/responder/servers/HTTP_Proxy.py", line 225, in _connect_to
    self.send_error(404, msg)
  File "/usr/lib/python3.11/http/server.py", line 482, in send_error
    'message': html.escape(message, quote=False),
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/html/__init__.py", line 19, in escape
    s = s.replace("&", "&amp;") # Must be done first!
        ^^^^^^^^^
AttributeError: 'TimeoutError' object has no attribute 'replace'
----------------------------------------

https://github.com/lgandx/Responder/blob/de20dcf408e8dee9f7dc1c129b6c3ded52d677b6/servers/HTTP_Proxy.py#L222-L226