PPriv.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Edit By GlEmYsSoN & @e8th4ever
  4. from pprint import pprint
  5. import sys, http.client, socket, select, gzip, zlib, re, traceback, subprocess, argparse
  6. from socketserver import ThreadingMixIn
  7. from http.server import HTTPServer, BaseHTTPRequestHandler
  8. from threading import Lock, Timer
  9. from io import StringIO
  10. from urllib.parse import urlsplit
  11. subprocess.call("clear",shell=True)
  12. parser = argparse.ArgumentParser()
  13. parser.add_argument("-p", "--port", help="Nombre de archivo a procesar")
  14. parser.add_argument("-t", "--texto", help="Nombre de archivo a procesar")
  15. parser.add_argument("-i", "--ip", help="Nombre de archivo a procesar")
  16. args = parser.parse_args()
  17. if args.port:
  18. port = int(args.port)
  19. else:
  20. print(" Deve ingresar el puerto que usara como socks...")
  21. sys.exit()
  22. if args.texto:
  23. msg1 = args.texto
  24. else:
  25. msg1 = '<strong><font color="#00FFFF">A</font><font color="#6bffff">D</font><font color="#99ffff">M</font><font color="#ebffff">@</font><font color="#ebffff">R</font><font color="#ccffff">u</font><font color="#99ffff">f</font><font color="#6bffff">u</font><font color="#2effff">9</font><font color="#00FFFF">9</font></strong>'
  26. if args.ip:
  27. server = args.ip
  28. else:
  29. server = "127.0.0.1"
  30. msg2 = 'Server Forbidden'
  31. class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
  32. address_family = socket.AF_INET
  33. def handle_error(self, request, client_address):
  34. print('-'*40, file=sys.stderr)
  35. print('Exception happened during processing of request from', client_address, file=sys.stderr)
  36. traceback.print_exc()
  37. print('-'*40, file=sys.stderr)
  38. class ThreadingHTTPServer6(ThreadingHTTPServer):
  39. address_family = socket.AF_INET6
  40. class SimpleHTTPProxyHandler(BaseHTTPRequestHandler):
  41. global_lock = Lock()
  42. conn_table = {}
  43. timeout = 300
  44. upstream_timeout = 300
  45. proxy_via = None
  46. def log_error(self, format, *args):
  47. if format == "Request timed out: %r":
  48. return
  49. self.log_message(format, *args)
  50. def do_CONNECT(self):
  51. req = self
  52. reqbody = None
  53. if ':22' in req.path:
  54. hostip = req.path.replace(':22', '')
  55. elif ':443' in req.path:
  56. hostip = req.path.replace(':443', '')
  57. req.path = "https://%s/" % req.path.replace(':443', '')
  58. replaced_reqbody = self.request_handler(req, reqbody)
  59. if replaced_reqbody is True:
  60. return
  61. u = urlsplit(req.path)
  62. address = (u.hostname, u.port or 443)
  63. try:
  64. conn = socket.create_connection(address)
  65. except socket.error:
  66. return
  67. self.send_response(200, msg1)
  68. self.send_header('Connection', 'close')
  69. self.end_headers()
  70. conns = [self.connection, conn]
  71. keep_connection = True
  72. while keep_connection:
  73. if not server.find(hostip) != -1:
  74. self.send_error(403, msg2)
  75. self.close_connection
  76. keep_connection = False
  77. rlist, wlist, xlist = select.select(conns, [], conns, self.timeout)
  78. if xlist:
  79. break
  80. for r in rlist:
  81. other = conns[1] if r is conns[0] else conns[0]
  82. data = r.recv(8192)
  83. if data:
  84. other.sendall(data)
  85. keep_connection = True
  86. conn.close()
  87. def do_HEAD(self):
  88. self.do_SPAM()
  89. def do_GET(self):
  90. self.do_SPAM()
  91. def do_POST(self):
  92. self.do_SPAM()
  93. def do_SPAM(self):
  94. req = self
  95. content_length = int(req.headers.get('Content-Length', 0))
  96. if content_length > 0:
  97. reqbody = self.rfile.read(content_length)
  98. else:
  99. reqbody = None
  100. replaced_reqbody = self.request_handler(req, reqbody)
  101. if replaced_reqbody is True:
  102. return
  103. elif replaced_reqbody is not None:
  104. reqbody = replaced_reqbody
  105. if 'Content-Length' in req.headers:
  106. req.headers['Content-Length'] = str(len(reqbody))
  107. self.remove_hop_by_hop_headers(req.headers)
  108. if self.upstream_timeout:
  109. req.headers['Connection'] = 'Keep-Alive'
  110. else:
  111. req.headers['Connection'] = 'close'
  112. if self.proxy_via:
  113. self.modify_via_header(req.headers)
  114. try:
  115. res, resdata = self.request_to_upstream_server(req, reqbody)
  116. except socket.error:
  117. return
  118. content_encoding = res.headers.get('Content-Encoding', 'identity')
  119. resbody = self.decode_content_body(resdata, content_encoding)
  120. replaced_resbody = self.response_handler(req, reqbody, res, resbody)
  121. if replaced_resbody is True:
  122. return
  123. elif replaced_resbody is not None:
  124. resdata = self.encode_content_body(replaced_resbody, content_encoding)
  125. if 'Content-Length' in res.headers:
  126. res.headers['Content-Length'] = str(len(resdata))
  127. resbody = replaced_resbody
  128. self.remove_hop_by_hop_headers(res.headers)
  129. if self.timeout:
  130. res.headers['Connection'] = 'Keep-Alive'
  131. else:
  132. res.headers['Connection'] = 'close'
  133. if self.proxy_via:
  134. self.modify_via_header(res.headers)
  135. self.send_response(res.status, res.reason)
  136. for k, v in list(res.headers.items()):
  137. if k == 'set-cookie':
  138. for value in self.split_set_cookie_header(v):
  139. self.send_header(k, value)
  140. else:
  141. self.send_header(k, v)
  142. self.end_headers()
  143. if self.command != 'HEAD':
  144. self.wfile.write(resdata)
  145. with self.global_lock:
  146. self.save_handler(req, reqbody, res, resbody)
  147. def request_to_upstream_server(self, req, reqbody):
  148. u = urlsplit(req.path)
  149. origin = (u.scheme, u.netloc)
  150. req.headers['Host'] = u.netloc
  151. selector = "%s?%s" % (u.path, u.query) if u.query else u.path
  152. while True:
  153. with self.lock_origin(origin):
  154. conn = self.open_origin(origin)
  155. try:
  156. conn.request(req.command, selector, reqbody, headers=dict(req.headers))
  157. except socket.error:
  158. self.close_origin(origin)
  159. raise
  160. try:
  161. res = conn.getresponse(buffering=True)
  162. except http.client.BadStatusLine as e:
  163. if e.line == "''":
  164. self.close_origin(origin)
  165. continue
  166. else:
  167. raise
  168. resdata = res.read()
  169. res.headers = res.msg
  170. if not self.upstream_timeout or 'close' in res.headers.get('Connection', ''):
  171. self.close_origin(origin)
  172. else:
  173. self.reset_timer(origin)
  174. return res, resdata
  175. def lock_origin(self, origin):
  176. d = self.conn_table.setdefault(origin, {})
  177. if not 'lock' in d:
  178. d['lock'] = Lock()
  179. return d['lock']
  180. def open_origin(self, origin):
  181. conn = self.conn_table[origin].get('connection')
  182. if not conn:
  183. scheme, netloc = origin
  184. if scheme == 'https':
  185. conn = http.client.HTTPSConnection(netloc)
  186. else:
  187. conn = http.client.HTTPConnection(netloc)
  188. self.reset_timer(origin)
  189. self.conn_table[origin]['connection'] = conn
  190. return conn
  191. def reset_timer(self, origin):
  192. timer = self.conn_table[origin].get('timer')
  193. if timer:
  194. timer.cancel()
  195. if self.upstream_timeout:
  196. timer = Timer(self.upstream_timeout, self.close_origin, args=[origin])
  197. timer.daemon = True
  198. timer.start()
  199. else:
  200. timer = None
  201. self.conn_table[origin]['timer'] = timer
  202. def close_origin(self, origin):
  203. timer = self.conn_table[origin]['timer']
  204. if timer:
  205. timer.cancel()
  206. conn = self.conn_table[origin]['connection']
  207. conn.close()
  208. del self.conn_table[origin]['connection']
  209. def remove_hop_by_hop_headers(self, headers):
  210. hop_by_hop_headers = ['Connection', 'Keep-Alive', 'Proxy-Authenticate', 'Proxy-Authorization', 'TE', 'Trailers', 'Trailer', 'Transfer-Encoding', 'Upgrade']
  211. connection = headers.get('Connection')
  212. if connection:
  213. keys = re.split(r',\s*', connection)
  214. hop_by_hop_headers.extend(keys)
  215. for k in hop_by_hop_headers:
  216. if k in headers:
  217. del headers[k]
  218. def modify_via_header(self, headers):
  219. via_string = "%s %s" % (self.protocol_version, self.proxy_via)
  220. via_string = re.sub(r'^HTTP/', '', via_string)
  221. original = headers.get('Via')
  222. if original:
  223. headers['Via'] = original + ', ' + via_string
  224. else:
  225. headers['Via'] = via_string
  226. def decode_content_body(self, data, content_encoding):
  227. if content_encoding in ('gzip', 'x-gzip'):
  228. io = StringIO(data)
  229. with gzip.GzipFile(fileobj=io) as f:
  230. body = f.read()
  231. elif content_encoding == 'deflate':
  232. body = zlib.decompress(data)
  233. elif content_encoding == 'identity':
  234. body = data
  235. else:
  236. raise Exception("Unknown Content-Encoding: %s" % content_encoding)
  237. return body
  238. def encode_content_body(self, body, content_encoding):
  239. if content_encoding in ('gzip', 'x-gzip'):
  240. io = StringIO()
  241. with gzip.GzipFile(fileobj=io, mode='wb') as f:
  242. f.write(body)
  243. data = io.getvalue()
  244. elif content_encoding == 'deflate':
  245. data = zlib.compress(body)
  246. elif content_encoding == 'identity':
  247. data = body
  248. else:
  249. raise Exception("Unknown Content-Encoding: %s" % content_encoding)
  250. return data
  251. def split_set_cookie_header(self, value):
  252. re_cookies = r'([^=]+=[^,;]+(?:;\s*Expires=[^,]+,[^,;]+|;[^,;]+)*)(?:,\s*)?'
  253. return re.findall(re_cookies, value, flags=re.IGNORECASE)
  254. def request_handler(self, req, reqbody):
  255. pass
  256. def response_handler(self, req, reqbody, res, resbody):
  257. pass
  258. def save_handler(self, req, reqbody, res, resbody):
  259. pass
  260. def test(HandlerClass=SimpleHTTPProxyHandler, ServerClass=ThreadingHTTPServer, protocol="HTTP/1.1"):
  261. server_address = ('', port)
  262. HandlerClass.protocol_version = protocol
  263. httpd = ServerClass(server_address, HandlerClass)
  264. sa = httpd.socket.getsockname()
  265. print("Servidor: " + str(sa[0]) + " Porta " + str(sa[1]))
  266. httpd.serve_forever()
  267. if __name__ == '__main__':
  268. test()