在有些情景下,需要拦截所有的http包和https数据包,http包很好抓,但是https包相对比较复杂,在此文章中,主要介绍http和https混合代理。
首先简单介绍下https,https=http+ssl,整体认证过程很复杂,其主要目的是为了防止中间人对数据进行监听或者篡改,其代理大致流程(不完整)为:
由于整个过程涉及非常多的加密解密知识,实现起来非常麻烦,所以我们选择了python(最新版)内置的ssl模块来帮助我们实现这个代理。
官方方给ssl模块的解释是:TLS/SSL wrapper for socket objects,即socket对象的tls/ssl的封装。
服务端使用可以参考其官方文档:
https://docs.python.org/2/library/ssl.html#server-side-operation。
首先,因为这个代理是http与https的混合代理,所以肯定不能直接使用内置模块监听在代理端口,这样一来就要求所有流量走https代理了,所以要先用socket模块,在代理端口监听,一旦有客户端连接,就新开一个线程处理连接。
client_conn函数:接收对方传来的第一个数据包,第二个参数https为该链接是否是https的标记。
这么做的原因是:混合代理判断数据包是http还是https的唯一方法,就是浏览器器如果发送https包,在传输前会先向代理发送一个CONNECT请求,通过第一个数据包,可以判断接下来的数据是https还是http包。
get_res函数:判断data数据包是不是CONNECT请求,如果是则走https通道,如果不是,则将数据包解析成请求,将其头和post data等解析出来。在此处,为了方便,代理脚本对外请求使用的是requests库而非socket,这样无论https还是http都可以很方便地获得结果。
get_str函数:对get_res中requests对外请求的结果进行包装,将其还原为http返回包。
https通道:将connstream通过ssl模块封装后转成正常socket,重新回到client_conn函数,视为正常http处理通信数据包。
res_deal:对返回包进行处理。
content_deal:对请求包进行处理,但不会影响requests的请求参数。
key.pem和key.crt都是本地生生成的,可以通过如下命令生生成:
openssl req -new -x509 -days 365 -nodes -out key.crt -keyout key.pem
在实际使用的过程中,很多人觉得这个代理相对其他代理比较慢,主要原因是后期使用requests库进行请求,会比socket直接请求浪费时间,而且期间各种数据包处理理也需要消耗时间。
另外还有人觉得这种https代理很麻烦,因为浏览器会飘红,每次都要询问你是否信任该证书,但是,这个是必须会有的,没有办法绕过。因为你的目的是在中间拦截https的数据包,而https产生的目的就是要防止被中间人拦截。
本文作者:点融安全应急响应中心(简称DSRC),点融非常重视其产品的安全性。DSRC愿与众多安全爱好者共同守卫点融安全,为投资者的资金安全、个人信息安全保驾护航。
返回搜狐,查看更多
责任编辑: