网络测试工具tomahawk之二 代码修改篇
来源:互联网 发布:java运算类型有哪几种 编辑:程序博客网 时间:2024/05/01 20:18
在上一篇中提到了Tomahawk只能测试二层设备,这可能是由于该工具本来就是tipping point公司用来测试其IPS的,而该公司的IPS刚好为二层透明模式。
二层的IPS产品很多,尤其是国外的产品,配置方便(实际上几乎不需要配置),但是国内的IPS往往附加在防火墙设备上,其工作在哪一层依赖于防火墙的配置,虽然防火墙可以配置成透明模式,但是一般单位都是把NAT做在防火墙上,所以网关型的IPS也是很常见。Tomahawk的局限在此。
本文将对tomahawk的代码作一个粗略的分析,比较乱,仅仅涉及为了将其修改为可以测试三层设备的部分。
1. 代码文件清单:
Tomahawk1.1包括以下文件
alloc.h
eventloop.c
eventloop.h
packetutil.c
packetutil.h //定义了两个重要的结构:trace和handle及其相关操作
test.pcap //一个用于测试的数据包文件(不是攻击)
tomahawk.c //主要发包收包程序
2. 具体代码
要看懂tomahawk,一定要理解其中两个重要的结构:trace和handle
l trace:
包括多个包文件的内容,是一个链表结构,包括发送次数等信息,也就是一次命令可以定义的一个发送过程。该结构由函数LoadTrace装载,但LoadTrace中(前段)并未初始化数据报(trace->pkt = NULL;),只是记录了文件名;包文件内容由LoadPacket导入到trace->pkt中,LoadPacket函数判断源和目的IP地址,并且修改MAC(在此可加入网关mac功能)
注:LoadPacket在1.1版中作了CanRewrite检查,即只处理TCP/UDP/ICMP数据包
l handle:
由createHandle创建,是一个链表结构,完成一次发送过程(一个数据包一次发送为一个handle)。其中主要函数:
CreatePacketSendGroup 查找包文件中独立的包(不依赖接收到的包就可以发送的那些,放入group中)
SendPackets 其中修改了源和目的IP地址将包发送出去,此函数还被RecvPacket,RetrySendPackets,ResendPackets调用;
RecvPacket中会根据收到数据报的handleID判断是否为发出的包。
l 如何判断收到的包
关键判断函数GetHandler,如果返回值不为null则numRecv++
GetHandler(const u_char *packetData, int len, int modAddrs, unsigned char startId, unsigned char endId)
如果modAddrs则ip的第二位为handleID(如192.22.1.1中22即为handle ID),如果handleID不在startId和endId之间也返回null.
如果没有modAddrs则返回startId的handle.
l 有一个activehandle[]数组记录了所有激活的handle
3. 代码修改
3.1 参数修改
添加了几个参数
-G GW2's MAC Interface2 gateway MAC Address @New!@
-k GW1's IP Interface1 gateway IP Address @New!@
-K GW2's IP Interface2 gateway IP Address @New!@
-S StudyMode Mode for gateway to study ARP @New!@
这几个参数分别指定了网关1、2的IP和MAC地址,-S参数是为了让网关学习到模拟出的IP地址的MAC地址,一般在测试时先运行一次:
tomahawk –S –k a.b.c.d –K e.f.g.h –g x:x:x:x:x:x –G x:x:x:x:x:x –l 251 –f test.pcap
这样受测设备将会学习到所有a.1.*.*~a.251.*.*和e.1.*.*~e.251.*.*的mac地址,也就是安装了tomahawk的机器的两个网卡的mac地址。
3.2代码修改
修改loadpacket中关于mac地址的内容为:
if (useGate) ...{
//fprintf(stderr, "[info] mac1 ");
ph->ether_shost[0] = if1.eaddr[0];
ph->ether_shost[1] = if1.eaddr[1];
ph->ether_shost[2] = if1.eaddr[2];
ph->ether_shost[3] = if1.eaddr[3];
ph->ether_shost[4] = if1.eaddr[4];
ph->ether_shost[5] = if1.eaddr[5];
ph->ether_dhost[0] = mac1[0];
ph->ether_dhost[1] = mac1[1];
ph->ether_dhost[2] = mac1[2];
ph->ether_dhost[3] = mac1[3];
ph->ether_dhost[4] = mac1[4];
ph->ether_dhost[5] = mac1[5];
}else...{
ph->ether_shost[0] = if1.eaddr[0];
ph->ether_shost[1] = if1.eaddr[1];
ph->ether_shost[2] = if1.eaddr[2];
ph->ether_shost[3] = if1.eaddr[3];
ph->ether_shost[4] = if1.eaddr[4];
ph->ether_shost[5] = if1.eaddr[5];
ph->ether_dhost[0] = if2.eaddr[0];
ph->ether_dhost[1] = if2.eaddr[1];
ph->ether_dhost[2] = if2.eaddr[2];
ph->ether_dhost[3] = if2.eaddr[3];
ph->ether_dhost[4] = if2.eaddr[4];
ph->ether_dhost[5] = if2.eaddr[5];
}
} else ...{
if (useGate)...{
//fprintf(stderr, "[info] mac2 ");
ph->ether_dhost[0] = mac2[0];
ph->ether_dhost[1] = mac2[1];
ph->ether_dhost[2] = mac2[2];
ph->ether_dhost[3] = mac2[3];
ph->ether_dhost[4] = mac2[4];
ph->ether_dhost[5] = mac2[5];
ph->ether_shost[0] = if2.eaddr[0];
ph->ether_shost[1] = if2.eaddr[1];
ph->ether_shost[2] = if2.eaddr[2];
ph->ether_shost[3] = if2.eaddr[3];
ph->ether_shost[4] = if2.eaddr[4];
ph->ether_shost[5] = if2.eaddr[5];;
}else ...{
ph->ether_dhost[0] = if1.eaddr[0];
ph->ether_dhost[1] = if1.eaddr[1];
ph->ether_dhost[2] = if1.eaddr[2];
ph->ether_dhost[3] = if1.eaddr[3];
ph->ether_dhost[4] = if1.eaddr[4];
ph->ether_dhost[5] = if1.eaddr[5];
ph->ether_shost[0] = if2.eaddr[0];
ph->ether_shost[1] = if2.eaddr[1];
ph->ether_shost[2] = if2.eaddr[2];
ph->ether_shost[3] = if2.eaddr[3];
ph->ether_shost[4] = if2.eaddr[4];
ph->ether_shost[5] = if2.eaddr[5];
}
}
修改ReadPacket函数,使其在-S模式下可以发送arp学习包
if (memcmp(x1,arp,6))...{
}else...{
memcpy (&arp_r, buffer, 42);
//ip4p.s_addr = arp_r.arp_tpa;
//fprintf(stderr, "[info] find arp %s", inet_ntoa(ip4p));
//fprintf(stderr, "[info] find arp %s", arp_r.arp_tpa);
//fprintf(stderr, "[info] IP %x:%x:%x:%x ", arp_r.arp_tpa[0],arp_r.arp_tpa[1],arp_r.arp_tpa[2],arp_r.arp_tpa[3]);
//for (k=0; k<42; k++){
// fprintf(stderr, "%x:", arp_r.eh_dst[k]);
//}
if ((( arp_r.arp_tha[6] & 0xFF) == firstByte1) && (!strncmp(interface->device, interface1, 4)))...{
for (k=0; k<4; k++)...{
arp_s1.arp_spa[k]=arp_r.arp_tpa[k];
}
memset(sendbuf, 0, sizeof(sendbuf));
memcpy(sendbuf, &arp_s1, 42);
//fprintf(stderr, "on interface 1 ");
}
if ((( arp_r.arp_tha[6] & 0xFF) == firstByte2) && (!strncmp(interface->device, interface2, 4)))...{
for (k=0;k<4;k++)...{
arp_s2.arp_spa[k]=arp_r.arp_tpa[k];
}
memset(sendbuf, 0, sizeof(sendbuf));
memcpy(sendbuf, &arp_s2, 42);
//fprintf(stderr, "on interface 2 ");
}
sendto(interface->fd, sendbuf, 42, 0, (struct sockaddr *)NULL, 0);
//WriteInterface(interface, sendbuf, 42);
}
}
修改Sendpackets函数,使其在发送数据包时将IP改为同网关IP的第一位相对应
if (useGate)...{
if (p[pktId].iface == IFACE_I)...{
iph.saddr = GetWireIP(h->id, p[pktId].wireSrc, p[pktId].saddr, firstByte1);
iph.daddr = GetWireIP(h->id, p[pktId].wireDst, p[pktId].daddr, firstByte2);
}else...{
iph.saddr = GetWireIP(h->id, p[pktId].wireSrc, p[pktId].saddr, firstByte2);
iph.daddr = GetWireIP(h->id, p[pktId].wireDst, p[pktId].daddr, firstByte1);
}
}else...{
iph.saddr = GetWireIP(h->id, p[pktId].wireSrc, p[pktId].saddr, firstByte);
iph.daddr = GetWireIP(h->id, p[pktId].wireDst, p[pktId].daddr, firstByte);
}
。。。。。。。。。
至此,修改完毕。
在下图所示的测试环境中:
运行
运行通过!
以前一直在搞java开发,这次使用C,指针刚用起来总是莫名其妙,后来解决了几个BUG后,感觉还是C灵活,指针可以“指哪打哪”!而且速度对于java来说快的不可想象,呵呵。想来有次测试任务需使用loadrunner测试Samba和NFS服务器性能指标(1000并发),当时写了两个java程序,用了8台机器才勉强测完,有时被测试的机器安然无恙,我的测试机倒一台台的挂掉,现在看来,如果用C的话一对一测试都应该没有问题。
tomahawk的修改完毕了,下面该做些什么呢?在后面的文章里,将会介绍
1. 为tomahawk做一个web方式的管理界面
2. 导出blade ids informer的攻击包作为tomahawk的攻击包库(blade ids informer的攻击库很全,但其格式不公开)
- 网络测试工具tomahawk之二 代码修改篇
- 网络测试工具tomahawk之一 安装篇
- 代码生成器工具之二
- tomahawk JSF组件扩展组件(二)
- 实验二:网络测试命令和工具的使用
- 代码自动生成工具MyGeneration之二
- 代码自动生成工具MyGeneration之二
- 代码自动生成工具MyGeneration之二
- 接口测试工具Postman之二---工具介绍
- 常用网络测试工具
- IxChariot网络测试工具
- 网络测试工具
- 常用网络测试工具
- 网络测试工具netperf
- 网络测试工具netperf
- 网络测试工具netperf
- C# 网络测试工具
- iperf网络测试工具
- ubuntu 的tomcat 自启动和远程控制
- Easy Client Side TabStrip
- PHP 中检查库或函数是否可用的方法
- 航班,股票....的WEb服务接口
- MapBasic相关(话题、源码、应用等)交流,欢迎大家来这里交流
- 网络测试工具tomahawk之二 代码修改篇
- PHP - Manual手册 - XC. Miscellaneous Functions杂项函数 - sleep延迟执行
- Request.QueryString
- 常用的js 操作
- 关于静态成员变量在类继承中的一个误区
- foreach
- Logistic混沌映射
- Windows Installer(安装服务)出错的解决方案
- 关于SqlServer中openxml的使用