通行证: 用户 密码 域名空间  下载中心 社区论坛 信息公告 my小屋
联系我们
设为首页
加入收藏

 

qq,asp,php,jsp,xml,sql,.net,编程 程序 网页图象 建站经验 私服
首页 | 新闻资讯 | 编程开发 | 网页设计 | 图形图象 | 网络媒体 | 网站模板 | 数 据 库 | 投稿
论坛 | 操作系统 | 系统优化 | 网络安全 | 黑客技术 | 硬件学堂 | 硬件报价 | 服 务 器 | 地图
专题 | 应用软件 | 聊天通讯 | q q 专栏 | 建站经验 | 在线工具 | 站长club | 注 册 表 | 旧版
社会 | 游戏娱乐 | 设计欣赏 | 疑难解答 | 社区论坛 | 韩国素材 | 素材图库 | 广告服务 | 服务
当前位置:首页>>网络安全>>安全工具>>正文 新版上线![旧版]
注:打开慢时请稍等

raw socket(原始套接字)实现sniffer(嗅探)

http://www.iyit.net  日期:2006-5-29 13:37:23  来源:网络转载   点击:
参加讨论

一. 摘要

raw socket: 原始套接字

可以用它来发送和接收 ip 层以上的原始数据包, 如 icmp, tcp, udp...

int sockraw = socket(af_inet, sock_raw, ipproto_raw);

这样我们就创建了一个 raw socket

sniffer: 嗅探器

关于嗅探器的原理我想大多数人可能都知道

1. 把网卡置于混杂模式;

2. 捕获数据包;

3. 分析数据包.

但具体的实现知道的人恐怕就不是那么多了. 好, 现在让我们用 raw socket 的做一个自已的 sniffer.

二. 把网卡置于混杂模式

在正常的情况下,一个网络接口应该只响应两种数据帧:

一种是与自己硬件地址相匹配的数据帧

一种是发向所有机器的广播数据帧

如果要网卡接收所有通过它的数据, 而不管是不是发给它的, 那么必须把网卡置于混杂模式. 也就是说让它的思维混乱, 不按正常的方式工作. 用 raw socket 实现代码如下:

setsockopt(sock, ipproto_ip, ip_hdrincl, (char*)&flag, sizeof(flag); //设置 ip 头操作选项

bind(sockraw, (psockaddr)&addrlocal, sizeof(addrlocal); //把 sockraw 绑定到本地网卡上

ioctlsocket(sockraw, sio_rcvall, &dwvalue);       //让 sockraw 接受所有的数据

flag 标志是用来设置 ip 头操作的, 也就是说要亲自处理 ip 头: bool flag = ture;

addrlocal 为本地地址: sockaddr_in addrlocal;

dwvalue 为输入输出参数, 为 1 时执行, 0 时取消: dword dwvalue = 1;

没想到这么简单吧?

三. 捕获数据包

你的 sockraw 现在已经在工作了, 可以在局域网内其它的电脑上用 sniffer 检测工具检测一下, 看你的网卡是否处于混杂模式(比如 digitalbrain 的 arpkiller).

不能让他白白的浪费资源啊, 抓包!

recv(sockraw, recvbuf, buffer_size, 0); //接受任意数据包

#define buffer_size 65535

char recvbuf[buffer_size];

越来越发现 sniffer 原来如此的简单了, 这么一个函数就已经完成抓取数据包的任务了.

四. 分析数据包

这回抓来的包和平常用 socket 接受的包可就不是一回事儿了, 里面包含 ip, tcp 等原始信息. 要分析它首先得知道这些结构.

数据包的总体结构:

----------------------------------------------

| ip header | tcp header(or x header) | data |

----------------------------------------------

ip header structure:

4    8    16                    32 bit

|--------|--------|----------------|--------------------------------|

| ver  | ihl  |type of service |     total length     |

|--------|--------|----------------|--------------------------------|

| identification |   flags   |     fragment offset    |

|--------|--------|----------------|--------------------------------|

| time to live  |  protocol  |     header checksum    |

|--------|--------|----------------|--------------------------------|

|             source address              |

|--------|--------|----------------|--------------------------------|

|            destination address             |

|--------|--------|----------------|--------------------------------|

|            option + padding              |

|--------|--------|----------------|--------------------------------|

|                data                |

|--------|--------|----------------|--------------------------------|

tcp header structure:

16                32 bit

|--------------------------------|--------------------------------|

|     source port      |    destination port    |

|--------------------------------|--------------------------------|

|             sequence number             |

|--------------------------------|--------------------------------|

|           acknowledgement number           |

|--------------------------------|--------------------------------|

| offset | resrvd |u|a|p|r|s|f|      window       |

|--------------------------------|--------------------------------|

|      checksum       |    urgent pointer     |

|--------------------------------|--------------------------------|

|             option + padding            |

|--------------------------------|--------------------------------|

|               data                |

|--------------------------------|--------------------------------|

五. 实现 sniffer

ok!

现在都清楚了, 还等什么.

下面是我用 bcb6 写的一个 simple sniffer 的代码, 仅供参考.

(需要在工程文件里加入ws2_32.lib这个文件)

//*************************************************************************//

//* cpp file: wmain.cpp

//* simple sniffer by shadowstar

//* http://shadowstar.126.com/

//*************************************************************************//

#include <vcl.h>

#pragma hdrstop

#include <winsock2.h>

#include <ws2tcpip.h>

#include <mstcpip.h>

#include <netmon.h>

#include "wmain.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

tmainform *mainform;

//---------------------------------------------------------------------------

__fastcall tmainform::tmainform(tcomponent* owner)

: tform(owner)

{

wsadata wsadata;

bool  flag  = true;

int   ntimeout = 1000;

char  localname[16];

struct hostent *phost;

//检查 winsock 版本号

if (wsastartup(makeword(2, 2), &wsadata) != 0)

throw exception("wsastartup error!");

//初始化 raw socket

if ((sock = socket(af_inet, sock_raw, ipproto_raw)) == invalid_socket)

throw exception("socket setup error!");

//设置ip头操作选项

if (setsockopt(sock, ipproto_ip, ip_hdrincl, (char*)&flag, sizeof(flag)) == socket_error)

throw exception("setsockopt ip_hdrincl error!");

//获取本机名

if (gethostname((char*)localname, sizeof(localname)-1) == socket_error)

throw exception("gethostname error!");

//获取本地 ip 地址

if ((phost = gethostbyname((char*)localname)) == null)

throw exception("gethostbyname error!");

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 绑定到本地地址上

if (bind(sock, (psockaddr)&addr_in, sizeof(addr_in)) == socket_error)

throw exception("bind error!");

isortdirection = 1;

}

//---------------------------------------------------------------------------

__fastcall tmainform::~tmainform()

{

wsacleanup();

}

//---------------------------------------------------------------------------

void __fastcall tmainform::btnctrlclick(tobject *sender)

{

tlistitem *item;

dword dwvalue;

int nindex = 0;

if (btnctrl->caption == "&start")

{

dwvalue = 1;

//设置 sock_raw 为sio_rcvall,以便接收所有的ip包

if (ioctlsocket(sock, sio_rcvall, &dwvalue) != 0)

throw exception("ioctlsocket sio_rcvall error!");

bstop = false;

btnctrl->caption = "&stop";

lsvpacket->items->clear();

}

else

{

dwvalue = 0;

bstop = true;

btnctrl->caption = "&start";

//设置sock_raw为sio_rcvall,停止接收

if (ioctlsocket(sock, sio_rcvall, &dwvalue) != 0)

throw exception("wsaioctl sio_rcvall error!");

}

while (!bstop)

{

if (recv(sock, recvbuf, buffer_size, 0) > 0)

{

nindex++;



ip = *(ip*)recvbuf;

tcp = *(tcp*)(recvbuf + (ip.hdrlen & ip_hdrlen_mask));

item = lsvpacket->items->add();

item->caption = nindex;

item->subitems->add(getprotocoltxt(ip.protocol));

item->subitems->add(inet_ntoa(*(in_addr*)&ip.srcaddr));

item->subitems->add(inet_ntoa(*(in_addr*)&ip.dstaddr));

item->subitems->add(tcp.srcport);

item->subitems->add(tcp.dstport);

item->subitems->add(ntohs(ip.totallen));

}

application->processmessages();

}  

}

//---------------------------------------------------------------------------

ansistring __fastcall tmainform::getprotocoltxt(int protocol)

{

switch (protocol)

{

case ipproto_icmp :      //1        /* control message protocol */

return protocol_string_icmp_txt;

case ipproto_tcp :      //6        /* tcp */

return protocol_string_tcp_txt;

case ipproto_udp :      //17       /* user datagram protocol */

return protocol_string_udp_txt;

default :

return protocol_string_unknown_txt;

}

}

//---------------------------------------------------------------------------



//*************************************************************************//

//* header file: wmain.h for wmain.cpp class tmainform

//*************************************************************************//

//---------------------------------------------------------------------------

#ifndef wmainh

#define wmainh

//---------------------------------------------------------------------------

#define buffer_size 65535

#include <classes.hpp>

#include <controls.hpp>

#include <stdctrls.hpp>

#include <forms.hpp>

#include <comctrls.hpp>

#include <extctrls.hpp>

#include <winsock2.h>

#include "netmon.h"



//---------------------------------------------------------------------------

class tmainform : public tform

{

__published: // ide-managed components

tpanel *panel1;

tbutton *btnctrl;

tlistview *lsvpacket;

tlabel *label1;

void __fastcall btnctrlclick(tobject *sender);

void __fastcall lsvpacketcolumnclick(tobject *sender,

tlistcolumn *column);

void __fastcall lsvpacketcompare(tobject *sender, tlistitem *item1,

tlistitem *item2, int data, int &compare);

void __fastcall label1click(tobject *sender);

rivate: // user declarations

ansistring __fastcall getprotocoltxt(int protocol);

ublic: // user declarations

socket   sock;

sockaddr_in addr_in;

ip     ip;

tcp     tcp;

psuhdr   psdheader;

char    recvbuf[buffer_size];

bool    bstop;

int isortdirection;

int icolumntosort;



__fastcall tmainform(tcomponent* owner);

__fastcall ~tmainform();

};

//---------------------------------------------------------------------------

extern package tmainform *mainform;

//---------------------------------------------------------------------------

#endif

偷了个懒, ip, tcp 头及一些宏定义用了 netmon.h 的头, 这个文件在 bcb6 的 include 目录下可以找得到, 其中与本程序相关内容如下:

//*************************************************************************//

//* header file: netmon.h

//*************************************************************************//

//

// ip packet structure

//

typedef struct _ip

{

union

{

byte  version;

byte  hdrlen;

};

byte servicetype;

word totallen;

word id;

union

{

word  flags;

word  fragoff;

};

byte timetolive;

byte protocol;

word hdrchksum;

dword  srcaddr;

dword  dstaddr;

byte options[0];

} ip;

typedef ip * lpip;

typedef ip unaligned * ulpip;

//

// tcp packet structure

//

typedef struct _tcp

{

word srcport;

word dstport;

dword seqnum;

dword acknum;

byte dataoff;

byte flags;

word window;

word chksum;

word urgptr;

} tcp;

typedef tcp *lptcp;

typedef tcp unaligned * ulptcp;

// upper protocols

#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"



这个文件也有人声称没有.

//*************************************************************************//

//* header file: mstcpip.h

//*************************************************************************//

// copyright (c) microsoft corporation. all rights reserved.

#if _msc_ver > 1000

#pragma once

#endif

/* argument structure for sio_keepalive_vals */

truct tcp_keepalive {

u_long onoff;

u_long keepalivetime;

u_long keepaliveinterval;

};

// new wsaioctl options

#define sio_rcvall      _wsaiow(ioc_vendor,1)

#define sio_rcvall_mcast   _wsaiow(ioc_vendor,2)

#define sio_rcvall_igmpmcast _wsaiow(ioc_vendor,3)

#define sio_keepalive_vals  _wsaiow(ioc_vendor,4)

#define sio_absorb_rtralert  _wsaiow(ioc_vendor,5)

#define sio_ucast_if     _wsaiow(ioc_vendor,6)

#define sio_limit_broadcasts _wsaiow(ioc_vendor,7)

#define sio_index_bind    _wsaiow(ioc_vendor,8)

#define sio_index_mcastif   _wsaiow(ioc_vendor,9)

#define sio_index_add_mcast  _wsaiow(ioc_vendor,10)

#define sio_index_del_mcast  _wsaiow(ioc_vendor,11)

// values for use with sio_rcvall* options

#define rcvall_off       0

#define rcvall_on       1

#define rcvall_socketlevelonly 2

现在我们自已的 sniffer 就做好了, run, start......哇, 这么多数据包, 都是从这一台机器上发出的, 它在干什么? 原来 adminstrator 密码为空, 中了尼姆达病毒!

六. 小结

优点: 实现简单, 不需要做驱动程序就可实现抓包.

缺点: 数据包头不含帧信息, 不能接收到与 ip 同层的其它数据包, 如 arp, rarp...

这里提供的程序仅仅是一个 sniffer 的例子, 没有对数据包进行进一步的分析. 写此文的目的在于熟悉raw socket 编程方法, 了解 tcp/ip 协议结构原理以及各协议之间的关系.




编辑:黑鹰 [发送给好友] [打印本页] [关闭窗口] [返回顶部]
上一篇:用sniffer透视动态域名
下一篇:黑客可以利用的5款远程控制软件测试
转载请注明来源:www.iyit.net
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。

 相关文章
最新更新 热点排行 推荐新闻
实战系统虚拟利器——ms vpc 2004
杀毒软件升级病毒库的备份与恢复 
强强联手 打造能自动查杀毒的超酷平台
黑客可以利用的5款远程控制软件测试
raw socket(原始套接字)实现sniffer
实战系统虚拟利器——ms vpc 2004
杀毒软件升级病毒库的备份与恢复 
强强联手 打造能自动查杀毒的超酷平台
黑客可以利用的5款远程控制软件测试
raw socket(原始套接字)实现sniffer
用sniffer透视动态域名
sniffer帮助理解子网掩码、网关与arp协
sniffer帮助理解nat(win2000)
再议 sniffer
用sniffer分析nat和变长子网掩码
实战系统虚拟利器——ms vpc 2004
杀毒软件升级病毒库的备份与恢复 
强强联手 打造能自动查杀毒的超酷平台
黑客可以利用的5款远程控制软件测试
raw socket(原始套接字)实现sniffer
优秀公益广告作品欣赏(8)
java数据类型转换
windows xp专业版iis连接数的更改
新开放qq免费挂级网站
优秀公益广告作品欣赏(7)
免费在qq上看在线电影电视听音乐
qq最新版下载 2006 beta2 体验新感受 
office2007简体中文版浮出水面 美图抢
qq珊瑚虫外挂4.0版本发布!
免费把qq炫铃设为本机qq的系统提示音
传统计算机病毒传播能力破坏性在提高
内存为何有“两面性”
amd水货盒装cpu识别方法
ip地址资源2012年枯竭 部署ipv6很紧迫
古老问题有新解:世上先有鸡蛋后有鸡
dreamweaver mx 2004从零开始(1)
利用css改善网站可访问性
如何让mm的脸通透可人
msn8.0下载
asp 五大高效提速技巧
 友情链接
设置首 页 - 版权声明 - 广告服务 - 关于我们 - 联系我们 - 友情连接
copyrights © 2004-2006 iyit.net all rights reserved.
网站合作、广告联系qq:147007642、466949678
易特网络技术 点击这里给我发消息