网络拓扑
DHCP服务器 ======== 你的笔记本电脑 ======== 你的手机
你的笔记本安装2.6内核版本的Linux发行版。
以上网络架设好,笔记本的网口从DHCP服务器要到IP,可以进行上网。
笔记本的无线网卡设定为AP模式,可以让你的手机连上,你的手机也要能上网。
你的手机要能从DHCP服务器直接获取IP,并且,你的手机发出的 DHCP的 discover封包经过你的笔记本的时候,你的笔记本要在封包中塞入option60这个字段(值任意)。
实验环境:Linux 2.6.31 openwrt系统代替题中的笔记本 手机
主要实现思想:在内核/net/core/dev.c源文件的netif_receive_skb函数中篡改数据包实现向DHCP包中插入option 60字段为字符串‘dhcp-athx‘。因为每个skb的skb->dev->name指示的是收到此数据帧的网卡,所以可以根据此变量的值进行区分不同sta,从而实现不同的sta篡改不同的option 60字段。
if (skb){ char *buf = (char *)(skb->mac_header); struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); struct udphdr *udph = (struct udphdr *)(buf + ETH_HLEN + 20); if(((unsigned char *)buf)[6] == 0x64//我的手机的MAC地址第一个字节 && ((unsigned char *)buf)[12] == 0x08 && ((unsigned char *)buf)[13] == 0x00 //以上为IP包关键字 && ((unsigned char *)buf)[23] == 0x11 //UDP关键字 && ((unsigned char *)buf)[35] == 0x44 //客户端源端口 && ((unsigned char *)buf)[37] == 0x43 //服务器目的端口 && ((unsigned char *)buf)[42] == 0x01 //DHCP客户端 && ((unsigned char *)buf)[284] == 0x01 //DHCP discover包 && ((unsigned char *)buf)[285] != 0x3c){ //防止修改网桥转给本机的那一份 int i; printk("[%s:%d]Before Packet length = %#4x udplen = %d iplen = %d devname = %s\n", __FUNCTION__, __LINE__, skb->len, udph->len, iph->tot_len, skb->dev->name); printk("head = 0x%p end = 0x%p data = 0x%p tail = 0x%p\n", skb->head, skb->end, skb->data, skb->tail); for (i = 0; i < skb->len; i++){ if (i % 2 == 0) printk(" "); printk("%2.2x", ((unsigned char *)buf)[i]); if (i % 16 == 15) printk("\n"); } printk("\n\n\n\n"); unsigned char dataadd[50] = {0x3c, 0x05, ‘H‘, ‘a‘, ‘r‘, ‘r‘, ‘y‘};//0x3c 0x05 ‘H‘ ‘a‘ ‘r‘ ‘r‘ ‘y‘ if(strcmp(skb->dev->name, "ath0") == 0){ memcpy(dataadd + 2, "dhcp-ath0", strlen("dhcp-ath0")); dataadd[2 + strlen("dhcp-ath0") + 1] = ‘\0‘; }else if(strcmp(skb->dev->name, "ath1") == 0){ memcpy(dataadd + 2, "dhcp-ath1", strlen("dhcp-ath1")); dataadd[2 + strlen("dhcp-ath1") + 1] = ‘\0‘; } //扩大data区域 int newlen = 2 + strlen("dhcp-ath1"); dataadd[1] = strlen("dhcp-ath1"); skb_put(skb, newlen); iph->tot_len = iph->tot_len + newlen; udph->len = udph->len + newlen; memmove(buf + 285 + newlen, buf + 285, skb->len - 285 - newlen); memcpy(buf + 285, dataadd, newlen); //重新计算checksum udph->check = 0; skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0); udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len - iph->ihl * 4, IPPROTO_UDP, skb->csum); iph->check = 0; ip_send_check (iph); printk("[%s:%d]After Packet length = %#4x udplen = %d iplen = %d devname = %s\n", __FUNCTION__, __LINE__, skb->len, udph->len, iph->tot_len, skb->dev->name); printk("head = 0x%p end = 0x%p data = 0x%p tail = 0x%p\n", skb->head, skb->end, skb->data, skb->tail); for (i = 0; i < skb->len; i++){ if (i % 2 == 0) printk(" "); printk("%2.2x", ((unsigned char *)buf)[i]); if (i % 16 == 15) printk("\n"); } printk("\n\n\n\n"); } }
截图:
时间: 2024-11-01 10:21:08