热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

网络安全实验网络嗅探器

0x01前言本来以为可以划水过去的网络安全实验课,突然就被老师布置了一个作业,写一个网络嗅探器,大概要求如下:利用Wins

0x01  前言

本来以为可以划水过去的网络安全实验课,突然就被老师布置了一个作业,写一个网络嗅探器,大概要求如下:

利用Winsock编程接口,设计实现一个能够在共享式局域网中完成网络抓包并分析所截获数据包的嗅探程序。

要求:

1、能够捕获并分析IP分组,ARP分组,ICMP报文,TCP报文,UDP报文等(如果能解析到应用层更好)。

2、数据包显示界面尽量美观



0x02  分析

一开始很苦恼呀,这丢给一个小白怎么做呀,后来听大神说虚拟机里有两个例子,改改就能用了(实验课用的是什么中软的一套程序,网络信息安全 综合实验系统,在虚拟机里运行,拷了也会显示未授权,比较尴尬),知识类实验→网络攻防→实验3 网络嗅探→练习二、练习三,,请教请教学霸,大概看了看,差不多了


就是先捕获一个数据包,捕获数据包后,首先判断是ip分组还是arp分组,如果是ip分组,则调用判断高层协议子函数,进一步分析后输出分析结果,如果是arp分组,则输出判断结果,别的分组则直接输出结果


0x03  代码

#define _WIN32_WINNT 0x502
#include
#include
#include #pragma comment(lib, "ws2_32.lib")#pragma comment(lib, "wpcap")#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)//Key offset
#define IP_HITYPE 9
#define IP_SADDR 12
#define IP_DADDR 16
#define IP_HEADLEN 32#define ICMP_TYPE 0#define TCP_SPORT 0
#define TCP_DPORT 2#define UDP_SPORT 0
#define UDP_DPORT 2//Higher layer Protocol Type#define HI_UNKNOW -1
//IP layer
#define HI_ICMP 1
#define HI_IGMP 2
#define HI_TCP 3
#define HI_UDP 4
#define HI_OSPF 5void ParseTCPLayer( const u_char* cBuff );
void ParseUDPLayer( const u_char* cBuff );
void ParseICMPLayer( const u_char* cBuff );
int ParseIPLayer( const u_char* cBuff );int main()
{pcap_if_t *alldevs;pcap_if_t *d;pcap_t *adhandle;char errbuf[PCAP_ERRBUF_SIZE];char timestr[16];int res,inum&#61;0,i&#61;0;int iPacketsum&#61;0;struct tm *ltime;struct pcap_pkthdr *header;const u_char *pkt_data;int nIpHeaderLen &#61; 5;//! 获取设备列表if( pcap_findalldevs(&alldevs, errbuf ) &#61;&#61; -1 ){printf( "调用pcap_findalldevs时发生错误: %s\n", errbuf );exit(1);} //! 显示设备列表for( d&#61;alldevs; d; d&#61;d->next ){printf( "%d.%s", &#43;&#43;i, d->name );if(d->description)printf( " %s\n", d->description );elseprintf( " no description available\n" );}if( i&#61;&#61;0 ){printf( "\nNo interfaces found! Make sure Winpcap is installed.\n" );return -1;}//! 指定可用设备printf( "Enter the interface number (1-%d):", i );scanf( "%d", &inum );if( inum<1 || inum >i ){printf( "\nInterface number out of range.\n" );// 释放设备列表pcap_freealldevs(alldevs);return -1;}//! 跳转到选中设备for(d&#61;alldevs, i&#61;0; inext,i&#43;&#43;);//! 打开网络设备if( (adhandle&#61;pcap_open_live(d->name, // 设备名称65535, // 捕获数据包最大长度(包括链路层数据)1, // 网卡混杂模式工作1000, // 读超时errbuf // 错误缓冲)) &#61;&#61; NULL ){printf( "Unable to open the adapter. %s is not supported by Winpcap\n" );// 释放设备列表pcap_freealldevs(alldevs);return -1;}printf( "\nlistening on %s...\n", d->description );pcap_freealldevs(alldevs); // 此时已不再需要设备列表,释放设备列表//! 开始捕获数据包&#xff0c;这里没有使用pcap_loop调用回调函数的方法,而是循环调用pcap_next_ex。while( (res&#61;pcap_next_ex( adhandle, &header, &pkt_data)) >&#61;0 ){if( res &#61;&#61; 0 ){// 超时continue;}iPacketsum&#43;&#43;;printf("\n ------------------------------------------------\n");// 判断数据包类型printf("数据包类型编码或长度&#xff1a;%.2x%.2x\n",pkt_data[12],pkt_data[13]);if(pkt_data[12] &#61;&#61; 8 && pkt_data[13] &#61;&#61; 0){printf("This is an ip data packet!\n");// 解析ip数据包switch( ParseIPLayer( pkt_data &#43;14 ) ){case HI_ICMP:ParseICMPLayer( &pkt_data[nIpHeaderLen*4] );break;case HI_TCP:ParseTCPLayer( &pkt_data[nIpHeaderLen*4] );break;case HI_UDP:ParseUDPLayer( &pkt_data[nIpHeaderLen*4] );break;}}else if(pkt_data[12] &#61;&#61; 8 && pkt_data[13] &#61;&#61; 6){printf("This is an ARP data packet!\n");}else{printf("Other type data packet!\n");}// 捕获时间ltime &#61; localtime(&header->ts.tv_sec);strftime( timestr, sizeof(timestr), "%H:%M:%S", ltime);printf( " No %d. 时间%s. 长度%d\n", iPacketsum,timestr, header->len );// 单行16字节显示数据包内容for(unsigned int j&#61;1; jlen&#43;1; j&#43;&#43;){printf( " %.2x", pkt_data[j-1] );if( (j % 16) &#61;&#61; 0 ) printf("\n");}}//! 关闭设备pcap_close( adhandle );return 0;
}// 解析IP层&#xff0c;获得上层协议类型
int ParseIPLayer( const u_char* cBuff )
{unsigned int usIp1(0), usIp2(0), usIp3(0), usIp4(0);unsigned int nIpHiType(0);memcpy( &usIp1, &cBuff[IP_SADDR], sizeof(char) );memcpy( &usIp2, &cBuff[IP_SADDR&#43;1], sizeof(char) );memcpy( &usIp3, &cBuff[IP_SADDR&#43;2], sizeof(char) );memcpy( &usIp4, &cBuff[IP_SADDR&#43;3], sizeof(char) );printf("****** IP Layer ******\n");printf("源IP地址&#xff1a;%d.%d.%d.%d ", usIp1,usIp2,usIp3,usIp4);memcpy( &usIp1, &cBuff[IP_DADDR], sizeof(char) );memcpy( &usIp2, &cBuff[IP_DADDR&#43;1], sizeof(char) );memcpy( &usIp3, &cBuff[IP_DADDR&#43;2], sizeof(char) );memcpy( &usIp4, &cBuff[IP_DADDR&#43;3], sizeof(char) );printf("目的IP地址&#xff1a;%d.%d.%d.%d ", usIp1,usIp2,usIp3,usIp4);memcpy( &nIpHiType, &cBuff[IP_HITYPE], sizeof(char) );switch ( nIpHiType){case 1:printf("IP高层协议类型&#xff1a;%d &#xff08;ICMP&#xff09;", nIpHiType);return HI_ICMP;case 2:printf("IP高层协议类型&#xff1a;%d &#xff08;IGMP&#xff09;", nIpHiType);return HI_IGMP;case 6:printf("IP高层协议类型&#xff1a;%d &#xff08;TCP&#xff09;", nIpHiType);return HI_TCP;case 17:printf("IP高层协议类型&#xff1a;%d &#xff08;UDP&#xff09;", nIpHiType);return HI_UDP;case 89:printf("IP高层协议类型&#xff1a;%d &#xff08;OSPF&#xff09;", nIpHiType);return HI_OSPF;default:printf("IP高层协议类型&#xff1a;%d &#xff08;未知的类型&#xff09;", nIpHiType);return HI_UNKNOW;}
}// 解析ICMP数据包&#xff0c;获得ICMP类型
void ParseICMPLayer( const u_char* cBuff )
{unsigned int nIcmpType(0);memcpy( &nIcmpType, &cBuff[ICMP_TYPE], sizeof(char) );printf("****** ICMP Layer ******\n");switch ( nIcmpType ){case 3:printf("ICMP类型&#xff1a;%d &#xff08;终点不可达&#xff09;", nIcmpType);break;case 4:printf("ICMP类型&#xff1a;%d &#xff08;源点抑制&#xff09;", nIcmpType);break;case 11:printf("ICMP类型&#xff1a;%d &#xff08;超时&#xff09;", nIcmpType);break;case 12:printf("ICMP类型&#xff1a;%d &#xff08;参数问题&#xff09;", nIcmpType);break;case 5:printf("ICMP类型&#xff1a;%d &#xff08;改变路由&#xff09;", nIcmpType);break;case 8:printf("ICMP类型&#xff1a;%d &#xff08;回送请求&#xff09;", nIcmpType);break;case 0:printf("ICMP类型&#xff1a;%d&#xff08;回送回答&#xff09;", nIcmpType);break;case 13:printf("ICMP类型&#xff1a;%d &#xff08;时间戳请求&#xff09;", nIcmpType);break;case 14:printf("ICMP类型&#xff1a;%d &#xff08;时间戳回答&#xff09;", nIcmpType);break;case 17:printf("ICMP类型&#xff1a;%d &#xff08;地址掩码请求&#xff09;", nIcmpType);break;case 18:printf("ICMP类型&#xff1a;%d &#xff08;地址掩码回答&#xff09;", nIcmpType);break;case 10:printf("ICMP类型&#xff1a;%d&#xff08;路由器询问&#xff09;", nIcmpType);break;case 9:printf("ICMP类型&#xff1a;%d &#xff08;路由器通告&#xff09;", nIcmpType);break;default:printf("ICMP类型&#xff1a;%d &#xff08;未知的ICMP类型&#xff09;", nIcmpType);}
}// 解析TCP数据包&#xff0c;获得源、目的端口对
void ParseTCPLayer( const u_char* cBuff )
{unsigned short usSPort(0);unsigned short usDPort(0);printf("****** TCP Layer ******\n");memcpy( &usSPort, &cBuff[TCP_SPORT], 2*sizeof(char) );usSPort &#61; htons( usSPort );switch ( usSPort ){case 20:printf("TCP源端口&#xff1a;%d&#xff08;FTP 数据&#xff09; ",usSPort);break;case 21:printf("TCP源端口&#xff1a;%d&#xff08;FTP 控制&#xff09; ",usSPort);break;case 23:printf("TCP源端口&#xff1a;%d&#xff08;TELNET&#xff09; ",usSPort);break;case 25:printf("TCP源端口&#xff1a;%d&#xff08;SMTP&#xff09; ",usSPort);break;case 80:printf("TCP源端口&#xff1a;%d&#xff08;HTTP&#xff09; ",usSPort);break;case 110:printf("TCP源端口&#xff1a;%d&#xff08;POP3&#xff09; ",usSPort);break;case 143:printf("TCP源端口&#xff1a;%d&#xff08;IMAP&#xff09; ",usSPort);break;default:printf("TCP源端口&#xff1a;%d ",usSPort);break;}memcpy( &usDPort, &cBuff[TCP_DPORT], 2*sizeof(char) );usDPort &#61; htons( usDPort );switch ( usDPort ){case 20:printf("TCP目的端口&#xff1a;%d&#xff08;FTP 数据&#xff09;\n", usDPort);break;case 21:printf("TCP目的端口&#xff1a;%d&#xff08;FTP 控制&#xff09;\n", usDPort);break;case 23:printf("TCP目的端口&#xff1a;%d&#xff08;TELNET&#xff09;\n", usDPort);break;case 25:printf("TCP目的端口&#xff1a;%d&#xff08;SMTP&#xff09;\n", usDPort);break;case 80:printf("TCP目的端口&#xff1a;%d&#xff08;HTTP&#xff09;\n", usDPort);break;case 110:printf("TCP目的端口&#xff1a;%d&#xff08;POP3&#xff09;\n", usDPort);break;case 143:printf("TCP目的端口&#xff1a;%d&#xff08;Imap&#xff09;\n", usDPort);break;default:printf("TCP目的端口&#xff1a;%d\n", usDPort);break;}
}// 解析UDP数据包&#xff0c;获得源、目的端口对
void ParseUDPLayer( const u_char* cBuff )
{unsigned short usSPort(0);unsigned short usDPort(0);printf("****** UDP Layer ******\n");memcpy( &usSPort, &cBuff[UDP_SPORT], 2*sizeof(char) );usSPort &#61; htons( usSPort );switch ( usSPort ){case 161:printf("UDP源端口&#xff1a;%d&#xff08;SNMP&#xff09; ", usSPort);break;case 67:printf("UDP源端口&#xff1a;%d&#xff08;DHCP&#xff09; ", usSPort);break;case 68:printf("UDP源端口&#xff1a;%d&#xff08;DHCP&#xff09; ", usSPort);break;case 53:printf("UDP源端口&#xff1a;%d&#xff08;DNS&#xff09; ", usSPort);break;case 520:printf("UDP源端口&#xff1a;%d&#xff08;RIP&#xff09; ", usSPort);break;case 138:printf("UDP源端口&#xff1a;%d&#xff08;NetBios&#xff09; ", usSPort);break;case 139:printf("UDP源端口&#xff1a;%d&#xff08;SMB&#xff09; ", usSPort);break;case 137:printf("UDP源端口&#xff1a;%d&#xff08;WINS&#xff09; ", usSPort);break;default:printf("UDP源端口&#xff1a;%d ", usSPort);break;}memcpy( &usDPort, &cBuff[UDP_DPORT], 2*sizeof(char) );usDPort &#61; htons( usDPort );switch ( usDPort ){case 161:printf("UDP目的端口&#xff1a;%d&#xff08;SNMP&#xff09;\n", usDPort);break;case 67:printf("UDP目的端口&#xff1a;%d&#xff08;DHCP&#xff09;\n", usDPort);break;case 68:printf("UDP目的端口&#xff1a;%d&#xff08;DHCP&#xff09;\n", usDPort);break;case 53:printf("UDP目的端口&#xff1a;%d&#xff08;DNS&#xff09;\n", usDPort);break;case 520:printf("UDP目的端口&#xff1a;%d&#xff08;RIP&#xff09;\n", usDPort);break;case 138:printf("UDP目的端口&#xff1a;%d&#xff08;NetBios&#xff09;\n", usDPort);break;case 139:printf("UDP目的端口&#xff1a;%d&#xff08;SMB&#xff09;\n", usDPort);break;case 137:printf("UDP目的端口&#xff1a;%d&#xff08;WINS&#xff09;\n", usDPort);break;default:printf("UDP目的端口&#xff1a;%d\n", usDPort);break;}
}








0x04  问题

给老师演示的时候&#xff0c;解析的ip分组再向下分析时&#xff0c;都是未知类型&#xff0c;而且ip地址看着也很奇怪&#xff0c;最后经过学霸指点&#xff0c;需要去掉前面的14个 char&#xff0c;为什么呢&#xff1f;请看下图&#xff1a;


前14个字节没什么用了&#xff0c;但是那些函数还是从头开始分析&#xff0c;那就比较尴尬了&#xff08;对了&#xff0c;第12,13字节&#xff0c;就是判断是ip分组还是arp分组的地方&#xff0c;ip分组是 0800&#xff0c;arp分组是0806&#xff09;

所以调用ParseIPLayer函数时&#xff0c;捕获到的数据需要向后偏移14个字节&#xff0c;也就是调用 ParseIPLayer( pkt_data &#43; 14 )


没有按老师要求用winsock编程接口&#xff0c;就这样吧&#xff0c;实现了就可以


0x05  废话

唉&#xff0c;看了一节课&#xff0c;也不如学霸的一句话&#xff0c;差距满满的

越微小的错误越难找到&#xff0c;&#xff0c;


推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • Linux防火墙配置—允许转发
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
author-avatar
灵123456妞子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有