工具| 手把手教你制作信息收集器之端口扫描
本期任务:使用python脚本实现端口扫描。
准备工具:选项分析器:optparse;网络库:socket
问题引入
1. 端口扫描器扫描效果如何?
答:下图是效果演示,扫的是IP地址为192.168.10.128这台主机上的80,21,25,135,443,445,7001,7002这几个端口。
2. 端口扫描器的扫描流程?
答:
1.输入目标主机名和要扫描的常用端口列表。
2.通过目标主机名得到目标的网络IP地址。
3.将列表里面的每一个端口去连接目标地址。
4.确定端口上运行的特殊服务,发送特定数据,并读取特定应用程序返回的标识。
3. 端口扫描器在代码上的设计步骤?
答:在代码层面上,我们一共设计了3个函数,分别是主函数main(),端口扫描函数portScan()和连接函数connScan()。主函数采用了选项分析器optparse模块来获取用户的输如的主机名和端口列表,并将其发送到portScan数,postScan数获取用户输入的IP,并取出端口列表中的每一个端口,发送到connScan函数中去。最后connScan函数通过建立socket套接字,采用TCP的形式连接端口和IP并送请求和垃圾数据以判断端口的状态。
收集器制作开始
1. 主函数的设计采用选项分析器optparse模块 optparse是一个功能强大,易于使用的选项分析器,专门用来处理命令行的参数。 使用它之前我们需要实例化一个optparse对象。
import optparse
parser=optparse.OptionParser('usage%prog'+'-H <target host> -p <target port>')
接下来,我们需要添加上命令参数,-H用来指定主机名,-p用来指定端口列表。
parser.add_option('-H',dest='tgthost',type='string',help='specify target host')
parser.add_option('-p',dest='tgtport',type='string',help='specify target port[s] by comma')
(options,args)=parser.parse_args()
其中,dest用来保存参数的值,该值可以作为options的属性被访问。type用来指定输入参数的类型,如字符串类型就是'string',help用来指定在帮助中显示的信息。 设定完了这些,optparse还会自动生成命令行的帮助信息:
获取到了主机名和IP地址后,程序跳转到portScan函数并传入参数。
tgthost=options.tgthost
tgtports=str(options.tgtport).split(',')
portScan(tgthost,tgtports) #跳到portScan()函数
2. portScan()函数的设计 portScan用来获取主机名的IP地址,并逐个将其发送到connScan函数中去。 其中,socket.gethostbyname(hostname)是域名解析,如:socket.gethostbyname('www.baidu.com')会返回百度的IP地址,而socket.gethostbyaddr(ip_address)会返回一个元组,第一个元素是主机名。
tgtIP=gethostbyname(tgthost)
tgtName=gethostbyaddr(tgtIP)
for tgtport in tgtports:
connScan(tgthost,int(tgtport))
3. connScan()函数的设计 connScan采用了socket模块来建立TCP的套接字,用来发送TCP的请求。
import socket
connSkt=socket(AF_INET,SOCK_STREAM) #建立TCP的套接字
connSkt.connect((tgthost,tgtport)) #连接IP地址和对应的端口
connSkt.send('ViolenPythonrn') #发送垃圾数据
result=connSkt.recv(100) #设置接收数据的容量
4. 完整的代码
#-*-coding:utf-8-*-
import optparse
import socket
from socket import *
def connScan(tgthost,tgtport):
try: #尝试去建立端口的连接并发送垃圾数据
connSkt=socket(AF_INET,SOCK_STREAM)
connSkt.connect((tgthost,tgtport))
connSkt.send('ViolenPythonrn')
result=connSkt.recv(100)
print '[+]%d/tcp open'%(tgtport) #如果没有出错,打印端口开放,并把接收到的banner信息打印出来
if str(result):
print '[ %d banner]'%(tgtport)+str(result)
connSkt.close()
except: #如果出错,则打印端口关闭
print '[-]%d/tcp closed'%(tgtport)
def portScan(tgthost,tgtports):
try:
tgtIP=gethostbyname(tgthost)
except:
print "[-] Cannot resolve '%s': Unknow host"%(tgthost)
return
try:
tgtName=gethostbyaddr(tgtIP)
print 'n[+] Scan Result for:'+tgtName[0]
except:
print 'n[+] Scan Result for:'+tgtIP
setdefaulttimeout(1)
for tgtport in tgtports:
# print 'Scanning port '+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='string',help='specify target port[s] by comma')
(options,args)=parser.parse_args()
tgthost=options.tgthost
tgtports=str(options.tgtport).split(',')
if (tgthost == None) | (tgtports[0] == None): #判断是否有ip和端口参数,没有则输出帮助信息并退出
print '[-] You must specify a target host and port[s].'
print parser.usage
exit(0)
portScan(tgthost,tgtports) #跳到portScan()函数
if __name__ == '__main__':
main()
小结
好了,一个轻量级的只需45行代码的端口扫描器就制作完成啦,本期的扫描器采用的是TCP的全连接扫描,小伙伴们可以尝试开发出其他的扫描方式哈,附上思维导图供大家参考,我们下期见。
- 技术解析 | Web缓存欺骗测试
- SSH僵尸主机挖矿木马预警
- 看我如何通过Tor Onion在Windows中执行远程Shell
- 某租车系统JAVA代码审计
- 深入挖掘APP克隆实验
- Sickle:推荐一款优质ShellCode开发工具
- 看我教你如何修改QQ安装包实现绕过QQ语音红包验证来领红包
- “奇幻熊”(APT28)组织最新攻击
- GDB调试CVE-2018-5711 PHP-GD拒绝服务漏洞
- 高效与争议并存:大规模自动化渗透工具AutoSploit
- Android应用测试速查表
- ADB配置提权漏洞(CVE-2017-13212)原理与利用分析
- Fuzz自动化Bypass软WAF姿势
- Web黑盒渗透思路之猜想
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Cloud for Customer Rule Editor的使用方法和底层工作原理
- (数据科学学习手札94)QGIS+Conda+jupyter玩转Python GIS
- 72-STM32+ESP8266+AIR202基本控制篇-移植使用-移植Android的MQTT包到自己的工程项目
- 用上Latex实现编辑伪代码
- TensorFlow交叉熵函数(cross_entropy)·理解
- 第05期:Prometheus 数据查询(一)
- 技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记
- 线程有多少种状态?Runnable 一定在执行任务吗?
- swift 中类(class)和结构体(struct)区别
- C语言三剑客之《C专家编程》一书精华提炼
- 前端必备技能:json-server全攻略
- 温故知新——Spring AOP(二)
- R语言中的偏最小二乘PLS回归算法
- R如何与Tableau集成分步指南
- 漏洞复现 | CVE‐2020‐5902踩坑记