使用Python3制作TCP端口扫描器
作者:高海峰 发布时间:2023-06-10 17:25:22
在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤。通过端口扫描我们可以了解到目标主机都开放了哪些服务,甚至能根据服务猜测可能存在某些漏洞。 TCP端口扫描一般分为以下几种类型:
TCP connect扫描:也称为全连接扫描,这种方式直接连接到目标端口,完成了TCP三次握手的过程,这种方式扫描结果比较准确,但速度比较慢而且可轻易被目标系统检测到。
TCP SYN扫描:也称为半开放扫描,这种方式将发送一个SYN包,启动一个TCP会话,并等待目标响应数据包。如果收到的是一个RST包,则表明端口是关闭的,而如果收到的是一个SYN/ACK包,则表示相应的端口是打开的。
Tcp FIN扫描:这种方式发送一个表示拆除一个活动的TCP连接的FIN包,让对方关闭连接。如果收到了一个RST包,则表明相应的端口是关闭的。
TCP XMAS扫描:这种方式通过发送PSH、FIN、URG、和TCP标志位被设为1的数据包。如果收到了一个RST包,则表明相应的端口是关闭的。
下面我们将使用Python3 实现TCP全连接端口扫描器,下面进入编程环节。
编码实战
全连接扫描
方式的核心就是针对不同端口进行TCP连接,根据是否连接成功来判断端口是否打开,现在我们来实现一个最简单的端口扫描器:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
def portScanner(host,port):
try:
s = socket(AF_INET,SOCK_STREAM)
s.connect((host,port))
print('[+] %d open' % port)
s.close()
except:
print('[-] %d close' % port)
def main():
setdefaulttimeout(1)
for p in range(1,1024):
portScanner('192.168.0.100',p)
if __name__ == '__main__':
main()
这段代码的核心就是portScanner
函数,从其中的内容可以看出,只是进行了简单的TCP连接,如果连接成功则判断为端口打开,否则视为关闭。 我们来看一下运行结果:
这样的扫描看起来效率太低了,实际也确实很慢,因为我们设置了默认的超时时间为1秒,这要是扫描10000个端口,岂不是要等到花都谢了? 最简单的办法就是用多线程
来提高效率,虽然python的多线程有点太弱了,不过至少可以利用我们等待的时间去干点别的。另外之前扫描的端口比较多, 显示的信息我们看起来不方便,这次我们只显示我们关心的打开的端口
,并将打开端口的数量在扫描结束的时候显示出来。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading
lock = threading.Lock()
openNum = 0
threads = []
def portScanner(host,port):
global openNum
try:
s = socket(AF_INET,SOCK_STREAM)
s.connect((host,port))
lock.acquire()
openNum+=1
print('[+] %d open' % port)
lock.release()
s.close()
except:
pass
def main():
setdefaulttimeout(1)
for p in range(1,1024):
t = threading.Thread(target=portScanner,args=('192.168.0.100',p))
threads.append(t)
t.start()
for t in threads:
t.join()
print('[*] The scan is complete!')
print('[*] A total of %d open port ' % (openNum))
if __name__ == '__main__':
main()
运行看一下效果,如下图:
这下看起来是不是方便多了?至此效率上的问题解决了,现在我们还需要为扫描器增加一个 参数解析的功能,这样才能看起来像个样子,总不能每次都改代码来修改扫描目标和端口吧!
参数解析我们将用python3自带的标准模块argparse
,这样我们就省去了自己解析字符串的麻烦! 下面来看代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from socket import *
import threading
import argparse
lock = threading.Lock()
openNum = 0
threads = []
def portScanner(host,port):
global openNum
try:
s = socket(AF_INET,SOCK_STREAM)
s.connect((host,port))
lock.acquire()
openNum+=1
print('[+] %d open' % port)
lock.release()
s.close()
except:
pass
def main():
p = argparse.ArgumentParser(description='Port scanner!.')
p.add_argument('-H', dest='hosts', type=str)
args = p.parse_args()
hostList = args.hosts.split(',')
setdefaulttimeout(1)
for host in hostList:
print('Scanning the host:%s......' % (host))
for p in range(1,1024):
t = threading.Thread(target=portScanner,args=(host,p))
threads.append(t)
t.start()
for t in threads:
t.join()
print('[*] The host:%s scan is complete!' % (host))
print('[*] A total of %d open port ' % (openNum))
if __name__ == '__main__':
main()
看一下运行效果,如下图:
至此我们的端口扫描器就基本完成了,虽然功能比较简单,旨在表达端口扫描器的基本实现思路! 至于更详细的功能可以基于这个基本结构来逐步完善!
小结
本节主要讲解了Python3实现一个简单的端口扫描器的过程,本次实验采用了Tcp全连接的方式,不断尝试连接主机的端口来判断端口的开放情况,虽然存在一些缺点, 不过这种方式最适合初学者学习,至于更复杂的方式以后学习起来也不会很难。想举一反三的朋友可以根据协议和端口的对照关系来完成扫描时同时输出协议, 这样看起来会更好一些,至于更详细的功能就留给大家做练习了!


猜你喜欢
- 在安装完数据库后,由于自己不小心直接关闭了安装窗口,或者长时间没有使用root用户登录系统,导致忘记了root密码,这时就需要重置MySQL
- 这篇文章主要介绍了python实现括号匹配方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可
- Django带来了一个高级的聚合生成框架,它使得创建RSS和Atom feeds变得非常容易。什么是RSS? 什么是Atom?RSS和Ato
- 一个最最简单的例子:绘制一个从 0 到 360 度完整的 SIN 函数图形import numpy as npimport matplotl
- 1、如何认识可视化?需要指出的是,虽然不同绘图工具包的功能、效果会有差异,但在常用功能上相差并不是很大。与选择哪种绘图工具包相比,更重要的是
- T-SQL 标识符在T-SQL语言中,对SQLServer数据库及其数据对象(比如表、索引、视图、存储过程、触发器等)需要以名称来进行命名并
- having的用法having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和havi
- 本文实例讲述了MySQL查看、创建和删除索引的方法。分享给大家供大家参考。具体如下:1.索引作用在索引列上,除了上面提到的有序查找之外,数据
- Python字符串处理学习中,有一道简单但很经典的题目,按照单词对字符串进行反转,并对原始空格进行保留: 如:‘ I love China!
- <input id="workname" style="width: 200px" name=
- 1. 停止服务MySQL2. 卸载mysql相关的程序3. 删除注册表(运行->regedit),machine->system
- 大家觉得在接手遗留代码时,见到什么东东是最让人感到不耐烦的?复杂无比的 UML ?我觉得不是。我的答案是,超过两个 else 的 if ,或
- 前言最近天气好像有了点小脾气,总是在万分晴朗得时候耍点小性子~阴会天,下上一会的雨~提醒我们时刻记得带伞哦,不然会被雨淋或者被太阳公公晒到
- 前端使用uniapp开发项目完成后,需要将页面打包,生成H5的静态文件,部署在服务器上。这样通过服务器链接地址,直接可以在手机上点开来访问。
- 本文目的是创建一个MySQL的image,并且在新创建出来的容器里自动启动MySQL服务接受外部连接步骤:1. 首先创建一个目录并在目录下创
- SQL Server 2008的独到之处:安装SQL Server 2008的设置和安装也有所改进。配置数据和引擎位已经分开了,所以它使创建
- 本文实例讲述了php+mysqli实现批量替换数据库表前缀的方法。分享给大家供大家参考。具体分析如下:在php中有时我们要替换数据库中表前缀
- rpc有多种调用方式,http、json-rpc、tcp一、服务端在代码中,启动了三个服务package mainimport ("
- 今天来填坑, 昨天说playwright未必一定要使用pytest-playwright包。 它也可以和pyunit一起使用。那么今天,田辛
- 1.什么是Hilbert矩阵矩阵下面分别列举了1*1;2*2;3*3大小的矩阵; 通过观察,我们发现其规律性极强,那第三列举个例子