sniffer实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验环境:
windows,C语言
实验内容:
用C语言编写一个监听网络流量的程序,并对截取的报文进行解析
实验代码:
#include <winsock2.h>
#include <iostream>
#include "RawSocket.h"
#pragma comment(lib, "ws2_32.lib") using namespace std;
memcpy ( &sa, hp->h_addr_list[0], hp->h_length ); ulLocaIP = sa.s_addr; } else { cout << "Can't Get local IP address! " << endl; return -1; }
sockaddr_in addr_in; //服务器地址信息
#define CAP_MAX_PACKETS 1000
void ParseTCPLayer( char* cBuff ); void ParseUDPLayer( char* cBuff ); void ParseICMPLayer( char* cBuff ); int ParseIPLayer( char* cBuff ); int Sniffer( int nCount );
普通的情况下,网卡只接收和自己的地址有关的信息包,即传输到本地主机的信息包。 要使 Sniffer 能接收并处理这种方式的信息,系统需要支持 BPF,Linux 下需要支持 SOCKET 一 PACKET。但一般情况下,网络硬件和 TCP/IP 堆栈不支持接收或者发送与本地计算机无 关的数据包,所以,为了绕过标准的 TCP/IP 堆栈,网卡就必须设置为我们刚开始讲的混杂 模式。一般情况下,要激活这种方式,内核必须支持这种伪设备 Bpfilter,而且需要 root 权 限来运行这种程序,所以 sniffer 需要 root 身份安装,如果只是以本地用户的身份进入了系 统,那么不可能嗅探到 root 的密码,因此不能运行 Sniffer。
cout << "IP 高层协议类型:" << nIpHiType << " (ICMP)" << endl;
return HI_ICMP; case 2:
cout << "IP 高层协议类型:" << nIpHiType << " (IGMP)" << endl; return HI_IGMP; case 6: cout << "IP 高层协议类型:" << nIpHiType << " (TCP)" << endl; return HI_TCP; case 17: cout << "IP 高层协议类型:" << nIpHiType << " (UDP)" << endl; return HI_UDP; case 89: cout << "IP 高层协议类型:" << nIpHiType << " (OSPF)" << endl; return HI_OSPF; default: cout << "IP 高层协议类型:" << nIpHiType << " (未知的类型)" << endl; return HI_UNKNOW; } }
if (SOCKET_ERROR == nErr) return -1;
// 设置原始套接字 SIO_RCVALL 控制代码,以便接收所有的 IP 数据包,设置为混杂模 式
u_long ulMode = 1; nErr = ioctlsocket(SockRaw, SIO_RCVALL, &ulMode); //让 sockRaw 接受所有的数 据 if ( nErr == SOCKET_ERROR )
// 主程序 int main( int argc, char* argv[] ) {
Sniffer( CAP_MAX_PACKETS );
return EXIT_SUCCESS; }
// 创建原始套接字,并监听 int Sniffer( int nCount ) {
WSADATA wsaData; int nErr=0;
{ WSACleanup( ); return -1;
}
// 创建原始套接字对象 SOCKET SockRaw = socket( AF_INET, SOCK_RAW, IPPROTO_IP );//AF_INET tcp/ip 地 址类型,SOCK_RAW 原始 socekt
if( SockRaw == INVALID_SOCKET ) return -1;
cout << "目的 IP 地址:" << usIp1 << "." << usIp2 << "." << usIp3 << "." << usIp4 << " ";
memcpy( &nIpHiType, &cBuff[IP_HITYPE], sizeof(char) );
switch ( nIpHiType) { case 1:
cout << "*************** IP Layer ****************" << endl; cout << "源 IP 地址:" << usIp1 << "." << usIp2 << "." << usIp3 << "." << usIp4 << " ";
memcpy( &usIp1, &cBuff[IP_DADDR], sizeof(char) ); memcpy( &usIp2, &cBuff[IP_DADDR+1], sizeof(char) ); memcpy( &usIp3, &cBuff[IP_DADDR+2], sizeof(char) ); memcpy( &usIp4, &cBuff[IP_DADDR+3], sizeof(char) );
addr_in.sin_family
= AF_INET;
addr_in.sin_port
= INADDR_ANY;//监听 端口
addr_in.sin_addr.S_un.S_addr = ulLocaIP;//0 接收本地数据包
// 将原始套接字绑定到一个本地地址(不能为 ADDR_ANY) nErr = bind(SockRaw, (struct sockaddr*) &addr_in, sizeof(addr_in));//绑定本 机 ip 地址
break;Βιβλιοθήκη Baidu
}
cout
<<
"*****************************************************************************"
<< endl << endl;
}
// 关闭套接字 closesocket( SockRaw );
// 卸载 Winsock 库 WSACleanup(); return 0; }
也有基于无线网络、广域网络(DDN, FR)甚至光网络(POS、Fiber Channel)的监听技术, 这时候略微不同于以太网络上的捕获概念,其中通常会引入 TAP (测试介入点)这类的硬件设 备来进行数据采集。
监听目的
当一个黑客成功地攻陷了一台主机,并拿到了 root 权限,而且还想利用这台主机去 攻击同一(物理)网段上的其他主机时,他就会在这台主机上安装 Sniffer 软件,对以太网 设备上传送的数据包进行侦听,从而发现感兴趣的包。如果发现符合条件的包,就把它存到 一个 Log 文件中去。通常设置的这些条件是包含字“username”或“password”的包,这样的 包里面通常有黑客感兴趣的密码之类的东西。一旦黑客截获得了某台主机的密码,他就会立 刻进入这台主机。
continue;
cout << "捕获到第 " << n << " 个数据包" << endl; int nIpHeaderLen=0; memcpy( &nIpHeaderLen, cBuffRecv, sizeof(char) ); nIpHeaderLen = nIpHeaderLen & 0xF;
cout << "网络嗅探中......" << endl; for ( int n=1; n <= nCount; ++n ) {
//破获数据包 nErr = recvfrom( SockRaw, cBuffRecv, sizeof(cBuffRecv), 0, (struct sockaddr*)&addrFrom, &nLen ); if ( nErr == SOCKET_ERROR )
如果 Sniffer 运行在路由器上或有路由功能的主机上,就能对大量的数据进行监控,因 为所有进出网络的数据包都要经过路由器。
Sniffer 属于第 M 层次的攻击。就是说,只有在攻击者已经进入了目标系统的情况下, 才能使用 Sniffer 这种攻击手段,以便得到更多的信息。
Sniffer 除了能得到口令或用户名外,还能得到更多的其他信息,比如一个重要的信息、 在网上传送的金融信息等等。Sniffer 几乎能得到任何在以太网上传送的数据包。
// 获取本地主机名及 IP 地址 char host_name[256]; hostent *hp; in_addr sa; unsigned long ulLocaIP; gethostname( host_name, sizeof(host_name) );//本地主机名 hp = gethostbyname(host_name);//返回对应于给定主机名的主机信息,本地的 ip 地 址 if (hp != NULL) {
// 加载 WinsockDLL nErr = WSAStartup( MAKEWORD(2,2), &wsaData );//返回值是 0 表示成功 if ( nErr != 0 )
return -1;
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )// 判断版本号是否和定义的一样
// 解析数据包 switch( ParseIPLayer( cBuffRecv ) ) { case HI_ICMP:
ParseICMPLayer( &cBuffRecv[nIpHeaderLen*4] );//32 字节 break; case HI_TCP: ParseTCPLayer( &cBuffRecv[nIpHeaderLen*4] ); break; case HI_UDP: ParseUDPLayer( &cBuffRecv[nIpHeaderLen*4] );
// 解析 IP 层,获得上层协议类型 int ParseIPLayer( 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+1], sizeof(char) ); memcpy( &usIp3, &cBuff[IP_SADDR+2], sizeof(char) ); memcpy( &usIp4, &cBuff[IP_SADDR+3], sizeof(char) );
return -1;
// 开始接收网络数据包,进入循环 char cBuffRecv[ 5120 ]; memset( cBuffRecv, 0, sizeof(cBuffRecv) );//用 0 初始化
SOCKADDR_IN addrFrom; int nLen = sizeof(SOCKADDR);
Sniffer 实验报告
学号:041040101 姓名: 张倩
实验目的:
熟悉并实现网络监听的基本原理
sniffer 原理:Sniffer 程序是一种利用以太网的特性把网络适配卡(NIC,一般为以
太网卡)置为杂乱(promiscuous)模式状态的工具,一旦网卡设置为这种模式,它就能接 收传输在网络上的每一个信息包。