两次实战过程中碰到的流量拦截,主要是记录一下测试思路和解决过程。
UDP出网限制绕过
出网情况探测?
测试发现TCP、ICMP不出网,但UDP可能出网。
UDP还是DNS出网?
进一步确定是DNS出网还是UDP出网:
UDP全端口还是指定端口?
确定是UDP出网。进一步看是否UDP全端口,还是仅53:
确定仅53端口。
防火墙拦截
直接上tinyvpn,提示kernel too old:
不想折腾它,换一个工具,用spp,可以跑起来,但总是连不上,偶尔连上了也极其不稳定。
是否UDP畅通无阻?
于是在想,是不是有些什么防火墙做了一些限制,是不是只允许DNS数据包。于是两边nc测试一下:
服务端毫无反应,说明是有一定拦截的。
DNS请求包是否正常?
截获一个DNS查询的包,然后通过nc发出去,发现,又能收到了:
看起来有点像是只能通过DNS请求包头。
单向拦截还是双向检测?
那问题来了,是双向检测还是单向检测呢?于是,服务端用python做了个DNS server。
正常回报OK:
异常回报,也能正常返回来:
那,有可能是回包没有做检测吧。(这里显示的先后顺序是打印不可见字符造成的)正在想是不是要改改SPP,给所有的包都加一个DNS查询的包头,绕过拦截。
有特定传输规则?
无意间又敲了几下,发现,出现的现象把我刚才的结论推翻了:
难道这个test
是Magic字符串,只接受它回车后的字符?不太科学,换一个字符试试:
嗯,难道,发包规则是:需要在第一行敲四个字符才行?
是否长度限制?
接着上面的测试,在想是必须要先敲一行还是单纯长度限制?再测一次:
看起来是,UDP包小于12字节的,会被丢弃。那回包会不会也有限制?改dns服务回报为’a’*11,发现无返回:
改成’a’*12,有返回了:
也就是说,这里的流量产品做了UDP的包长度过滤,小于12字节的包会被丢弃。
工具改造
于是,找到SPP的作者请教一番,小改一下SPP的FrameData结构体:
给它后面加上三个int32,让每个包大小都大于等于12字节。
重新编译,丢到机器上:
之后,bypass了防火墙拦截规则,基于UDP的反向Socks5代理OK了:
ICMP出网限制绕过
背景
某内网中,办公网、测试网、生产网严格隔离了,其中测试、生产网段均有部分据点。测试发现,办公网有个WEB可在测试网访问,刚好上面有个SSRF。
并且,通过该SSRF,探测到办公网存在NC,NC存在bsh命令执行,不过不出网,也无法TCP出来测试网。进一步探测,发现该NC机器A可ping通生产网B机器。嗯?能ping通,还都是root权限,是不是可以做个ICMP隧道,得到去往办公网段的通路?
卡点1: GLIBC_2.15 not found — 内核版本
通过SSRF+bsh,艰难的把elf拆包后,一段段的echo进去,之后再base64 -d组成一个完整的ELF,结果一运行,报错了:
于是换了个centos6.5来编译。
卡点2: unrecognized command line option “-flto” — gcc版本
编译报错:
搜了一波,是需要4.7以上的gcc,好的,升级一下,顺利编译通过。
卡点3: 非法指令(core dumped) — AVX2指令集
再次艰难上传后,运行:
strace
一下,也没啥发现:
最开始以为是内核版本不对,或者rhel做了什么更改。于是,尽量去找同内核版本机器编译,一顿折腾下来,还是不行。
想着,应该是cpu架构问题,就搜了下看了下cat /proc/cpuinfo
,看到Intel(R) Xeon(R) CPU E5-2630
,连带着指令异常去搜了下,看到这个解释:
编译机 和 运行机 的 CPU 型号不同, 支持的指令集不同。不兼容的指令集主要有: SSE4.2 和 AVX2。
如果 编译机支持 AVX2, 运行机不支持, 就会出现 Illegal instruction (core dumped) 的问题。
跑去编译机和执行机上看了下,还真是,编译机是支持AVX2的,而Xeon(R) CPU E5-2630
只有AVX
。服务端能跑,大概是因为刚好支持AVX2吧。
于是改Makefile,把编译选项中-march=native
干掉。于是,成功编译运行了。
在想着,这次应该OK了吧。
结果:
都是open了后,就一直在等待建立连接。
来来回回测了很久,都是这样,问题会出现在什么地方呢?
再去vps上试了试,连接成功会立马出现established:
卡点4: 防火墙拦截 — 流量特征
是否长度限制拦截?
百思不得其解,于是在想,是不是网段间做了什么操作,比如防火墙过滤了比较长的ICMP包,然后去ping -l 1024 xxx
,毫无问题。
是否MTU大小拦截?
在想,会不会和虚拟网卡mtu有关,把mtu改小一点,或许能过防火墙。结果在外网测试发现mtu改太低了后,就连不上了。还是先放弃这个测试思路。
同网段是否存在拦截情况?
在同网段找了俩台机器,分别做server和client,试了下,发现,毫无问题:
是不是有什么流量特征?
于是,开始在vps上、目标上开tcpdump,抓icmp包来看到底是什么情况。
能建立通道的:
内网不能建立隧道的:
发现只有出去的ICMP,没有回来的。顺带,看到了所有icmptunnel
的包里,都带有TUNL
字样,在想,会不会是被这个特征拦了呢?
于是,测一下发一个带TUNL
的ICMP包,linux/mac下可以执行:sudo ping -s 12 -p "54554e4c" 127.0.0.1
来给ICMP尾部填充上想要测试的字符。
这个时候,去包和回包中,都会带上-p(hex)
后的值:
如果被拦了,显然就不会有回包了,我遇到就是这种情况。
工具改造
知道了拦截规则,就去改改源码吧,把特征去掉再测一测。
看,代码里是有MAGIC的,于是改掉它,重新编译,把server端重新起起来,客户端一跑,激动人心的一刻来了:
就这样,接入了办公网段,突破了网络隔离。
课后思考:
那么,问题来了,怎么判断icmp不通的时候是因为:echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
,还是真的网段隔离呢?
原文始发于微信公众号(安全攻防团队):记两次Bypass流量拦截搭隧道