简单的实现一个HTTP代理

  1. 0x00前言
  2. 0x01如何实现
  3. 0x02实现
  4. 0x03缺陷
  5. 0x04参考链接

0x00前言

之前一直尝试先个http代理,每次都是败北而归。这次稍微好一点….补上坑吧
timg?image&quality=80&size=b9999_10000&sec=1575308314356&di=7e29c0b116060d76c0a7daa25a63ed15&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201711%2F25%2F20171125231052_rRBuv.thumb.1000_0.jpeg

0x01如何实现

HTTP代理

request
浏览器->py(代理)->目标
response
目标->py(代理)->浏览器

获取Host头里指向的域名和端口,如果没有指定端口默认为80,处理Proxy-Connection头部。将Proxy-Connection修改为Connection: close

使用异步来处理请求,否则可能会出现响应跟不上的问题

0x02实现

#@author:九世
#@time:2019/12/2
#@file:test.py

from gevent.monkey import patch_all;patch_all()
from gevent.server import StreamServer
import socket
import re

class Http(object):
    def __init__(self,text):
        self.yuan=text
        self.text=bytes.decode(text).replace('\r','')
        self.headers={}
        self.TUNNEL_OK = b'HTTP/1.1 200 Connection Established\r\nConnection: close\r\n\r\n'

    def proxyconnection(self,text):
        self.yuan=re.sub(b"Proxy-Connection",b"Connection",self.yuan)
        self.yuan=re.sub(b"keep-alive",b"close",self.yuan)
        domain=re.findall("\s.* HTTP",text)[0]
        dtm=str(domain).rstrip().lstrip().replace(self.headers['Host'],'').replace('http://',' ').replace('https://',' ')
        searchs=str(domain)
        self.yuan=re.sub(bytes(searchs,encoding='utf-8'),bytes(dtm,encoding='utf-8'),self.yuan)

    def jiexi(self):
        try:
            data=re.findall('Host[:].*',self.text)
            if len(data)>0:
                dt=str(data[0]).replace('Host:','').split(':')
                if len(dt)==2:
                    self.headers['Host']=str('{}'.format(dt[0]).strip().rstrip())
                    self.headers['port']=dt[1]
                else:
                    self.headers['Host']=str('{}'.format(dt[0])).rstrip().lstrip()
                    self.headers['port']=80

            if 'Proxy-Connection' in self.text and not "CONNECT" in self.text:
                self.proxyconnection(self.text)

            if 'Host' in self.headers:
                return self.headers['Host'],self.headers['port'],self.yuan


        except:
            pass

    def send_banners(self,host,port,data):
        jg=b''
        c=socket.socket()
        c.connect((host,int(port)))
        c.sendall(data)
        while True:
            rc=c.recv(4096)
            if rc:
                jg+=rc
            else:
                break

        return jg

def main(s,address):
    try:
        while True:
            request = s.recv(4096)
            print(request)
            obj = Http(request)
            jg = obj.jiexi()
            if b'CONNECT' in request:
                s.sendall(obj.TUNNEL_OK)
                while True:
                    rv=s.recv(1024)
                    if rv:
                        fb=obj.send_banners(jg[0],jg[1],rv)
                        print(fb)
                        s.sendall(fb)
                    else:
                        break
            else:
                fb = obj.send_banners(jg[0], jg[1], jg[2])
                s.sendall(fb)
    except Exception as r:
        if 'not subscriptable' in str(r):
            pass

if __name__ == '__main__':
    print('[+] 开始监听')
    try:
        server=StreamServer(("127.0.0.1",4444),main)
        server.serve_forever()
    except:
        pass
    '''
    s=socket.socket()
    s.bind(('127.0.0.1',4444))
    s.listen(1)

    while True:
        accept,adr=s.accept()
        request=accept.recv(4096)
        print(request)
        obj=Http(request)
        jg=obj.jiexi()
        fb=obj.send_banners(jg[0],jg[1],jg[2])
        accept.sendall(fb)
    '''

QuXvge.png

小结:
1.解析HTTP请求获取Host头里请求的内容和端口
2.使用异步来处理,否则会出现响应更不上的问题
3.修改Proxy-Connection头为Connection:close
4.处理HTTPS

0x03缺陷

  • 无法转发HTTPS
  • 某些隐性BUG

0x04参考链接

python http代理支持 https - 宁次 - 博客园
什么是HTTP隧道,怎么理解HTTP隧道呢? - 知乎
Python HTTPS代理隧道 - 代码日志
python – gevent StreamServer.start()似乎没有做我期望的 - 代码日志


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:简单的实现一个HTTP代理

本文作者:九世

发布时间:2019-12-02, 22:43:58

最后更新:2019-12-02, 23:11:36

原始链接:http://jiushill.github.io/posts/2aaeb1.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录