1-编写一个端口扫描器

本文介绍如何使用Python编写一个TCP全连接扫描器,包括TCP连接扫描、抓取应用Banner和线程扫描。通过创建套接字并利用Python的BSD套接字API,可以实现端口扫描和识别主机开放的端口。此外,文章还提到了NMAP端口扫描工具,讨论了如何在Python中集成Nmap进行更复杂的扫描操作。
摘要由CSDN通过智能技术生成

源代码:https://github.com/LToddy/penetrationtest

任何一个靠谱的网络攻击都是起步于侦察的。
攻击者必须在挑选并确定利用目标中的漏洞之前找到目标在哪里有漏洞。
编写一个扫描目标主机开放的TCP端口的侦察小脚本。
为了与TCP端口进行交互,我们要先建立TCP套接字。

Python提供了BSD套接字的接口。
BSD套接字提供了一个应用编程接口,使程序员能编写在主机之间进行网络通信的应用程序。
通过一系列套接字API函数,我们可以创建、绑定监听、连接,或在TCP/IP套接字上发送数据。

大多数能访问互联网的应用使用的都是TCP协议。
例如,在目标组织中,Web服务器可能位于TCP80端口,电子邮件服务器在TCP25端口,FTP服务器在TCP21端口。
要连接目标组织中的任一服务器,攻击者必须知道与服务器相关联的IP地址和TCP端口。

所有成功的网络攻击一般都是从端口扫描来开序幕的。
有一种类型的端口扫描会向一系列常用的端口发送TCP SYN数据包,并等待TCP ACK响应——这能让我们确定这个端口是开放的。
与此相反,TCP连接扫描是使用完整的三次握手来确定服务器或端口是否可用的。

TCP全连接扫描

开始编写自己用的TCP全连接扫描来识别主机的TCP端口扫描器。
要导入Python的BSD套接字API实现。
套接字API会为我们提供一些在实现TCP端口扫描程序时有用的函数。
要深入的了解请查看文档.

为了更好的了解TCP端口扫描器的工作原理,我们将脚本分成五个独立的步骤,分别为它们编写Python代码。
首先输入一个主机名和用逗号分割的端口列表,并予以扫描。
接下来将主机转换成IPv4互联网地址。对列表中的每个端口,我们都会链接目标地址和该端口。
最后,为了确定在该端口上运行什么服务,我们将发送垃圾数据并读取由具体应用发回的Banner。

在第一步中,从用户那里获得主机名和端口。
为了做到这一点,我们在程序中使用optparse库解析命令行参数。
调用optparse.OptionParser([usage message])会生成一个参数解析器(option parser)类的实例。
接着,在parser.add_option中指定这个脚本具体要解析哪个命令行参数。

e.g. 一个快速解析要扫描的目标主机名和端口的方法

import optparse

parser = optparse.OptionParser('usage %prog -H <target host> -p <target port>')
parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', help='specify target port')

(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPort = options.tgtPort
if tgtHost == None or tgtPort == None:
    print(parser.usage)
    exit(0)
else:
    print(tgtHost)
    print(tgtPort)

接下来我么要生成俩个个函数: connScan和portScan.
portScan函数以参数的形式接受主机名和目标端口列表。
它首先会尝试用gethostbyname()函数确定主机名对应的IP地址。
接下来,它会使用connScan函数输出主机名字(或IP地址),并使用connScan()函数尝试逐个连接我们要连接的每个端口。
connScan函数接受两个参数:tgtHost和tgtPort,它会去尝试建立与目标主机端口的连接。
如果成功,connScan将打印出一个端口开放的消息。如果不成功,它会打印出端口关闭的消息。

from socket import *


def connScan(tgtHost, tgtPort):
    try:
        connSkt = socket(AF_INET, SOCK_STREAM)
        connSkt.connect((tgtHost, tgtPort))
        print('[+] %d/tcp open' % tgtPort)
        connSkt.close()
    except Exception:
        print('
端口扫描软件的代码在网上很多,可是并不一定适合基础不深的鸟鸟们学。要不就是代码大多都很长而且使用了多线程(关于多线程的很多概念就够闹腾的了,扫描部分就更算了),让我等小菜都望而生畏;要不就是速度很慢,学会了也派不上用场。今天我就介绍一下自己学习winsock后写的端口扫描软件吧! 端口扫描软件的基本思路就不说了,没有什么很难的算法,大家想想就应该知道的,只要从起始端口到结尾端口都遍历一遍,找到打开的端口输出就可以了。大体的就是这个样子:for(CurrPort=StartPort;CurrPort<=EndPort;CurrPort++) {scan的执行体; }。这个软件没有使用到多线程技术,也就不用考虑那么多的关于多线程的概念了。因此我们的这个扫描软件从两个方面来讨论,第一方面是如何可以找到打开的端口,第二方面是如何提高扫描端口的速度。 一、找到打开的端口 在介绍如何找到打开的端口以前,让我们先来认识一个函数——connect()。connect函数将一个流套接字连接到指定IP地址的指定端口上。connect函数的用法:int connect(SOCKET s,const struct sockaddr FAR* name,int namelen);参数s指定用于连接的套接字句柄,name参数指向一个sockaddr_in结构,用来指定要连接到的服务的IP地址和端口,namelen参数则指定sockaddr_in结构的长度。这个参数连接成功的时候,函数返回0,否则返回值是SOCKET_ERROR。connect函数的用法大体我们就说这么多了。说到这里大家应该想到了吧?我们用connect函数的返回值进行判断,找到打开的端口号。好,看下具体的代码,有详细的注释,如果对函数不明白可以到MSDN或网上查询。 int scan(char *Ip, int StartPort, int EndPort) { clock_t StartTime,EndTime; //扫描的开始时间和结束时间 float CostTime; //扫描过程中耗费的时间 WSADATA wsa; SOCKET s; struct sockaddr_in server; int CurrPort; //当前端口 int ret; WSAStartup(MAKEWORD(2,2),&wsa); //使用winsock函数之前,必须用WSAStartup函数来装入并初始化动态连接库 server.sin_family=AF_INET; //指定地址格式,在winsock中只能使用AF_INET server.sin_addr.s_addr=inet_addr(Ip); //指定被扫描的IP地址 StartTime=clock(); for(CurrPort=StartPort;CurrPort<=EndPort;CurrPort++) { s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //创建套接字 /* SOCKET socket(int af,int type,int protocol); 为通信连接创建一个套接字 af参数: 指定套接字地址格式,在winsock中只能使用AF_INET type参数: 套接字类型,这里使用了SOCK_STREAM,流套接字 protocol参数:配合type使用,指定协议类型,这里使用IPPROTO_TCP(就是TCP协议) */ server.sin_port=htons(CurrPort); //指定被扫描IP地址的端口号 ret=connect(s,(struct sockaddr *)&server,sizeof(server)); //连接 if(0==ret) //判断连接是否成功 { printf("%s:%d\n",Ip,CurrPort); closesocket(s); } } EndTime=clock(); CostTime=(float)(EndTime-StartTime)/CLOCKS_PER_SEC; printf("Cost time:%f second\n",CostTime); //输出扫描过程中耗费的时间 WSACleanup(); //释放动态连接库并释放被创建的套接字 return 1; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值