主机系统扫描程序设计


1、相关原理、技术分析

1.1获得主机的网络信息

获取主机的网络信息非常简单,我们就拿获取主机的IP地址,获取主机的网卡来说

  • 获取目标主机的IP地址

最简单的办法就是ping目标主机,就会得到IP地址,当然扫描主机也要得到IP地址,在python中用一个函数也可以搞定

  • 获取目标主机的网卡

获取目标主机的网卡有点东西,需要使用interfaces 和 wr这两个模块,需要找到对应的注册表,再得到网卡信息

1.2系统信息

获取系统信息最好的办法就是ping目标主机,根据TTL值来判断目标系统信息,如果TTL值再53左右就是Linux系统,如果TTL值再128左右就是Windows系统,如下可以看到百度是Linux系统

在这里插入图片描述

1.3端口信息

端口信息我使用套接字编程实现的,我先建立一个套接字,然后与目标主机的对应端口连接,连接不成功会返回socket.error错误,根据这一点,我就可以判断目标主机开放的端口,进而推算出目标主机的服务

不同端口对应的服务:

  • FTP (21/TCP)
  • SSH (22/TCP)
  • Telent (23/TCP)
  • SMTP (25/TCP)
  • DNS (53/UDP & 53/TCP)
  • DHCP 67/68
  • Kerberos (88/TCP)
  • POP3 (110/TCP & 995/TCP)
  • RPC (135/TCP)
  • NetBIOS (137/UDP & 138/UDP)
  • NetBIOS / Samba (139/TCP)
  • IMAP (143/TCP & 993/TCP)
  • SNMP (161/TCP & 161/UDP)
  • LDAP (389/TCP)
  • HTTPS (443/TCP)
  • Linux Rexec (512/TCP & 513/TCP & 514/TCP)
  • Rsync (873/TCP)
  • RPC (1025/TCP)
  • Java RMI (1090/TCP & 1099/TCP)
  • MSSQL (1433/TCP)
  • Oracle (1521/TCP)
  • NFS (2049/TCP)
  • ZooKeeper (2171/TCP & 2375/TCP)
  • Docker Remote API (2375/TCP)
  • MySQL (3306/TCP)
  • RDP / Terminal Services (3389/TCP)
  • Postgres (5432/TCP)
  • VNC (5900/TCP)
  • CouchDB (5984/TCP)
  • WinRM (5985/TCP)
  • Redis (6379/TCP)
  • Kubernetes API Server (6443/TCP && 10250/TCP)
  • JDWP (8000/TCP)
  • ActiveMQ (8061/TCP)
  • Jenkin (8080/TCP)
  • Elasticsearch (9200/TCP)
  • Memcached (11211/TCP & 11211/UDP)
  • RabbitMQ (15672/TCP & 15692/TCP & 25672/TCP)
  • MongoDB (27017/TCP)
  • Hadoop (50070/TCP & 50075/TCP)

2、设计思路、算法描述

该算法分为三步,获得主机的网络信息,获取网络信息,获取端口信息,首先获取计算机信息,platform中,有对应的函数,然后获取端口信息,直接建立套接字,再进行连接,连接不成功会返回socket.error错误,连接成功就加入prettytable中,以表格的形式输出结果,最后再获取网卡信息

3、详细实现(代码必须注释)

import socket
import platform
from prettytable import PrettyTable
from netifaces import interfaces
import winreg as wr

total = 0  # 计算开放的端口数量

t = PrettyTable()
column_names = ["开放的端口   ", "开放的服务   "]


# 定义获取Windows系统网卡接口的在注册表的键值的函数
def get_key(ifname):
   # 获取所有网络接口卡的键值
   id = interfaces()
   # 存放网卡键值与键值名称的字典
   key_name = {}
   try:
       # 建立链接注册表,"HKEY_LOCAL_MACHINE",None表示本地计算机
       reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
       # 打开r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}',固定的
       reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')
   except:
       return ('路径出错或者其他问题,请仔细检查')

   for i in id:
       try:
           # 尝试读取每一个网卡键值下对应的Name
           reg_subkey = wr.OpenKey(reg_key, i + r'\Connection')
           # 如果存在Name,写入key_name字典
           key_name[wr.QueryValueEx(reg_subkey, 'Name')[0]] = i
           # print(wr.QueryValueEx(reg_subkey , 'Name')[0])
       except FileNotFoundError:
           pass
   # print('所有接口信息字典列表: ' + str(key_name) + '\n')
   return key_name[ifname]


def get_platform():
   """获取操作系统名称及版本号"""
   return platform.platform()


def get_version():
   """获取操作系统版本号"""
   return platform.version()


def get_architecture():
   """获取操作系统的位数"""
   return platform.architecture()


def get_machine():
   """计算机类型"""
   return platform.machine()


def get_node():
   """计算机的网络名称"""
   return platform.node()


def get_processor():
   """计算机处理器信息"""
   return platform.processor()


def get_system():
   """获取操作系统类型"""
   return platform.system()


def main():
   host = input('请输入主机信息:\n')
   ip = [22, 53, 67, 80, 110, 443, 3306]  # 由于主机端口太多了,我这里就扫描几个常见的端口
   print('操作系统信息如下:')
   table = PrettyTable()  # 建立表格,用来存放目标主机信息
   table.field_names = ["platform", "version", "architecture", "machine", "processor", "system"]  # 一行一行存储信息
   table.add_row([get_platform(), get_version(), get_architecture(), get_machine(), get_processor(), get_system()])
   print(table)  # 输出目标主机信息
   for port in ip:  # 循环端口扫描
       Scan(host, port)
   print("常见端口信息如下:\n")
   print(t)
   print(f"重要端口总共开放了{total}个")
   print("网卡(网络)信息如下:")
   print(get_key('WLAN'))


def Scan(IP, port):
   global total  # 计数
   try:
       Socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
       # 发起连接,连接不成功会返回socket.error错误
       Socket_tcp.connect((IP, port))
       # 计数
       total += 1
       t.add_column(column_names[0], [port])
       # 各个端口开放所代表的服务
       if port == 22:
           t.add_column(column_names[1], ['SSH'])
       elif port == 53:
           t.add_column(column_names[1], ['DNS'])
       elif port == 67:
           t.add_column(column_names[1], ['DHCP'])
       elif port == 80:
           t.add_column(column_names[1], ['HTTP'])
       elif port == 110:
           t.add_column(column_names[1], ['POP3'])
       elif port == 443:
           t.add_column(column_names[1], ['HTTPS'])
       elif port == 3306:
           t.add_column(column_names[1], ['mysql'])

       # 关闭连接
       Socket_tcp.close()
   except:
       pass


if __name__ == '__main__':
   main()  # 主函数

4、程序测试、结果分析

程序的结果如下所示:

在这里插入图片描述

这里我扫描的是自己的主机,由于端口信息有65535个,我这里只扫描了几个常用的端口信息``(22, 53, 67, 80, 110, 443, 3306)连接不成功会返回socket.error错误,连接成功就加入prettytable中`,以表格的形式输出结果,完全正确。几乎代码分析全再代码中,我这里只验证结果

在这里插入图片描述

在这里插入图片描述

如上是本机的信息,可以和程序结果对比。

5、总结

总体来说python的模块功能非常强大

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安全天天学

你的鼓励是对我最大的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值