(图文无关)

0×00 前言

前一阵子收录了一个名为Potato的提权工具,发现该工具提权的姿势与以往工具不太一样,而且与WPAD代理有关,于是展开测试和分析,主要通过分析其网络数据流量来研究该提权工具的独特姿势。分析中学到了不少东西,希望能把一些思考过的东西跟大家分享下。还请各位大牛批评指正!

整个工程代码和程序在GitHub上。https://github.com/foxglovesec/Potato

貌似是foxglovesec和breenmachine两位大牛在Github上建立的代码库,需要VS2012及以上版本打开!

0×01 初步测试

首先是测试该程序的使用范围和实际效果:

Potato的说明里写到可以在Windows 7,8,10, Server 2008, Server 2012上完成权限提升。看着挺唬人,试试看,以下只列出测试过的系统。

- Windows 7 x86和x64 系统上能够稳定立即提权(后面在分析其机制中会解释立即这词)

- Server 2008 R2 x64   系统上可以提权,但需要时间等待(约30分钟左右,跟Windows Updata时间有关)

- Server 2012 x64     系统上可以提权,但需要时间等待(更长,跟Windows更新证书列表时间有关)

- Windows 8和10等有机会测试下。

一个重要前提,Potato程序是用C#编写的,需要系统装有.Net Framework 3.5以上版本支持。

0×02 原理分析

以Potato在windows 7系统上的提权为例,详细分析开始:

Potato-master\source\Potato\Potato\bin\Release是Potato项目build后的程序所在目录。

打开cmd以普通用户的身份执行下面命令:

Potato.exe -ip 10.0.0.X -cmd "net user test /add" -disable_exhaust true

PS:测试系统Windows 7 SP1 x64 IP:10.0.0.X

在Potato使用的整个过程中打开抓包工具,由于Wireshark无法抓取127.0.0.1 Loopback上的数据包,这次选择使用RawCap.exe来抓取,该工具需要管理员权限,很好用,文件可以直接保存为pcap。同时对10.0.0.X和127.0.0.1进行抓包。在虚拟机中用RawCap.exe对127.0.0.1 Loopback抓包无效,是在实体机器上测试并抓取网络数据的。

Step 1:让自己认为WPAD是它自己127.0.0.1

补充:WPAD(Web Proxy Auto-Discovery Protocol)  Web 代理自动发现协议

当系统开启了代理自动发现功能后,用户使用浏览器上网时,浏览器就会在当前局域网中自动查找代理服务器,如果找到了代理服务器,则会从代理服务器中下载一个名为PAC(Proxy Auto-Config)的配置文件。该文件中定义了用户在访问一个 URL 时所应该使用的代理服务器。浏览器会下载并解析该文件,并将相应的代理服务器设置到用户的浏览器中。

Windows系统下,在解析这个WPAD名称时,会先从本机hosts文件开始,然后是问DNS,如果前面都没搞清楚WPAD是谁,则会利用NBNS协议进行广播。Potato在实现其第一阶段时主要利用NBNS协议,但当本机利用NBNS协议询问WPAD是谁时,Potato还是个普通权限,不可能利用嗅探技术把握发送WPAD应答包的时机。而NBNS协议是基于UDP之上,又是无连接协议,Potato在这里使用了称为Local NBNS Spoofer的技术。

当主机利用NBNS询问一个主机名时,它会发出下图中的Name query包。被询问者如果存活的话,会返回Name query response包。此时出现一个问题,如何知道询问与应答是对应关系的呢?实际上NBNS协议中的Transaction ID字段就是来解决这个的。

一问一答的Transaction ID必定相同。Potato在这里向本机的137端口不断发送Name query respose响应包,而Transaction ID字段范围是0-65535,尝试65536种可能,当本机在某时发送询问WPAD的Name query包时,总有一个Transation ID可以与之对应上。

下图是实际截获Potato发送的众多NBNS中的三个数据包,注意看TransationID。

最后来张匹配上的图。

Potato实现了让自己认为自己127.0.0.1是WPAD的目的。这时候ping WPAD 会发现是127.0.0.1

上面是基于询问者用NBNS协议询问WPAD是谁,主机在使用NBNS之前会先问DNS,假如DNS中有WPAD,询问者将不会再用NBNS,第一阶段目的不就泡汤了?

而参数中的-disable_exhaust就是来解决这个问题的,称为UDP端口耗尽技术,目的使DNS失效。下图是来说明DNS走的是UDP协议。

Potato将绑定每一个可以绑定的UDP端口,导致没有可用于UDP请求的源端口,DNS失败后询问者将不得不使用NBNS协议。Potato再次达成第一阶段目标。

PS:理论上而言,只要有一个足够快的连接,应该就可以对任何能用UDP端口137进行通信的Windows主机进行NBNS欺骗。

Step 2:在本机上展开假WPAD代理服务

第一阶段完成对本机的欺骗,使其认为自己127.0.0.1是WPAD,那么本机就会从WPAD上获取PAC文件。