在一次实战演练中应用reGeorg代理工具时,出現了许多 难题,带著这种疑惑我准备简易剖析一下reGeorg。
我这里先以vm虚拟机phpstudy自然环境为吊舱,用proxifier设置代理程序流程,pycharm设定reGeorgSocksProxy.py客户端来更强剖析reGeorg新项目。
这儿简略说一下tunnel.nosocket.php和tunnel.php的差别。查看源文件发觉tunnel.php多了这行编码。功效是载入socket这一控制模块,但dl自php 5.3起默认设置状况下处在禁止使用情况,因此 php 5.3版本号下列才能够应用tunnel.php。假如开启,则需配备php.ini。
程序流程通道
大家从程序流程的通道来一点点看。
应用argparse控制模块来接收、分析主要参数,一共有五个主要参数。
askGeorg方法
配备好相对的主要参数,脚本制作先根据askGeorg方法检验远程控制服务器代理是不是一切正常。
查看askGeorg方法是怎么判断的?
先看一下应用的是http還是https协议书,再connect连接到tunnel详细地址是不是为200。假如回应码为200,则提醒
Socket程序编写
再向下,socket程序编写用于接收当地分享的总流量。
bind默认设置关联到当地127.0.0.1,8888端口号上。servSock.accept() 等候TCP的连接(即Proxifier的总流量)。
将接收到的数据信息和远程控制服务器代理创建session连接。
session类
session类除开复位也有七个方法。从字面意思大约掌握到
它是这好多个方法先后实行的次序,大家一个个看。
复位
应用urlparse库分析tunnel详细地址获得每个字段名。分辨是HTTP還是HTTPS协议书。
urllib3.HTTPConnectionPool用于建立一个连接池。
run方法
复位进行后,运作run方法,最先分辨应用的哪些socks,即handleSocks方法。
根据接收一字节的数据信息。分辨是socks4還是socks5连接。
(能够根据wireshark爬取分辨是socks4還是socks5)
分辨为socks5,就启用parseSocks5方法。分辨socks4,就实行parseSocks4方法。
parseSocks5方法
这儿proxifier配备的是socks5。
大家就看parseSocks5方法,最先见到輸出,提醒大家检验到应用的是socks5代理。
随后方法又接收一个字节,随后依据atyp分辨target是IPV4還是hostname還是IPV6。
这儿手动式輸出atype值查询。即print(str(ord(atype)))
随后再接收4个字节数为IP地址,ord()涵数转换为ASCII码拼凑为规范的IP地址。即target。接收两个字节数,即targetPort。
targetPort也是根据ord()涵数回到十进制数,輸出规范端口号。
再往出来到connect连接,将target取值给serverIp,并应用gethostbyname回到IP地址IPV4详细地址。
将serverIp再次变为字节数,等候下一步用发送。在发送以前还必须先设定session。即setupRemoteSession方法。
跟踪setupRemoteSession方法。
能够见到是发送POST数据包,而且在headers头设定了 ,以CONNECT为标志,意味着和target开展连接。发送该数据包,假如回应吗为200,而且回应头x-status为ok,则获得回应头的set-cookie取值给cookie。
回到cookie开展connect,随后sock.sendall()发送数据信息。
以后return到handleSocks方法,再到run方法。
到此连接创建,刚开始session对话,来储存服务器端和客户端的socket对话情况。
下边便是重要的reader和write。
reader方法
建立PoolManager目标,发送HTTP数据包。和CONNECT标示相相近。此次应用READ为标志。在headers头加上
POST发送该数据包。假如回应吗为200且x-status为ok,则将回应的data数据信息以socks发送。
writer方法
writer方法完成数据包forward分享。和READ方法相近,但是在POST发送数据包时,立即发送了data数据包。标志为forward。
发送给tunnel.nosocks.php
最终关掉session。即closeRemoteSession方法。
closeRemoteSession方法
還是POST发送数据包,headers加上disconnect标志,
回应码为200,则Connection Terminated连接停止。
CONNECT
当接收到客户端的CONNECT连接要求,方法去连接总体目标详细地址和端口号,假如存有回到X-STATUS: OK,相反则回到X-STATUS: FAIL。
随后进到while循环系统,fwrite()涵数将写进,然后一直fgets()载入,将看到的結果取值给,随后輸出。
DISCONNECT
当接收到客户端的DISCONNECT连接要求时,只必须将致为false,关掉session就可以。
READ
当接收到客户端的READ连接要求时,分辨,輸出
FORWARD
当接收到客户端的FORWARD连接要求时,应用file_get_contents获得內容,并开展輸出。
随后将储存在,根据以前的while循环系统中fgets()获取数据,增加到,再用READ要求輸出出去。
以debug方式再次回望reGeorgSocksProxy.py客户端和tunnel.nosocket.php服务端代码执行的全过程。
为了更好地更便捷汇总该全过程,干了小小的调节。
设定好profile,代理ip软件浏览10.211.55.4的8080端口号。
reGeorgSocksProy.py最先浏览tunnel.nosocket.php是不是回应一切正常,随后分辨来源于协议书是socks5還是socks4。电脑浏览器浏览10.211.55.4的8080端口号,reGeorgSocksProy.py接收到的target便是10.211.55.4,port端口号便是8080。并设定session。
接着就是read方法和write方法即forward。
writer()方法带上要求10.211.55.4的8080端口号的数据包存有data中随后forward发送,data数据信息储放在静态变量,根据while循环系统先fwrite()、fgets()方法获得回到的結果,read()方法再从結果中复印给客户端。
最终回到closeRemoteSession()方法,关掉session。
wireshark爬取数据包更形象化的能够见到全部全过程。
connect连接到特定浏览的10.211.55.4和8080端口号。
forward 分享10.211.55.4:8080的GET数据包。
read载入回到的內容给客户端。
填补:socks5是怎么判断的?
由于socks5代理开启在当地的环回详细地址上,即127.0.0.1。且socks协议书工作中在TCP链路层。因此 wireshark应当抓当地lo网口
过虑标准为
只看发送到8888的这两个数据包就可以了。
第一个数据包,leng长短为4。数据信息內容为十六进制的
第一个字节数05即分辨应用socks5协议书,对 应handleSocks方法的
第二、三个字节0200对应方法的parseSocks5
第四个字节02对应parseSocks5方法的
再看第二个数据包,leng长度10,数据内容十六进制的
跟进源代码的parseSocks5方法,继续sock.recv()
接收4个字节长度。即。也对应
然后再接收4个字节为target,2个字节为targetPort。
再用ord()函数从target依次拼接返回十进制数。
我们可以在console控制台判断一下
大概分析之后,大家应该对整个流程有了一定了解。
下面结合实战对存在的两个问题进行解决。
1. proxifier 代理时为什么出现许多莫名其妙的IP?
其实打开firfox浏览器的一瞬间,firefox就会有多个域名发出请求。
而在reGeorgSocksProxy.py终端里就会解析出多个莫名其妙的IP。
2.什么时候才可以判断确实代理成功?
从代码层上看,访问远程代理服务器tunnel.nosocket.php返回就可以代理成功的。因为tunnel.nosocket.php只起到一个中转的作用,转发流量到内网。
而这次error的原因是目标地址的80端口没有开放,其实不能说明代理是不能使用的。
比如访问8180端口
最后选择在kali的proxychains和自己编写的端口扫描成功代理。
最后还测试某盾查杀了tunnel.nosocket.php,调式发现主要查杀两个位置。
一个fsockopen()函数,对该函数提前引用即可绕过。
一个php输入流,即,使用str_rot13()函数和一些混淆即可绕过。
也可以结合webshell免杀的思路,使用简单的编码思路将脚本base64编码之后再解码。
也可成功免杀。
大致分析了reGeorg的工作流程,明白是socks编程完成流量的转发,再将结果返回,结合实战成功建立了代理,最后两个姿势进行简单免杀处理。