Python3实现TCP端口扫描
在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤。通过端口扫描我们可以了解到目标主机都开放了哪些服务,甚至能根据服务猜测可能存在某些漏洞。 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端口扫描的更多相关文章
- Python3实现TCP端口扫描器
本文来自 高海峰对 玄魂工作室 的投稿 作者:高海峰 QQ:543589796 在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤.通过端口扫描我们可 ...
- Socket2实现tcp端口扫描
主要的界面如下: 主要代码如下: //对于每一个线程,传过去的参数 typedef struct ThreadParamStruct { CString strIP; //要扫描的IP地址 UINT ...
- tcp端口扫描与syn扫描
连接网络设备时,一般都会在网络设备端选取0-65535之间的一个端口进行连接,端口扫描是指:检查网络设备上0-65535号端口哪些端口是开启状态.如果黑客扫描到某网络设备的80端口是开启状态,那么很有 ...
- TCP端口扫描
# TCP三次握手 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1 ...
- tcp端口扫描(python多线程)
1 使用单线程扫描单台主机 首先实现的是对单台主机中0-1024端口的扫描,发现差不多每秒扫描一个端口,很慢. import socket def tcp_scanner(host,port): cl ...
- TCP端口扫描类型-隐蔽扫描和僵尸扫描
TCP扫描有三种类型:全连接扫描,隐蔽扫描,僵尸扫描.全连接扫描无须赘述. 隐蔽扫描:发送完SYN数据包以及收到SYN/ACK数据包后不再发送SCK数据包,由于没有建立完整的TCP连接,所以在目标主机 ...
- 34.TCP非阻塞连接及套接字异常处理丶端口扫描脚本
TCP非阻塞及套接字异常处理: TCP阻塞套接字异常捕获: 套接字创建失败,8000 socket.error 客户端连接错误: ConnectionRefusedError socket.gaier ...
- 小白日记10:kali渗透测试之端口扫描-UDP、TCP、僵尸扫描、隐蔽扫描
端口扫描 二三四层发现的目的只是为了准确发现所有活着主机IP,确定攻击面,端口扫描即发现攻击点,发现开放端口.端口对应网络服务及应用端程序,服务端程序的漏洞通过端口攻入.[所有的扫描结果,都不要完全相 ...
- Kali学习笔记9:端口扫描详解(上)
UDP端口扫描: 原理:回应ICMP不可达,代表端口关闭:没有回应,端口开启 建议了解应用层的UDP包头结构,构建对应的UDP数据包用来提高准确度 另外:所有的扫描都存在误判情况 我们用Scapy写个 ...
随机推荐
- 为什么volatile不能保证原子性而Atomic可以?
在上篇<非阻塞同步算法与CAS(Compare and Swap)无锁算法>中讲到在Java中long赋值不是原子操作,因为先写32位,再写后32位,分两步操作,而AtomicLong赋值 ...
- MySQL中索引和优化的用法总结
1.什么是数据库中的索引?索引有什么作用? 引入索引的目的是为了加快查询速度.如果数据量很大,大的查询要从硬盘加载数据到内存当中. 2.InnoDB中的索引原理是怎么样的? InnoDB是Mysql的 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 关于java中接口定义常量和类定义常量的区别
/** * * @author YZJ * @Description java中定义常量的最佳方法 */ public final class Contants{ /** * @Description ...
- Spring声明事务管理
首先我们先了解事务,什么是事务? 简单来说就是要么全部成功,要么什么都不做. 为什么要使用事务? 比如说常用银行系统的例子,如果没有用事务,有人在存入钱的时候出了问题,那么银行系统数据库的数据没有改变 ...
- 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...
- RequireJS+JQueryMobile
RequireJS提供了JS下模块化开发的充分条件.之前我自己也在多个项目中尝试模块化开发,但是由于没有类似RequireJS这样的框架,最后的效果都不是很理想. 在RequireJS中,所有的JS都 ...
- JAVAScript柯里化、部分应用参数终极理解
一.柯里化 在定义柯里化.部分应用参数的概念前,首先必须对闭包有深入的了解和定义,闭包一句话说清楚:函数返回值为函数. 柯里化的定义:将多参函数分解为按步骤接受单个参数的函数,如下代码: var mo ...
- 如何使用github搭建个人博客
1.去github官网注册个人帐号:没有的:猛戳这里去注册,比如我的账户名:wjf444128852,我的已经汉化(可在github里搜索github如何汉化有插件) 2.点击仓库-新建,仓库名字必须 ...
- css2基础知识梳理
基础的css知识,只放XMind的截图. css01 css02 css03 css04 css05 css+div布局是前端的基本功,要多多练习.运用标准流.浮动.定位.层级等,做简单的静态页面.一 ...