一.前言
1.关于本人
本人仍然还在学习阶段,有问题欢迎大佬指正,希望我的文章能够帮助到你.以后我很多东西都会在博客更新,和大家一起进步,加油.
2.主题介绍
本次博客主要是开发一个端口扫描工具,用python语言,要求要能指定ip,指定c段,指定端口号和端口范围,还有多线程或者线程池实现,提高端口扫描效率.最重要的是掌握一些python的知识点,一些思路和提高python编程能力.
3.涉及的知识点
- argparse模块:python用于解析命令行参数和选项的标准模块
- os模块:python中执行cmd命令
- ping命令参数
- ThreadPoolExecutor模块:提高效率
- socket编程:端口扫描的核心代码
- 列表字符串等基础知识
- c段扫描
二.程序代码与结果
1.核心代码:
import os
import socket
import sys
import argparse
import time
from threading import Thread
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
#端口扫描
def scan(ip,port):
try:
#for port in range(1, 65536):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((ip, port))
if result == 0:
print("Port: {} Open".format(port))
sock.close()
except KeyboardInterrupt:
sys.exit()
#指定端口
def sport(ip,port):
# 指定特定端口
if("," in port):
ports=port.split(',')
for p in ports:
p=int(p)
scan(ip,p)
#指定端口范围
elif("-" in port):
ports=port.split('-')
start=int(ports[0])
end=int(ports[1])
with ThreadPoolExecutor(100) as t:
for p in range(start,end):
t.submit(scan, ip=ip, port=p)
#单个端口
else:
scan(ip,int(args.port))
#探测ip存活
def check_ip(ip):
check = os.popen(f"ping {ip} -w 1 -n 1")
data=check.read()
if("TTL" in data):
return True;
parser = argparse.ArgumentParser()
#ip为必填:python scan.py ip
parser.add_argument('ip',type=str,help="give your ip")
#可以指定端口号,也可以指定端口范围
# (1)不指定-p,默认就是全端口扫描
# (2)指定特定的端口号,例如指定80和3306端口 -p 80,3306
# (3)可以指定端口范围,例如0-3306 -p 0-3306
# (4)指定一个端口:例如只扫描445端口,-p 445
parser.add_argument('-p','--port',type=str,help="give your port")
args = parser.parse_args()
ip=args.ip
if("/" in ip):
ips = ip.split('.')
ip=ips[0]+"."+ips[1]+"."+ips[2]+"."
for i in range(1,254):
ip = ips[0] + "." + ips[1] + "." + ips[2] + "."
ip=ip+str(i)
if(check_ip(ip)):
print(ip+":")
if args.port:
port = args.port
sport(ip, port)
else:
with ThreadPoolExecutor(100) as t:
for port in range(1, 65536):
t.submit(scan, ip=ip, port=port)
else:
if(check_ip(ip)):
print(ip+":")
if args.port:
port=args.port
sport(ip,port)
#全端口扫描
else:
with ThreadPoolExecutor(100) as t:
for port in range(1,65536):
t.submit(scan,ip=ip,port=port)
else:
print("网络不可达")
2.运行结果
(1).单个ip,默认是全扫描
(2).单个ip,指定特定的端口
(3).单个ip,指定端口范围
(4)扫描c段,指定特定的端口
(5)扫描c段,指定端口范围
三.知识点
1.argparse模块:python用于解析命令行参数和选项的标准模块
(1)首先创建解析器
parser = argparse.ArgumentParser()
(2)添加必选参数:
add_argument方法添加参数
ip是必须有的,没填就会报错,且前面不用任何参数
parser.add_argument('ip',type=str,help="give your ip")
(3)添加可选参数:
parser.add_argument里面的参数加上--或者-,或者两个都加
parser.add_argument('-p','--port',type=str,help="give your port")
-p或者-port可填可不填
(4)获取参数:
parse_args方法:获得所有参数
args = parser.parse_args() #此时args有所有输入的参数
args.ip #获得ip参数
args.port #获取port参数
(5)对应的代码:
(6)更详细的学习:
Argparse 教程 — Python 3.10.2 文档
2.c段扫描
(1)c段
通俗来讲,就是例如192.168.0.0/24,就是192.168.0.1-192.168.0.254,前面24位不用变,最后8位改变.
(2)c段扫描的原理
由于c段主机比较多,所以在进行端口扫描时,最好先探测一下c段有什么主机哪些存活,再对c段存活的主机进行端口扫描,这样效率就比较快了.探测存活主机的方法,这里是使用ping命令,ping得到的主机就是存活主机,且ping通的主机都有TTL,程序可以根据有无TTL值来判断是否ping通
(3)对应代码:
3.ping命令参数
(1)ping命令时间问题:
ping 得到存活的主机速度比较快,但是ping到没有存活的主机速度比较慢
ping存活不到的主机要18秒,太慢了
(2)ping命令参数:
查看ping命令参数
(3)ping命令使用参数改进:
最主要的是-n和-w
我们可以使用-n参数,只显示一条回显结果 -n 1
我们还可以使用-w参数,设置超时时间为 -w 1
测试结果:时间快了好多
(4)对应代码:
4.os模块:python中执行cmd命令
(1)os模块执行cmd命令的方法:
- os.system(cmd)
这个方法在执行的时候,它会自动的打开一个终端,并且无法对cmd命令中执行的结果进行保存,简单的说就是使用这个方法,可以在一个脚本中对cmd进行执行操作
- os.popen(cmd,mode)
这个方法是使用是对一个cmd进程中的管道进行打开操作它会返回一个文件对象,读写模式根据mode决定,可以是读也可以是写,如果mode为'r',可以使用此函数的返回值调用read()来获取cmd命令的执行结果。
所以为了读取执行结果,一般使用os.popen
(2)对应代码:
5.socket编程:端口扫描的核心代码
(1)创建socket对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.AF_INET是服务器之间网络通信
SOCK_STREAM是基于TCP连接的
(2)设置超时时间
sock.settimeout(1)
(3)连接对方的ip加端口
使用connect_ex方法,如果结果为0,说明对方ip+端口是存在的,端口扫描也是基于这个来处理的
result = sock.connect_ex((ip, port))
if result == 0:
print("Port: {} Open".format(port))
(4)关闭socket:
sock.close()
(5)涉及代码:
6.ThreadPoolExecutor模块:线程池提高效率
(1)导入模块:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
(2)线程池解析:
with ThreadPoolExecutor(100) as t: #创建100个线程的线程池
for port in range(1,65536): #有这么多个任务
t.submit(scan,ip=ip,port=port) #调用的函数以及参数
所以函数体内尽量实现功能即可,for循环可以在外部做,这样效率就比较高
(3)对应代码:
版权归原作者 weixin_58729813 所有, 如有侵权,请联系我们删除。