• 安全开发实战(3)--存活探测与端口扫描


    目录

    安全开发专栏

    前言

    存活探测

    端口扫描

    方式一:

    1.3.1 One

    1.3.2 Two

    1.3.3 批量监测

    方式二:

    1.3.1 One

    1.3.2 Two

    1.3.3  Three

    1.3.4 扫描ip地址,提取出开放端口和协议

     ​编辑

    1.3.5 批量扫描(最终完成版)

    总结


    安全开发专栏

                                                                 安全开发实战​icon-default.png?t=N7T8http://t.csdnimg.cn/25N7H

    前言

            本篇主要是对上一篇,通过域名反差ip后,我们需要通过对主机进行存活监测以及存活的端口进行探测.

    存活探测

            存活探测的作用是确定网络中哪些主机是活动的,即哪些主机正在运行并且可以响应网络请求。通过发送特定类型的数据包(如ICMP回显请求)来检测主机是否在线。

            在渗透测试中,存活探测可以帮助我们确定网络范围,并识别可能存在的目标。这是渗透测试的第一步,我们需要了解哪些主机可以被攻击。

    端口扫描

            端口扫描的作用是确定主机上哪些网络端口是开放的,即哪些端口正在监听传入的网络连接。通过向目标主机发送网络数据包,并根据主机的响应来确定哪些端口是开放的,以及在返回该端口上运行的服务,帮助我们有针对性的使用漏洞来进行进一步的利用。

            在渗透测试中,端口扫描用于识别目标主机上可能存在的漏洞或弱点。通过确定哪些端口是开放的,我们可以进一步分析目标主机上运行的服务和应用程序,从而发现可能的攻击路径和入口点。

              下面的两种方式,各有各的好处,但是相对来说,第二中方式的探测速度更快一点

    方式一:

    1.3.1 One

            socket中的connect()方法连接一但端口不开放,直接就会报错结束监测不利于后续的多个端口的监测

    1. import socket
    2. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    3. # connect方式: ip地址或者端口不存在的话会报错,连接尝试失败,ip和端口开放返回None
    4. # 连接方式 ip/域名,端口号
    5. result = server.connect(('127.0.0.1', 99))
    6. print(result)

    1.3.2 Two

            这里通过使用另一种socket的方法,并且进行了对比,下面的输出图片中能明显看出,开放端口会输出0,不开放的端口会默认返回一个随机的相同的错误码,直到那个端口开放,后又会换一个错误码输出.

                          当然,在渗透测试中,我们不需要考虑未开放的端口,因为意义不大

    1. # 端口扫描(扫描真实IP或域名)
    2. # 方式1: 写原生socket来完成tcp,udp扫描
    3. # connect_ex: ip地址或者端口不存在的话会返回一个错误码,ip和端口开放返回0,connect_ex的效率比上面的快两倍左右
    4. import socket
    5. ports = [21, 22, 80, 135, 443, 445, 1433, 1521, 3306, 3389, 7001, 8000]
    6. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    7. url = str(input("请输入要监测的域名或IP地址:"))
    8. for port in ports:
    9. result = server.connect_ex((url, port))
    10. if result == 0:
    11. print(f'{port}端口是开放的')
    12. else:
    13. print(f'{port}端口是关闭的')
    14. # print(result) # 这个是用来输出当端口为开放时,输出的错误码的

    1.3.3 批量监测

            渗透中不开放的端口是没有利用价值的,但是要写还是写全吧,当然不使用的话可以直接注释掉,下面是做示例为了提升速度,所以只监测了三个端口,当然可以自行在列表中添加一些常用的端口.

    1. import socket
    2. # ports = [21, 22, 80, 135, 443, 445, 1433, 1521, 3306, 3389, 7001, 8000]
    3. ports = [22, 22, 80]
    4. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    5. with open('ip.txt', 'r') as f:
    6. for ip in f.readlines():
    7. for port in ports:
    8. ip = ip.rstrip() # 去掉换行符
    9. result = server.connect_ex((ip, port))
    10. if result == 0:
    11. with open("端口开放.txt", "a+") as w:
    12. w.write(f'{ip}:{port}'+'\n')
    13. print(f'{ip}:{port}端口是开放的')
    14. else:
    15. with open("端口未开放.txt", "a+") as w:
    16. w.write(f'{ip}:{port}' + '\n')
    17. print(f'{ip}:的{port}的端口是关闭的')
    18. # print(result)

    ip.txt

    1. 36.155.132.3
    2. 202.89.233.100

     端口开放.txt

    36.155.132.3:80

     端口不开放.txt

    1. 36.155.132.3:22
    2. 36.155.132.3:22
    3. 202.89.233.100:22
    4. 202.89.233.100:22
    5. 202.89.233.100:80

    方式二:

    1.3.1 One

            本方式是通过使用python的第三方库,使用python-nmap来管理下载的nmap来实现,首先先下载namp,当然对于使用过的namp的,直接将下载namp的安装路径,直接放入到环境变量path中即可

    Download the Free Nmap Security Scanner for Linux/Mac/Windowsicon-default.png?t=N7T8https://nmap.org/download#windows

     

    1.3.2 Two

    1. # 方式2:调用第三方库nmap,masscan等进行扫描
    2. # 下载nmap工具,并将nmap的路径配置到环境变量中
    3. # 需要先安装nmap工具,并且将nmap的路径(就是安装的路径)配置到环境变量path中
    4. # 就是在环境中安装 python-nmap 库 ,用cmd安装的话使用 pip3 install python-nmap 命令
    5. import nmap
    6. nm = nmap.PortScanner()
    7. # host代表ip地址, 后面的是nmap的扫描命令
    8. nm.scan(hosts='192.168.xx.x', arguments='-n -sP -PE')
    9. # 探测整个ip段
    10. # nm.scan(hosts='192.168.xx.x/24', arguments='-n -sP -PE')
    11. up_hosts = nm.all_hosts() # 获取存活主机列表
    12. print(up_hosts)

             为了更好的演示,这里我扫描了我自己连接wiff下的整个网段的ip地址,如图所示会将探测的存活ip地址的列表返回回来

    1.3.3  Three

            既然进行了主机存活监测,下一步就是端口探测了,当然也可以进行调用nmap进行扫描,如下图所示,能够看出,扫描的主机,以及命令,扫描的端口范围,端口的协议,端口开放情况,那么接下来的操作就是通过批量导入ip地址,并将开放的端口和协议从下面的一堆信息中提取出来就结束了

    1. import nmap
    2. nm = nmap.PortScanner()
    3. nm.scan(hosts='192.168.xx.x', arguments='-n -sP -PE')
    4. # 探测整个ip段
    5. # nm.scan(hosts='192.168.xx.x/24', arguments='-n -sP -PE')
    6. up_hosts = nm.all_hosts() # 获取存活主机列表
    7. print(up_hosts)
    8. # 探测端口存活
    9. # 存活ip,探测端口范围
    10. state = nm.scan('192.168.xx.x', '22-443')
    11. print(state)

    1.3.4 扫描ip地址,提取出开放端口和协议

            这里是将监测的存活的主机,以及存活主机的端口一起进行监测,将监测的结果(存活的主机,存活主机的端口以及对应的协议打印出来),当然这里我只进行了端口和协议的输出,因为渗透中,除非使用nmap进行漏洞扫描,不然最多到这一步就可以了.

            这里有个知识点,open代表端口开放,那么filtered代表什么,这里我也是进行了查询后知道了,这里使用110端口做示例,帮助自己有个更好的了解:

            在网络安全领域,特别是在端口扫描或者防火墙日志中,"端口号: 110 状态: filtered" 这样的表述通常涉及到网络过滤和端口的状态。具体解释:

    • 端口号: 110 - 端口号是用于区分计算机网络上不同服务的一个数字标识符。端口号110通常被指派给POP3(邮局协议第三版)服务,这是一种用于接收电子邮件的协议。

    • 状态: filtered - 这个状态表示该端口目前处于被过滤的状态。在网络术语中,“filtered”意味着某些网络流量或数据包被防火墙、安全设备或网络策略所阻止,无法到达目标端口。这可能是由于安全规则或策略的结果,目的是防止未经授权的访问或保护内部网络不受外部威胁。

    当进行端口扫描时,如果某个端口返回的状态是“filtered”,这可能意味着:

    • 端口被防火墙或安全设备保护,并且没有回应扫描器发送的数据包。

    • 端口上可能运行的服务无法从外部网络访问,因为流量被过滤了。

    • 这种状态也可能表示网络设备本身存在安全机制,例如入侵检测系统(IDS)或入侵防御系统(IPS),它们会识别并阻止潜在的恶意流量。

            因此,"端口号: 110 状态: filtered" 通常表明POP3服务的端口当前不能被外部访问,并且任何尝试连接该端口的请求都被网络的安全设施所拦截。

    1. import nmap
    2. nm = nmap.PortScanner()
    3. # 指定主机,后面指定的协议和nmap的命令一致
    4. nm.scan(hosts='192.168.xx.x', arguments='-p 22-443 -sV')
    5. for host in nm.all_hosts():
    6. print('主机 : %s ' % host)
    7. print('状态 : %s' % nm[host].state()) # up 表示在线,down表示不在线
    8. for proto in nm[host].all_protocols(): # nm[host].all_protocols() 主机存活的所有协议
    9. print('协议 : %s' % proto)
    10. lport = nm[host][proto].keys()
    11. for port in lport:
    12. print('端口号 : %s\t状态 : %s' % (port, nm[host][proto][port]['state']))

    1.3.5 批量扫描(最终完成版)

            这里我也优化了之前,到最后写入的时候打开文件,从刚开始就打开写入文件以及读的文件,使整个文件不容易出错,代码整体没有什么难度,主要是考虑写入时的位置,以及怎么循环每个主机和端口的判断,同时使用库中自带的方法

            整体就是通过监测出存活的ip,然后对开放的端口进行监测,然后打印到结果的文件夹,以及输出到控制台中

    1. import nmap
    2. with open('ip.txt', 'r') as f:
    3. with open("result.txt", "a+") as w:
    4. for ip in f.readlines():
    5. ip = ip.rstrip()
    6. nm = nmap.PortScanner()
    7. nm.scan(hosts=ip, arguments='-p 22-443 -sV')
    8. for host in nm.all_hosts():
    9. w.write(f'主机 : {host}\n')
    10. w.write(f'状态 : {nm[host].state()}\n')
    11. print('主机 : %s ' % host)
    12. print('状态 : %s' % nm[host].state()) # up 表示在线,down表示不在线
    13. for proto in nm[host].all_protocols():
    14. print('协议 : %s' % proto)
    15. w.write(f'协议 : {proto}\n')
    16. lport = nm[host][proto].keys()
    17. for port in lport:
    18. state_result = nm[host][proto][port]['state']
    19. w.write(f'端口号 : {port}\t状态 : {state_result}\n')
    20. print('端口号 : %s\t状态 : %s' % (port, state_result))
    21. w.write('\n') # 添加一个换行符,为了分开主机,方便查看

    ip.txt

    1. 192.xxx.xx.1
    2. 192.xxx.xx.4
    3. 192.xxx.xx.6
    4. 192.xxx.xx.5

    result.txt

    1. 主机 : 192.xxx.xx.1
    2. 状态 : up
    3. 协议 : tcp
    4. 端口号 : 22 状态 : filtered
    5. 端口号 : 23 状态 : filtered
    6. 端口号 : 26 状态 : filtered
    7. 端口号 : 53 状态 : open
    8. 端口号 : 80 状态 : open
    9. 主机 : 192.xxx.xx.4
    10. 状态 : up
    11. 协议 : tcp
    12. 端口号 : 25 状态 : filtered
    13. 端口号 : 110 状态 : filtered
    14. 端口号 : 135 状态 : open
    15. 端口号 : 137 状态 : filtered
    16. 端口号 : 139 状态 : open
    17. 端口号 : 329 状态 : filtered
    18. 主机 : 192.xxx.xx.6
    19. 状态 : up
    20. 主机 : 192.xxx.xx.5
    21. 状态 : up
    22. 协议 : tcp
    23. 端口号 : 135 状态 : open

    总结

            本篇主要是对上一篇反查ip后,对整个ip段或是反查的ip进行存活的端口监测,确定目标主机开放的端口以及对应的服务,通过两种不同的方式进行编写,两种方式各有各的好处吧. 

  • 相关阅读:
    nginx实现负载均衡load balance
    医疗革命的关键推手,看AIGC弥合医疗差距的未来之路
    C++编译错误
    使用Jenkins实现前端自动化打包部署(Linux版本)
    docker 下安装mysql8.0
    【图灵MySQL】SQL底层执行原理详解
    JavaScript 67 JavaScript HTML DOM 67.11 JavaScript HTML DOM 导航
    Vue3 - 路由 Vue-router 4.X(配置与使用教程)
    贪心算法求解 图的m着色问题
    为什么有的考生在提前批面试中会“沟通不好”?
  • 原文地址:https://blog.csdn.net/weixin_72543266/article/details/137917520