Last active
April 16, 2022 12:43
-
-
Save vitouXY/a7d8126ffb6ba963ee190d11ec3b970a to your computer and use it in GitHub Desktop.
HTTP Injector ; QPython
This file contains 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 characters
#!/usr/bin/env python2 | |
#!/usr/bin/python2 | |
#-*-coding:utf8-*- | |
# coding=utf-8 | |
#qpy:console | |
""" | |
HTTP Injector Python | |
https://stackoverflow.com/questions/43341946/injector-python-http-proxy-basic-proxy-authentication | |
+++ Inject Payload | |
'[method] [host_port] HTTP/1.1[crlf]Host: www.cautive-portal.com[crlf]X-Online-Host: [host][crlf]X-Forwarded-For: www.cautive-portal.com[crlf]User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)[crlf][crlf]' | |
## Normal * | |
'[netData][crlf]Host: www.cautive-portal.com[crlf][crlf]' | |
'CONNECT [host_port] [protocol][crlf]Host: www.cautive-portal.com[crlf][crlf]' | |
## Front Inject | |
'GET http://www.cautive-portal.com/ HTTP/1.1[crlf]Host: www.cautive-portal.com[crlf][crlf]CONNECT [host_port] [protocol][crlf][crlf]' | |
## Back Inject * | |
'CONNECT [host_port] HTTP/1.1[crlf][crlf]GET http://www.cautive-portal.com/ [protocol][crlf]Host: www.cautive-portal.com[crlf][crlf]' | |
## Front Query | |
'CONNECT www.cautive-portal.com@[host_port][crlf]GET http://www.cautive-portal.com/ [protocol][crlf]Host: www.cautive-portal.com[crlf][crlf]' | |
## Back Query | |
'CONNECT [host_port]@www.cautive-portal.com[crlf]GET http://www.cautive-portal.com/ [protocol][crlf]Host: www.cautive-portal.com[crlf][crlf]' | |
+++ Headers | |
Host: www.cautive-portal.com | |
X-Online-Host: www.cautive-portal.com | |
X-Forward-Host: www.cautive-portal.com | |
X-Forwarded-For: www.cautive-portal.com | |
Connection: Keep-Alive or Close | |
Proxy-Connection: Keep-Alive or Close | |
Content-Type: */* | |
Content-Length: 0 or 1024 | |
Accept: */* | |
User-Agent: | |
Opera/9.80 (Android; Opera Mini/7.6.40234/113.82; U; es) Presto/2.12.423 Version/12.16 | |
Mozilla/5.0 | |
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) | |
+++ Inject Method | |
'HEAD', 'GET', 'POST', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PUT', 'PATCH' | |
302 FOUND! 400 Bad Request? --> 200 OK | |
""" | |
#Embedded file name: pyc | |
#__all__ = ["Socket"] | |
__author__ = 'Any' | |
__credits__ = ['Any','Usuario_CL'] | |
__contributor__ = 'Usuario_CL' | |
__maintainer__ = 'Usuario_CL' | |
__copyright__ = 'Copyleft (c) 2018 - All Rights Not Reserved' | |
__date__ = '16/11/2018' | |
__version__ = '0.00.1-(2)' | |
__prog_name__ = 'HTTP Injector' | |
import socket | |
import thread | |
import string | |
import select | |
import platform, sys, os | |
ru = lambda text: text.decode('utf-8', 'ignore') | |
ur = lambda text: text.encode('utf-8', 'ignore') | |
class bcolors: | |
HEADER = '\033[95m' | |
OKBLUE = '\033[94m' | |
OKGREEN = '\033[92m' | |
WARNING = '\033[93m' | |
FAIL = '\033[91m' | |
ENDC = '\033[0m' | |
BOLD = '\033[1m' | |
UNDERLINE = '\033[4m' | |
# format(__prog_name__) | |
name_ini = '%s.ini' % __prog_name__.replace(' ', '') | |
conf_ini = os.path.realpath(os.path.join(os.path.dirname(__file__), '%s' % name_ini)) | |
#conf_ini = os.path.join(sys.path[0], '%s' % name_ini) | |
class Sets: | |
def __init__(self): | |
self.LHOST = '127.0.0.1' | |
self.LPORT = 8081 | |
self.IMETHOD = 4 | |
self.PHOST = '127.0.0.1' | |
self.PPORT = 8080 | |
self.PAYLOAD = '' | |
self.load() | |
def load(self): | |
try: | |
for name, value in [ line.split(' = ') for line in open(conf_ini, 'rb').read().splitlines() ]: | |
self.__dict__[name] = eval(value) | |
except: | |
self.save() | |
for name, value in [ line.split(' = ') for line in open(conf_ini, 'rb').read().splitlines() ]: | |
self.__dict__[name] = eval(value) | |
def save(self): | |
data = '' | |
for name in self.__dict__.keys(): | |
line = name + ' = ' + repr(self.__dict__[name]) + '\r\n' | |
data += line | |
open(conf_ini, 'wb').write(ur(data)) | |
del data | |
# | |
__BIND_ADDR = Sets().LHOST | |
if not __BIND_ADDR : __BIND_ADDR = '127.0.0.1' | |
__BIND_PORT = Sets().LPORT | |
if __BIND_PORT < 1 or __BIND_PORT > 65535 : __BIND_PORT = 8888 | |
if not __BIND_PORT : __BIND_PORT = 8888 | |
try: | |
__METHOD = ['HEAD', 'GET', 'POST', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PUT', 'PATCH'][Sets().IMETHOD] | |
except IndexError: | |
__METHOD = 'CONNECT' | |
if not __METHOD : __METHOD = 'CONNECT' | |
__PROXY_ADDR = Sets().PHOST | |
if not __PROXY_ADDR : __PROXY_ADDR = '127.0.0.1' | |
__PROXY_PORT = Sets().PPORT | |
if __PROXY_PORT < 1 or __PROXY_PORT > 65535 : __PROXY_PORT = 3128 | |
if not __PROXY_PORT : __BIND_PORT = 3128 | |
__PAYLOAD = Sets().PAYLOAD | |
if getattr(socket, 'socket', None) is None: | |
raise ImportError('socket.socket missing, proxy support unusable') | |
""" | |
Injection | |
""" | |
TAM_BUFFER = 65535 | |
MAX_CLIENT_REQUEST_LENGTH = 8192 * 8 | |
## Monta uma payload # chr(0x0D) + chr(0x0A) | |
def getReplacedPayload(payload, netData, hostPort, protocol, method): | |
str = payload.replace('[netData]', netData) | |
str = str.replace('[host_port]', (hostPort[0] + ':' + hostPort[1])) | |
str = str.replace('[host]', hostPort[0]) | |
str = str.replace('[port]', hostPort[1]) | |
str = str.replace('[protocol]', protocol) | |
str = str.replace('[cr]','\r') | |
str = str.replace('[lf]','\n') | |
str = str.replace('[crlf]','\r\n') | |
str = str.replace('[lfcr]','\n\r') | |
# | |
print 'netdata['+netData+'] host['+hostPort[0]+'] port['+hostPort[1]+'] protocol['+protocol+']' | |
str = str.replace('[method]', method) | |
# | |
return str | |
## getReplacedPayload -- | |
## Separa o protocol HTTP de uma requisicao | |
def getRequestProtocol(request): | |
inicio = request.find(' ', request.find(':')) + 1 | |
str = request[inicio:] | |
fim = str.find('\r\n') | |
return str[:fim] | |
## getRequestProtocol -- | |
## Separa o host e porta de uma requisicao | |
def getRequestHostPort(request): | |
inicio = request.find(' ') + 1 | |
str = request[inicio:] | |
fim = str.find(' ') | |
str = str[:fim] | |
if str.startswith('http://'): | |
str = request[inicio+7:] | |
h_ini = str.find('/') | |
h_str = str[:h_ini] | |
if (h_str.find(':')<0): str = '%s:80' %h_str | |
else: str = '%s' %h_str | |
elif str.startswith('https://'): | |
str = request[inicio+8:] | |
h_ini = str.find('/') | |
h_str = str[:h_ini] | |
if (h_str.find(':')<0): str = '%s:443' %h_str | |
else: str = '%s' %h_str | |
if (str.find(':')<0): str = '%s:80' %str | |
#hostPort = str[:fim] | |
hostPort = str | |
return hostPort.split(':') | |
## getRequestHostPort -- | |
def getRequestMethod(request): | |
inicio = request.find(' ') | |
return request[:inicio] | |
## Separa a request line de uma requisicao | |
def getRequestNetData(request): | |
return request[:request.find('\r\n')] | |
## getRequestNetData -- | |
# netData1 = 'POST http://mini5-1.opera-mini.net:80/ HTTP/1.0' | |
# netData2 = 'POST mini5-1.opera-mini.net:80 HTTP/1.0' | |
## Le uma request/response HTTP | |
def receiveHttpMsg(socket): | |
len = 1 | |
data = socket.recv( 1) | |
while data.find('\r\n\r\n'.encode()) == - 1: | |
if not data: break | |
data = data + socket.recv(1) | |
len += 1 | |
if len > MAX_CLIENT_REQUEST_LENGTH: break | |
return data | |
## receiveHttpMsg -- | |
## Implementa o metodo CONNECT | |
def doConnect(clientSocket, serverSocket, tamBuffer): | |
sockets = [clientSocket, serverSocket] | |
timeout = 0 | |
print bcolors.BOLD + bcolors.OKBLUE + ' <-> CONNECT started' + bcolors.ENDC | |
while 1: | |
timeout += 1 | |
ins, _, exs = select.select(sockets, [], sockets, 3) | |
if exs: break | |
if ins: | |
for socket in ins: | |
try: | |
data = socket.recv(tamBuffer) | |
if not data: break; | |
if socket is serverSocket: | |
clientSocket.sendall(data) | |
else : | |
serverSocket.sendall(data) | |
timeout = 0 | |
except : | |
break | |
if timeout == 60: break | |
## doConnect -- | |
## Atente um cliente | |
def acceptThread(clientSocket, clientAddr): | |
print bcolors.BOLD + bcolors.OKGREEN + ' <-> Client connected: ' + bcolors.ENDC, clientAddr | |
## Le a requisicao cliente | |
request = receiveHttpMsg(clientSocket) | |
## Valida o metodo. Somente CONNECT e aceito | |
""" | |
if not request.startswith(__METHOD): | |
print bcolors.BOLD + bcolors.WARNING + ' <!> Client requested method != '+__METHOD+'!\r' + bcolors.ENDC | |
clientSocket.sendall('HTTP/1.1 405 Only_'+__METHOD+'_Method!\r\n\r\n') | |
clientSocket.close() | |
thread.exit() | |
#""" | |
## Separa dados da request enviada | |
netData = getRequestNetData(request) | |
protocol = getRequestProtocol(request) | |
hostPort = getRequestHostPort(netData) | |
method = getRequestMethod(request) | |
## Gera a requisicao final a partir da payload, com base nos dados da reques | |
finalRequest = getReplacedPayload(__PAYLOAD, netData, hostPort, protocol, method) | |
## Envia a requisicao ao servidor proxy | |
proxySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
proxySocket.connect((__PROXY_ADDR, __PROXY_PORT)) | |
except socket.error: | |
print(bcolors.FAIL + ' <!> Error - Proxy Address ' + bcolors.ENDC) | |
proxySocket.close() | |
clientSocket.close() | |
thread.exit() | |
except socket.timeout: | |
print(bcolors.FAIL + ' <!> TimeOut - Proxy Address ' + bcolors.ENDC) | |
proxySocket.close() | |
else: | |
proxySocket.sendall(finalRequest) | |
## Recebe a resposta do servidor proxy | |
proxyResponse = receiveHttpMsg(proxySocket) | |
print bcolors.BOLD + bcolors.OKGREEN + ' <-> Status line : ' + bcolors.ENDC + getRequestNetData(proxyResponse) | |
## Envia a resposta do proxy ao cliente | |
clientSocket.sendall(proxyResponse) | |
## Se a resposta do proxy contem codigo 200, executa metodo CONNECT | |
if proxyResponse.find('200') != -1: | |
doConnect(clientSocket, proxySocket, TAM_BUFFER) | |
## Fecha a conexao com o cliente | |
print bcolors.BOLD + bcolors.OKBLUE + ' <-> Client ended : ' + bcolors.ENDC, clientAddr | |
proxySocket.close() | |
clientSocket.close() | |
thread.exit() | |
## acceptThread -- | |
""" | |
Listening | |
""" | |
def doListen(): | |
print bcolors.BOLD + bcolors.HEADER + 'Serving HTTP on ' + __BIND_ADDR + ' port ' + str(__BIND_PORT) + ', use <Ctrl-C> to stop...\r\n' + bcolors.ENDC | |
## Configura a escuta numa porta local | |
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
try: | |
server.bind((__BIND_ADDR, __BIND_PORT)) | |
except socket.error: | |
server.close() | |
## Local/Listen/Bind Address already in use | |
print(bcolors.FAIL + ' <!> Error - Listening Address ' + bcolors.ENDC) | |
else: | |
server.listen(1) | |
## Recebe o cliente e despacha uma thread para atende-lo | |
while True: | |
try: | |
clientSocket, clientAddr = server.accept() | |
thread.start_new_thread(acceptThread, tuple([clientSocket, clientAddr])) | |
except (KeyboardInterrupt, SystemExit): | |
#thread.exit() | |
server.close() | |
sys.exit(0) | |
os.abort() | |
os._exit(0) | |
def showInfo(): | |
print __prog_name__ + ' v' + __version__ + ' for Python2/' + platform.system() + '\r\n' | |
#print ('==> '+__file__.split("/")[-1].split(".py")[0]) | |
print ' ' + bcolors.BOLD + bcolors.UNDERLINE + 'RPROXY:' + bcolors.ENDC + ' ' + __PROXY_ADDR + ':' + str(__PROXY_PORT) + ' ' + bcolors.BOLD + bcolors.UNDERLINE + 'METHOD:' + bcolors.ENDC + ' ' + __METHOD | |
print bcolors.BOLD + bcolors.UNDERLINE + 'PAYLOAD:' + bcolors.ENDC + ' ' + __PAYLOAD + '\n' | |
def __run(): | |
showInfo() | |
doListen() | |
if __name__ == '__main__': | |
__run() | |
# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Other example
netData1 = 'POST http://mini5-1.opera-mini.net:80/ HTTP/1.0'
netData2 = 'POST mini5-1.opera-mini.net:80 HTTP/1.0'