出自: http://www.stuhack.com

VC++编程实现网络嗅探器

引言

从事网络安全的技术人员和相当一部分准黑客(指那些使用现成的黑客软件进行攻击而不是根据需要去自己编写代码的人)都一定不会对网络嗅探器(sniffer)感到陌生,网络嗅探器无论是在网络安全还是在黑客攻击方面均扮演了很重要的角色。通过使用网络嗅探器可以把网卡设置于混杂模式,并可实现对网络上传输的数据包的捕获与分析。此分析结果可供网络安全分析之用,但如为黑客所利用也可以为其发动进一步的攻击提供有价值的信息。可见,嗅探器实际是一把双刃剑。

虽然网络嗅探器技术被黑客利用后会对网络安全构成一定的威胁,但嗅探器本身的危害并不是很大,主要是用来为其他黑客软件提供网络情报,真正的攻击主要是由其他黑软来完成的。而在网络安全方面,网络嗅探手段可以有效地探测在网络上传输的数据包信息,通过对这些信

VC++编程实现网络嗅探器

引言

从事网络安全的技术人员和相当一部分准黑客(指那些使用现成的黑客软件进行攻击而不是根据需要去自己编写代码的人)都一定不会对网络嗅探器(sniffer)感到陌生,网络嗅探器无论是在网络安全还是在黑客攻击方面均扮演了很重要的角色。通过使用网络嗅探器可以把网卡设置于混杂模式,并可实现对网络上传输的数据包的捕获与分析。此分析结果可供网络安全分析之用,但如为黑客所利用也可以为其发动进一步的攻击提供有价值的信息。可见,嗅探器实际是一把双刃剑。

虽然网络嗅探器技术被黑客利用后会对网络安全构成一定的威胁,但嗅探器本身的危害并不是很大,主要是用来为其他黑客软件提供网络情报,真正的攻击主要是由其他黑软来完成的。而在网络安全方面,网络嗅探手段可以有效地探测在网络上传输的数据包信息,通过对这些信息的分析利用是有助于网络安全维护的。权衡利弊,有必要对网络嗅探器的实现原理进行介绍。

嗅探器设计原理

嗅探器作为一种网络通讯程序,也是通过对网卡的编程来实现网络通讯的,对网卡的编程也是使用通常的套接字(socket)方式来进行。但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。而网络嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。

具体到编程实现上,这种对网卡混杂模式的设置是通过原始套接字(raw

socket)来实现的,这也有别于通常经常使用的数据流套接字和数据报套接字。在创建了原始套接字后,需要通过setsockopt()函数来设置IP头操作选项,然后再通过bind()函数将原始套接字绑定到本地网卡。为了让原始套接字能接受所有的数据,还需要通过ioctlsocket()来进行设置,而且还可以指定是否亲自处理IP头。至此,实际就可以开始对网络数据包进行嗅探了,对数据包的获取仍象流式套接字或数据报套接字那样通过recv()函数来完成。但是与其他两种套接字不同的是,原始套接字此时捕获到的数据包并不仅仅是单纯的数据信息,而是包含有

IP头、

TCP头等信息头的最原始的数据信息,这些信息保留了它在网络传输时的原貌。通过对这些在低层传输的原始信息的分析可以得到有关网络的一些信息。由于这些数据经过了网络层和传输层的打包,因此需要根据其附加的帧头对数据包进行分析。下面先给出结构.数据包的总体结构:

数据包

IP头 TCP头(或其他信息头) 数据

数据在从应用层到达传输层时,将添加TCP数据段头,或是UDP数据段头。其中UDP数据段头比较简单,由一个8字节的头和数据部分组成,具体格式如下:

16位 16位

源端口 目的端口

UDP长度 UDP校验和

而TCP数据头则比较复杂,以20个固定字节开始,在固定头后面还可以有一些长度不固定的可选项,下面给出TCP数据段头的格式组成:

16位 16位

源端口 目的端口

顺序号

确认号

TCP头长 (保留)7位 URG ACK PSH RST SYN FIN 窗口大小

校验和 紧急指针

可选项(0或更多的32位字)

数据(可选项)

对于此TCP数据段头的分析在编程实现中可通过数据结构_TCP来定义:

typedef struct _TCP{ WORD SrcPort; // 源端口

WORD DstPort; // 目的端口

DWORD SeqNum; // 顺序号

DWORD AckNum; // 确认号

BYTE DataOff; // TCP头长

BYTE Flags; // 标志(URG、ACK等)

WORD Window; // 窗口大小

WORD Chksum; // 校验和

WORD UrgPtr; // 紧急指针

} TCP;

typedef TCP *LPTCP;

typedef TCP UNALIGNED * ULPTCP;

在网络层,还要给TCP数据包添加一个IP数据段头以组成IP数据报。IP数据头以大端点机次序传送,从左到右,版本字段的高位字节先传输(SPARC是大端点机;Pentium是小端点机)。如果是小端点机,就要在发送和接收时先行转换然后才能进行传输。IP数据段头格式如下:

16位 16位

版本 IHL 服务类型 总长

标识 标志 分段偏移

生命期 协议 头校验和

源地址

目的地址

选项(0或更多)

同样,在实际编程中也需要通过一个数据结构来表示此IP数据段头,下面给出此数据结构的定义:

typedef struct _IP{

union{ BYTE Version; // 版本

BYTE HdrLen; // IHL

};

BYTE ServiceType; // 服务类型

WORD TotalLen; // 总长

WORD ID; // 标识

union{ WORD Flags; // 标志

WORD FragOff; // 分段偏移

};

BYTE TimeToLive; // 生命期

BYTE Protocol; // 协议

WORD HdrChksum; // 头校验和

DWORD SrcAddr; // 源地址

DWORD DstAddr; // 目的地址

BYTE Options; // 选项

} IP;

typedef IP * LPIP;

typedef IP UNALIGNED * ULPIP;

在明确了以上几个数据段头的组成结构后,就可以对捕获到的数据包进行分析了。

嗅探器的具体实现

根据前面的设计思路,不难写出网络嗅探器的实现代码,下面就给出一个简单的示例,该示例可以捕获到所有经过本地网卡的数据包,并可从中分析出协议、IP源地址、IP目标地址、TCP源端口号、TCP目标端口号以及数据包长度等信息。由于前面已经将程序的设计流程讲述的比较清楚了,因此这里就不在赘述了,下面就结合注释对程序的具体是实现进行讲解,同时为程序流程的清晰起见,去掉了错误检查等保护性代码。主要代码实现清单为:

// 检查 Winsock 版本号,WSAData为WSADATA结构对象

WSAStartup(MAKEWORD(2, 2), &WSAData);

// 创建原始套接字

sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW));

// 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理

setsockopt(sock, IPPROTO_IP, IP_HDRINCL,

(char*)&flag, sizeof(flag));

// 获取本机名

gethostname((char*)LocalName, sizeof(LocalName)-1);

// 获取本地 IP 地址

pHost = gethostbyname((char*)LocalName));

// 填充SOCKADDR_IN结构

addr_in.sin_addr = *(in_addr

*)pHost->h_addr_list[0]; //IP

addr_in.sin_family = AF_INET;

addr_in.sin_port = htons(57274);

// 把原始套接字sock 绑定到本地网卡地址上

bind(sock, (PSOCKADDR)&addr_in,

sizeof(addr_in));

// dwValue为输入输出参数,为1时执行,0时取消

DWORD dwValue = 1;

// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL

// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

ioctlsocket(sock, SIO_RCVALL, &dwValue);

前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:

while (true)

{

// 接收原始数据包信息

int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);

if (ret > 0)

{

// 对数据包进行分析,并输出分析结果

ip = *(IP*)RecvBuf;

tcp = *(TCP*)(RecvBuf + ip.HdrLen);

TRACE("协议: %srn",GetProtocolTxt(ip.Protocol));

TRACE("IP源地址:

%srn",inet_ntoa(*(in_addr*)&ip.SrcAddr));

TRACE("IP目标地址:

%srn",inet_ntoa(*(in_addr*)&ip.DstAddr));

TRACE("TCP源端口号: %drn",tcp.SrcPort);

TRACE("TCP目标端口号:%drn",tcp.DstPort);

TRACE("数据包长度: %drnrnrn",ntohs(ip.TotalLen));

}

}

其中,在进行协议分析时,使用了GetProtocolTxt()函数,该函数负责将IP包中的协议(数字标识的)转化为文字输出,该函数实现如下:

#define PROTOCOL_STRING_ICMP_TXT "ICMP"

#define PROTOCOL_STRING_TCP_TXT "TCP"

#define PROTOCOL_STRING_UDP_TXT "UDP"

#define PROTOCOL_STRING_SPX_TXT "SPX"

#define PROTOCOL_STRING_NCP_TXT "NCP"

#define PROTOCOL_STRING_UNKNOW_TXT "UNKNOW"

......

CString CSnifferDlg::GetProtocolTxt(int Protocol)

{

switch (Protocol){

case IPPROTO_ICMP : //1

return PROTOCOL_STRING_ICMP_TXT;

case IPPROTO_TCP : //6

return PROTOCOL_STRING_TCP_TXT;

case IPPROTO_UDP : //17

return PROTOCOL_STRING_UDP_TXT;

default:

return PROTOCOL_STRING_UNKNOW_TXT;

}

最后,为了使程序能成功编译,需要包含头文件winsock2.h和ws2tcpip.h。在本示例中将分析结果用TRACE()宏进行输出,在调试状态下运行,得到的一个分析结果如下:

协议: UDP

IP源地址: 172.168.1.5

IP目标地址: 172.168.1.255

TCP源端口号: 16707

TCP目标端口号:19522

数据包长度: 78

......

协议: TCP

IP源地址: 172.168.1.17

IP目标地址: 172.168.1.1

TCP源端口号: 19714

TCP目标端口号:10

数据包长度: 200

......

从分析结果可以看出,此程序完全具备了嗅探器的数据捕获以及对数据包的分析等基本功能。

小结

本文介绍的以原始套接字方式对网络数据进行捕获的方法实现起来比较简单,尤其是不需要编写VxD虚拟设备驱动程序就可以实现抓包,使得其编写过程变的非常简便,但由于捕获到的数据包头不包含有帧信息,因此不能接收到与

IP 同属网络层的其它数据包, 如

ARP数据包、RARP数据包等。在前面给出的示例程序中考虑到安全因素,没有对数据包做进一步的分析,而是仅仅给出了对一般信息的分析方法。通过本文的介绍,可对原始套接字的使用方法以及TCP/IP协议结构原理等知识有一个基本的认识。本文所述代码在Windows

2000下由Microsoft Visual C++ 6.0编译调试通过。

将网卡设为混杂模式_[转载]如何将网卡设置为混杂模式相关推荐

  1. 有几种部署模式_来!PyFlink 作业的多种部署模式

    关于 PyFlink 的博客我们曾介绍过 PyFlink 的功能开发,比如,如何使用各种算子(Join/Window/AGG etc.),如何使用各种 Connector(Kafka, CSV, So ...

  2. crt 8.7.3 黑暗模式_科技有意思 | 黑黑黑黑黑黑黑黑暗模式

    不知从什么时候,手机上的黑暗模式成了系统的标配. 本来这只是系统中的一个功能,现在经过从iOS 13系统的终于支持.苹果督促包括腾讯在内的开发者尽快适配,到一直不支持黑暗模式的微信也答应尽快开发相关功 ...

  3. java 生产者消费者模式_聊聊并发(十)生产者消费者模式

    本文首发于InfoQ   作者:方腾飞  校对:张龙 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使 ...

  4. 我的世界java旁观者模式_我的世界如何切换到旁观模式

    我的世界中如何切换到旁观模式 本篇教程将用图文的形式一步步教会你在我的世界中如何切换到旁观模式. 旁观模式只出现在我的世界PC/Mac版本中,它首次出现在我的世界PC/Mac  1.8版本中,允许玩家 ...

  5. 小米手环6NFc支持Android,小米手环6nfc有几种运动模式_小米手环6nfc支持几种运动模式...

    小米手环6nfc版发布之后有不少人关注,这个版本相对之前增加了不少运动模式,具体小米手环6nfc有几种运动模式,大家感兴趣的话不妨来中国排行网看看小米手环6nfc支持几种运动模式. 1.小米手环6nf ...

  6. android 打开免打扰模式_今天才知道,原来手机飞行模式这么厉害,每天晚上都能用得到...

    在我们的手机上有一个飞行模式,想必很多人都只是知道,却没有用过,其实这个飞行模式还是挺厉害的,我们每天晚上都能用得着,一起看来了解一下吧. 一.降低辐射 一天工作8小时就已经够累的了,晚上回到家里当然 ...

  7. linux查看cpupower模式,CPU优化建议使用cpupower设置CPU Performance模式

    前言 CPU动态节能技术用于降低服务器功耗,通过选择系统空闲状态不同的电源管理策 略,可以实现不同程度降低服务器功耗,更低的功耗策略意味着CPU唤醒更慢对性能 影响更大.对于对时延和性能要求高的应用, ...

  8. 计算机色盲模式在哪,Win10系统怎么设置开启色盲模式

    电脑现如今已成为不少人日常生活工作中不可或缺的重要工具,但我们习以为常的电脑使用,对一些色盲朋友们来说可能不太方便.好在如今新版的win10系统新增了色盲模式,这对于色盲朋友们来说是一个非常棒的功能, ...

  9. 艾伟_转载:.NET设计模式:工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着"某个对象"的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?提供一种封装机制来隔离出 ...

最新文章

  1. 算法工程师养成记(附精选面试题)
  2. c语言矩阵的乘积,c语言矩阵相乘
  3. k8s控制器controller(Deployment)示例:通过命令生成deployment和service的yaml文件
  4. php 图片路径混淆,爬虫遇到了字符图片混淆。pytesseract识别图片字符
  5. SOL注入——HTTP头部注入(2)(七)
  6. android 多态如何组件化,Android组件化之子模块之间通信方案
  7. 数据仓库被淘汰了?都怪数据湖
  8. 关于Samba的资源共享配置详解
  9. CIO:互联网IT系统和传统企业IT系统的异同
  10. 【终极算法】从阿尔法狗元(AlphaGo Zero)的诞生看终极算法的可能性
  11. 进军杀毒市场!百度杀毒软件2013正式发布
  12. smt贴片加工贴片机开机和贴片编程
  13. 激流之傲服务器维修,国服3月15日部分服务器预计维护16小时
  14. 报表工具(报表设计器)使用的开发历程
  15. 如何用美剧真正提升你的英语水平?
  16. 最好用的六款虚拟机软件
  17. 【闲谈】我为什么不想回答你的问题
  18. [译]不再对 MVVM 感到绝望
  19. iOS开发学习48 OC的lambda block
  20. 【Java并发】double-checked-locking设计模式

热门文章

  1. 【已解决】无法加载 DLL“xxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。
  2. 【译】创建纹理文本的技巧
  3. 上海亚商投顾:两市成交创23个月新低 医疗器械板块强势
  4. Could not find method ndk() for arguments [build_3k23ytju20kdwiqf5u0x5zphe$_run_closure1$_closure4@7
  5. qq录制视频保存到哪了?如何更改qq录屏存储位置
  6. android利用小米推送保活自已应用,Android--利用第三方推送实现APP伪保活(小米篇)...
  7. 分类接口,淘宝分类详情 API
  8. 计算机操作系统思维导图_计算机网络思维导图(零基础--思维导图详细版本及知识点)...
  9. win10系统上安装CAD2007百度网盘免费下载和安装教程
  10. 够快,首个“开源ChatGPT项目“来了!网友吐槽:这谁能跑