TCP端口的高级扫描方法及实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

表 1 目标主机不同设
置情况下的扫描结果
1.引言
由于每一个端口都对应了相应的服务, 支持 IP_HDRINCL 选项的设置。

扫描程序界面如图 1 所示。

TCP Connect()扫描由于不需 要 使 用 原 始 套 接 字 实 现 , 需
单 独构造一个扫描线程实现, 其扫描数据包的发送过程为: 声明一 个套接字, 设置套接字选项, 设置套接字为非阻塞, 调用 connect 所以某一端口开放 也就意味着其对应的服务也在运行。

利用端口扫描的结果, 我们 可以掌握主机的运行状况, 帮助我们判断有没有后门程序在运 行, 关闭不需要的服务等提供条件。

当然, 黑客通过端口扫描也 可以发现系统的弱点, 为进一步进行攻击提供条件。

本文使用 V C6.0 作为编程工具, 在 Windows2000 平台下, 使 用 Windows 原始套接字实现带有特殊标志字段数据包的产生、 发送, 并实现对目标主机响应数据包的嗅探。

利用数据包嗅探过 程分析俘获到的响应数据包, 得到 TCP 数据单元头部的六个 1 位标志字段的内容。

通过对已知目标主机的端口状态及其响应 的分析, 进而得到一些规律, 应用这些规律可以进一步帮助我们
判断目标主机端口是否开放。

2. TCP 端口扫描原理 2.1 TCP 实现原理 函数。

该扫描过程主要应用了 TCP Connect () 函数实现, connect 函数返回值判断目标端口是否开放。

根据 原始套接字扫描是一种比较复杂的扫描过程, 需要手动设 置 TCP 和 IP 的 头 部 字 段 。

Windows 系
统 下 Windows2000 或 WindowsXP/S erver 2003 支持原始套接字。

构造并发送原始套接 字扫描过程如下: 声明一个原始套接字, 设置 IP_HDRINCL 选项 以构造 TCP 和 IP 的头部字段, 填充套接字 IP 首部( 在这里将目 标主机 IP 填入) , 填充 TCP 首部( 在这里将目标主机端口填入) , 计算校验和, 发送数据包。

侦 听 线 程 的 作 用 是 抓 取 并 分 析 来 自 目 标 主 机 响 应 的 数 据
包 , 并
将 结 果 输 出 到 用 户 界 TCP 协议数据单元的头部有六个 1 位字段, 分别是 UR G 、 面。

其过程如下: 声明一个原 始套接字, 设置套接字选项,
将 本 地 IP 和 端 口 绑 定 到 该 套 接 字 , 使 用 WS AIoctl 设 置
S IO_RCV ALL 接 收 所 有 的 数 据包, 启动一个死循环来不断
分析接收到的数据包。

在该死 ACK 、PS H 、RS T 、S Y N 和 FIN 字段。

这六个字段对连接的建立与 管理有十分重要的作用。

目 前 常 用 的 TCP 端 口 扫 描 方 法 为 TCP Connect () 扫 描 和 TCP S Y N 扫描。

TCP Connect()扫描: 这是最基本的 TCP 扫描。

操作系统提供 的 connect()系统调用, 用来与每一个感兴趣的目标计算机 的 端 口进行连接。

如果端口处于侦听状态, 那么 connect()就能成功。

否则, 这个端口是不能用的, 即没有提供服务。

TCP SY N 扫 描 : 首 先 客 户 端 ( 请 求 方 ) 在 连 接 请 求 中 , 发
送 SY N=1, ACK=0 的 TCP 数
据 包 给 服 务 器 端 ( 接 收 请 求 端 ) , 表 示 循 环 中 , 对 于 接 收 到 的 数 据 包, 判断是不是远程开放端口 图 1 扫描程序界面 返回的数据包, 如果是, 则分析并输出其 ACK 、RS T 、S Y N 、FIN 字 段的值。

4. 扫描结果
使用扫描程序, 对一目标主机进行扫描。

目标主机不同设置 情况下的扫描结果见表 1 所示。

从扫描结果可以看出: 1. 如果目标主机端口没有防火墙保护, Connect()扫描和 S yn 扫描都可以判断目标主机的端口是否打开; 2. 如果目标主机防火墙打 开 , 使 用 常 用 的 Connect()扫 描 和 S yn 扫描, 目标主机没有任何数据包返回, 让人会以为目标主机
不 存 在 。

这 时 可 以 使 用 Ack 扫 描 、Fin 扫
描 或 者 Null 扫描方 式 , 如
果 目 标 主机存在, 则就会有数据 包返回。

但这时并不能判
断 所 扫 描 的 目 标 端 口 是
否打开( 原因: 表 3 与表 4 结果相同) , 也就不 能 判
断 目 标 主 机 是 否 运 行 有 相应的服务进程; 3. 主 机 端 口 虽 然 关 闭 , 但
使 用 Connect() 扫 描 和 S yn 扫 描 都 能 判 ( 下转第 153 页)
要求同服务器端建立一个连接; 然后如果服务器端响应这个连
接, 就返回一个 S Y N=1, ACK=1 的数据包给客户端, 表示服务器
端 同 意 这 个 连 接 , 并 要 求 客 户 端 确 认 ; 最
后 客 户 端 就 再 发 送 SY N=0, ACK=1 的数据包给服务器端, 表示确认建立连接。

以上两种扫描方式比较常用, 除此之外, 还有其它的一些扫 描 方 法 , 包 括 : TCP ACK 扫 描 , TCP FIN 扫 描 , TCP NULL 扫
描 等。

其中, TCP ACK 扫描方法是向目标主机的端口发送一个标
志字段 ACK 为 1 的数据包, TCP FIN 扫描方法是向目标主机的 端 口 发 送 一 个 标 志 字 段 FIN 为 1 的 数 据 包 , TCP NULL 扫 描 是 向目标主机的端口发送一个所有标志字段为 0 的数据包。

2.2 响应数据包 TCP 报文段头部标志
TCP 端口扫描响应数据包的 TCP 报文段头部字段中, URG
和 PS H 这两个字段基本不会被使用到, 其余的四个字段 ACK 、
RS T 、S Y N 和 FIN 字段都有可能会被用到。

所以, 扫描主机的嗅 探过程通过俘获来自被扫描主机的响应数据包, 并抓取 ACK 、 RS T 、S Y N 和 FIN 字段, 从而得到被扫描主机的响应方式。

3. 端口扫描的程序设计及实现
本扫描程序的设计及实现是在 Windows2000 server 操作系 统 平 台 下 , 使 用 Microsoft V isual C++6.0 开 发 实 现 的 , 该
程 序 的 设计实现采用了 Windows 原始套接字技术, 需要使用 Ws2_32. lib 库和 Winsock 头文件 winsock2.h , 还需要 WS 2TCPIP.h 头文件
是重置变量MouseDownPoint 值并解除捕捉鼠标,下:
void COp en gl Vi ew::On LBu tt on Up(UI NT nFlags, CPoint point) {
MouseDownPoint=CPoint(0,0); //鼠标按下位置置于原点具体代码如
HDC hDC=::GetDC(hWnd); WglMakeCurrent(hDC,m_hglrc); drawscene(); //绘制图形wglMakeCurrent(NULL,NULL); SwapBu ffers(hDC); //交换缓存
}
( 5) 修改Co peng lView 类中的OnSize()函数, 其作用是在窗口大小发生变化时, 相应的改变视口大小和投影变换方式, 将场景中的物体正确地显示于窗口当中, 具体代码如下:
void COp en gl Vi ew::On Si ze(UI NT n T ype, int cx, int cy)
{
CV iew::OnSize(nT ype, cx, cy);
if ( 0 < cx && 0 < cy )
{
GLsizei w=cx;
Glsizei h=cy;
ReleaseCapture();
}
// 解除捕捉鼠标
(3) 在COpenglView 类中添加OnMouseMove ()函数, 其作用是计算当按下左键拖动鼠标时旋转对象的一个步长, 具体代码如下:
void COp en gl Vi ew::On Mous eMove(UI NT nFlags, CPoint point)
{
// 检测是否捕捉鼠标
if (GetCapture()==this)
{
X_An gl e+=d oub l e(p oin t.y- MouseDownPoint.y)/3.6;
Y_An gl e+=d oub l e(p oin t.x- MouseDownPoint.x)/3.6;
// 旋转对象一个步长
// 设置视口变换
glV iewport(0,0,w,h);
glMatrix Mode(GL_PROJECT ION); // 设置透视变换
glLoadIdentity();
glMatrix Mode(GL_MODELV IEW); glLoadIdentity();
Invalidate(T RUE);// 更新场景
MouseDownPoint=point; // 记下鼠标位置
};
}
(4) 进一步修改COpenglView 类中的drawscene()函数, 以完成旋转操作, 具体代码如下:
void COpenglV iew::drawscene()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotated(X_Angle,1.0,0.0,0.0);
glRotated(Y_Angle,0.0,1.0,0.0);
// 旋转对象一个给定的角度
///////////////////////////////
//绘制图形具体代码
//////////////////////////////
glPopMatrix();
glFlush();
}
4. 结束语
本文从实用角度出发, 详细介绍了利用V isual C++和OpenGL 如何实现单文档交互式可视化程序的基本框架及人工交互功能, 并且给出了具体的代码。

对于程序的后续开发, 只需要在函数drawscene()中添加相应的代码即可。

};
}
( 6) 在COpenglView 类中添加draw scene()函数, 其作用是完成主要的绘图操作, 具体代码如下
void COpenglV iew::drawscene()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
//绘制图形具体代码
glFlush();
}
3. 交互模块设计
3.1 添加成员变量:
义如下:
private:
f loat X_Angle;
f loat Y_Angle;
CPoint MouseDownPoint;
在COpenglView 类中添加成员变量, 定
3.2 初始化成员变量。

在COpenglView 类的构造函数中对成员变量进行初始化, 具体代码如下:
COpenglV iew::COpenglV iew()
{
//初始化成员变量
X_Angle=0.0; Y_Angle=0.0;
MouseDownPoint=CPoint(0,0);
}
3.3 修改相关函数。

(1) 在CO peng lView 类中添加OnLButtonDown ()函数,其作用是记录按下鼠标左键时鼠标的坐标并捕捉鼠标, 具体代码如下:
void COp en gl Vi ew::On LBu tt on Do wn(UI NT nFlags, CPoint po int)
{
MouseDownPoint=point; // 记录鼠标的位置
SetCapture(); // 捕捉鼠标的运动
}
(2) 在CO peng lView 类中添加OnLButtonUp ()函数, 其作用
参考文献:
1. 向世明.O penGL 编程与实例[M].北京: 电子工业出版社, 1999.
2. 和平鸽工作室.O penGL 高级编程与可视化系统开发[EM]. E 京: 中国水利水电出版社, 2002.
3. 张俊霞.三维地形可视化及其实时显示方法概述[J].北京测绘, 2001, (6): 91.
4. 百建军, 朱亚平等.O penGL 三维图形设计与制作[M]. 北京: 人民邮电出版社, 1999.
5. 侯俊杰.深入浅出MF C[M].湖北: 华中科技大学出版社(第2版).2001.
( 上接第180 页)
断该主机的存在,如果返回数据包的ack=1, rst=1, 则意味者目判断的辅助工具, 也可为深入理解TCP 协议的工作过程创造了
条件。

标主机没有使用防火墙对该端口的屏蔽策略,
闭状态, 目标主机没有相应服务进程运行;
且该端口处于关
4. 在以上所有情况下, Ack 扫描、Fin 扫描或者Null 扫描方式得到的扫描结果都是一样的, 也就是说, 这三种特殊的扫描方式不能判断目标端口是否打开, 只能判断目标主机是否存在。

5. 结论
通过分析TCP 协议的头部字段, 利用Winsock 原始套接字
参考文献:
1. ( 美) W. R ichard S tevens 著, 范建华等译. T CP/ IP 详解[M]. 北京, 机械工业出版社, 2000.4
2. ( 美) Jeff S chmid t 著, 詹文军等译.W ind ows2000 安全手册[M].北京, 电子工业出版社, 2001.7
3. 孙海峰等. 浅议TCP S YN Flooding 攻击[J]. 计算机与现代化, 2004 ( 6) : 28~29
和V isual C++6.0 实现的主机端口扫描程序,经过实际测试运。

相关文档
最新文档