早上微信的一个技术群里不知怎么就提到了MAC的OUI,我记得我说IANA早就获得00-00-5e这个OUI了,这个OUI本来可用来做地址解析,但是IPv4简单地用ARP广播实现了地址解析,没有用到这个OUI拼接的组播进行…
一SDWAN领域的元老级别的,开公司当老板的哥们儿拿到了自己的OUI,可见这位老板哥已经做大了,可以自己出网卡了…
做个广告,对SDWAN感兴趣的自认为优秀的很帅的人可以去投奔这位老板哥,很帅很老板的哥。
是这样的,听我简单说。
在IPv4时代,如果你想对某个大厂的服务器组织一次DDoS,你可能需要进行一次反射发包,即构造一系列目标地址为任意地址的主机,源地址为被攻击服务器地址的包发出去,然后所有这些主机将会同时给被攻击机器发包,从而耗尽其处理器资源。
被攻击者很难定位攻击者是从哪里发起的,因为IPv4地址除了那个点分十进制的32位整型数字之外,什么信息都没有,而且几乎可以肯定,攻击源是攻击者任意构造的,由于IPv4地址的任意分配特征,你几乎不可能根据运营商地址分配信息找到他们总部,他们其实也是受害者,很难进一步溯源。
但是在IPv6的场景下,事情起了变化。
如果服务器审计到一个类似下面地址的源地址在持续发包扫描:
2422:222::e205:c5ff:fe7c:cee8
那么我就知道,这个数据包十有八九来自一个TP-Link的网卡,为什么呢?
请注意这个IP地址的hostID部分,中间的两个字节是0xff,0xfe,这正符合EUI-64的格式,而EUI-64则是由其MAC地址映射而来,而MAC地址则是和厂商绑定的,厂商则可以查到购买者的信息…
由于IPv6几乎不做NAT,从 2422:222::e205:c5ff:fe7c:cee8
这个源地址,我们知道该数据包的始发站一定来自于一块TP-Link的网卡,这个从其EUI-64结构头3个字节e205:c5就可以看出,详细的OUI信息来自于:
http://standards-oui.ieee.org/oui/oui.txt
<http://standards-oui.ieee.org/oui/oui.txt>
如果你持续看到 …e205:c5ff:fe… 源地址,那就就可以肯定这是TP-Link在发动各攻击。从TP-Link公司找它们的大客户就好了…
这解释了IPv6地址是如何暴露隐私的,同时也说明了IPv6隐私扩展临时地址的必要性!
那么作为一个攻击者,如果知道这个,如何可以利用?
这个机制既能嫁祸于人,也能自废武功!可谓甩锅神技,又容易走火入魔。
比如攻击者在构造源地址的时候,其hostID的头3字节统一都构造成某一个小厂的OUI的生成(不要是Intel之类的大厂,BAT加一起都得罪不起),比如一个小厂名叫X2,刚刚申请到一个OUI,假设它是
e0-12-34 ,此时你在构造源IP地址的时候,hostID的前5个字节写成 e2-12-34-ff-fe
就可以了。攻击者的目的是想让被攻击者定位到X2,而不是自己。
然而,被攻击者肯定会注意到这个序列,然后就会注意到这个序列,然后它会了解到攻击包来自X2的网卡,就算你的IP前缀分散的再散,只需要获取X2的订单信息源就能定位到间接攻击者的地理位置(购买网卡的人总要来自某个地方吧…),进而获取运营商的管理信息,记住,IPv6的地址前缀分配是和位置相关的。从这些位置的采购X2公司网卡的客户那里,就可能获取都间接攻击者的访问日志,进而定位到直接攻击者。
绕了一圈,自己打了自己一拳。本来是想嫁祸于人,结果暴露了自己…所以说,想用这种方式,千万不要反射数据包,一定要直接发往服务器,这样便不会让你的反射包在OUI匹配的地方留下足迹。
这就是IPv6,雁过留声,千万别做坏事。
下面给出一个程序,发送暴露OUI的攻击报文:
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h>
#include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include
<netinet/in.h> #include <linux/in6.h> #define __u8 unsigned char #define __be16
unsigned short #define __u32 unsigned int struct ipv6hdr { __u8 priority:4,
version:4; __u8 flow_lbl[3]; __be16 payload_len; __u8 nexthdr; __u8 hop_limit;
struct in6_addr saddr; struct in6_addr daddr; }; int main(int argc, char **argv)
{ int sd; unsigned char oui[3]; unsigned char *eui64; char packet[128] = {0};
static struct sockaddr_in6 source, remote; struct ipv6hdr *hdr; int num; // 目标地址
if (inet_pton(AF_INET6, argv[1], &remote) <= 0) { fprintf(stderr, "Cannot
convert destination: %s\n", strerror(errno)); abort(); } // 源地址 if (inet_pton(
AF_INET6, argv[2], &source) <= 0) { fprintf(stderr, "Cannot convert source:
%s\n", strerror(errno)); abort(); } // 3个字节的OUI sscanf(argv[3], "%x", &oui[0]);
sscanf(argv[4], "%x", &oui[1]); sscanf(argv[5], "%x", &oui[2]); remote.
sin6_family= PF_INET6; remote.sin6_port = htons (0); sd = socket(PF_INET6,
SOCK_RAW, IPPROTO_RAW); if (sd < 0) { fprintf(stderr, "Cannot create socket:
%s\n", strerror(errno)); abort(); } packet[0] = 0x60; hdr = (struct ipv6hdr *)&
packet[0]; memset(hdr->flow_lbl, 0, sizeof(hdr->flow_lbl)); hdr->payload_len =
htons(sizeof(packet) - sizeof(struct ipv6hdr)); hdr->nexthdr = IPPROTO_UDP; hdr
->hop_limit = 64; eui64 = (unsigned char*)((unsigned char*)&source + 8); //
EUI-64规则 eui64[0] = oui[0]; eui64[1] = oui[1]; eui64[2] = oui[2]; eui64[3] =
0xff; eui64[4] = 0xfe; eui64[0] ^= 0x02; srand((unsigned)time(NULL)); //
低24位随机生成,以模拟不同的主机。 eui64[5] = rand()%0xff; eui64[6] = rand()%0xff; eui64[7] =
rand()%0xff; memcpy(&hdr->saddr, &source, 16); memcpy(&hdr->daddr, &remote, 16);
memcpy(&remote.sin6_addr.s6_addr, &hdr->daddr, sizeof(remote.sin6_addr.s6_addr))
; num = sendto(sd, packet, sizeof(packet), 0, (struct sockaddr *)&remote, sizeof
(remote)); if (num < 0) { fprintf(stderr, "Cannot send message: %s\n", strerror(
errno)); abort(); } return (0); }
我用下面的命令行进行测试:
[root@localhost ~]# ./a.out 240e:123:222::444 2422:222::44 0xe0 0x12 0x34 226
18 52
得到的抓包如下:
被攻击的大厂管理员如果看到持续的源地址中都存在小红框里的数字,会怎么想?查OUI吧。哈哈!
浙江温州皮鞋湿,下雨进水不会胖。
热门工具 换一换