网络攻防学习 1编写一个端口扫描器

本文介绍了一个初级的TCP端口扫描器的实现方法,利用Python编写,通过套接字与目标主机通信,扫描开放的TCP端口及其上运行的服务。文章详细展示了如何使用optparse模块解析命令行参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

谨以此文献给初学的自己!

我有太多的名词不认识通过学习 一步步巩固基础 一步步提高自己r

任何一个靠谱的网络攻击都是起步于侦查的。我们将学习编写一个扫描主机开放的tcp端口的侦察小脚本,为了与tcp端交互,我们先建立TCP套接字。

套接字:

英文名字为socket, 是支持TCP/IP网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

书写一个初级的端口扫描器,从而学习了optparse的用法,optparse可用来解析命令行参数 来传递指令来实现交互

 

import optparse
from optparse import OptionParser
import socket
from socket import *
#去测试目标主机的那个端口是开放的,并且开放的端口的活动应用是什么
def connScan(tgtHost,tgtPort):
    try:
        connSkt=socket.socket(AF_INET,SOCK_STREAM)
        connSkt.connect((tgtHost,tgtPort))
        #我们需要发送一个消息去获得一个响应,从而根据这个响应 我们来判断对应的目标主机和端口上的应用
        connSkt.send("ViolentPython\r\n")
        results=connSkt.recv(1024)
        #标明端口开放
        print ("[+]%d/tcp open")% tgtPort
        #输出返回的结果
        print ("[+]"+str(results))
        connSkt.close()
    except:
        print ("[-]%d/tcp closed"% tgtPort)
def portScan(tgtHost,tgtPorts):
    #其实我我觉得这两个try就是为了测试tgtHost的准确性
    try:
        #传入一个主机名字会返回其对应得IP地址
        tgtIP=gethostbyname(tgtHost)
    except:
        print ("[-] cannot resolve '%s': unkown host"%tgtHost)
        return
    try:
        #根据IP能返回其对应的主机名字
        tgtName=gethostbyaddr(tgtIP)
        #返回扫描的结果
        print ("\n[+] Scan Results for:" +tgtName[0])
    except:
        print ("\n[+] Scan Results for :"+tgtIP)
    #设置全局的socket超出时间1秒
    setdefaulttimeout(1)
    for tgtPort in tgtPorts:
        print ("Scanning Port%s "%tgtPort)
        connScan(tgtHost,int(tgtPort))

def main():
#生成一个参数解释器的实例
    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="int",help="specify target port[s] separeted by comma")
    #parse_args 来用来解析这些参数
    (options,args)=parser.parse_args()

    tgtHost=options.tgtHost
    #端口不止一个 所以我们用split分隔 共同存储在一个列表中
    tgtPorts=str(options.tgtPort).split(",")
    if (tgtHost==None) | (tgtPorts[0]==None):
        print ("[-]you must specify a target host and port[s].")
        exit(0)
    portScan(tgtHost,tgtPorts)
if __name__=="__main__":
    main()
#上面这一部分 快速解析了要扫描的目标主机名字 和 端口

 

转载于:https://www.cnblogs.com/shidi/p/7487368.html

端口扫描软件的代码在网上很多,可是并不一定适合基础不深的鸟鸟们学。要不就是代码大多都很长而且使用了多线程(关于多线程的很多概念就够闹腾的了,扫描部分就更算了),让我等小菜都望而生畏;要不就是速度很慢,学会了也派不上用场。今天我就介绍一下自己学习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、付费专栏及课程。

余额充值