背景

客户有个需求想要做个功能,通过页面输入IP段能划分子网,显示子网的信息,以及针对网络内的ip在线情况进行统计分析

需求分析
  1. 子网划分涉及到网络地址的内容,趁机把上学时候学习到的ipv4地址的内容又回顾了下。python有个第三方库叫做netaddr可以自动解析ip段,返回起始ip、网络地址和主机地址。
  2. ip客户端在线一般情况都是通过ping方式检测,其原理是发送ICMP数据包,但是现在windows防火墙以及各类软件防火墙都会进行拦截,所以其准确性非常低。后来又研究了下,发现可以发送arp数据包的方式探测,同时还能获取到目标主机的mac地址信息(但是只有本网段内的设备可以获取到mac地址,跨网段的地址获取到的是核心交换机的mac地址)。于是开始寻找比对,最终选择了第三方库Kamene,它是一个Python程序,使用户能够发送,嗅探,剖析和伪造网络数据包。此功能允许构建可以探测、扫描或攻击网络, 很强大
注意事项
  1. windows操作系统探测IP需要安装winPcap,不然会报动态库wpcap.dll不存在。
  2. Linux操作系统是通过构造原始套接字SOCKET RAW实现,所以需要通过sudo执行,或者使用root用户给你使用的python执行程序以及tcpdump赋权。ps:setcap仅对二进制文件有效,脚本文件无效。 赋权信息的进一步说明可查看附录一
# 赋权
setcap cap_net_raw,cap_net_admin=eip /tester/venv/bin/python3.6
setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

# 查看赋权
getcap /tester/venv/bin/python3.6
getcap /usr/sbin/tcpdump

# 取消赋权
setcap -r /tester/venv/bin/python3.6
setcap -r /usr/sbin/tcpdump
代码样例
from kamene.layers.l2 import ARPingResult, ARP, Ether
from kamene.sendrecv import srp
from netaddr import IPNetwork


def arp_scan(scan_ip, iface=''):
    """
    arp扫描目标网段
    :param scan_ip: ip地址
    :param iface:  网卡名称 可选
    :return: {'online': ['ip1', 'ip2' ...],
              'offline': ['ip1', 'ip2' ...],
              'all': [['ip1', 'mac1', 'online'], ['ip2', 'mac2', 'offline'] ...]
              }
    """
    try:
        net_ip = IPNetwork(scan_ip)
    except Exception:
        raise ValueError(f'非法的网络地址{scan_ip}')
    network = broadcast = None
    if net_ip.size >= 4:
        # 网络地址
        network = str(net_ip.network)
        # 广播地址
        broadcast = str(net_ip.broadcast)
    ip_list = {'online': [], 'offline': [], 'all': []}
    params = {'iface_hint': scan_ip,
              'verbose': 0,  # 不输出过程信息
              'filter': "arp and arp[7] = 2",
              'timeout': 2}
    if iface:
        params.update({'iface': iface})
    ans, unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=scan_ip), **params)
    ans = ARPingResult(ans.res)
    for send_, recv_ in ans.res:
        ip_list['online'].append(recv_.psrc)
        ip_list['all'].append((recv_.psrc, recv_.src, 'online'))

    ip_list['offline'] = [dst.pdst for dst in unans.res]
    # 剔除网络地址和广播地址
    if network in ip_list['offline']:
        ip_list['offline'].remove(network)
    if broadcast in ip_list['offline']:
        ip_list['offline'].remove(broadcast)
    ip_list['all'].extend([[ip, '', 'offline'] for ip in ip_list['offline']])
    ip_list['all'].sort(key=lambda x: IPNetwork(x[0]).value)
    if ip_list['online']:
        ip_list['online'].sort(key=lambda x: IPNetwork(x).value)
    if ip_list['offline']:
        ip_list['offline'].sort(key=lambda x: IPNetwork(x).value)
    return ip_list
附录
一、 Liunx Capbilities

Capabilities的主要思想在于分割root用户的特权,即将root的特权分割成不同的能力,每种能力代表一定的特权操作。例如:能力CAP_SYS_MODULE表示用户能够加载(或卸载)内核模块的特权操作,而CAP_SETUID表示用户能够修改进程用户身份的特权操作。在Capbilities中系统将根据进程拥有的能力来进行特权操作的访问控制。
在Capilities中,只有进程和可执行文件才具有能力,每个进程拥有三组能力集,分别称为cap_effective, cap_inheritable, cap_permitted(分别简记为:pE,pI,pP),其中cap_permitted表示进程所拥有的最大能力集;cap_effective表示进程当前可用的能力集,可以看做是cap_permitted的一个子集;而cap_inheitable则表示进程可以传递给其子进程的能力集。系统根据进程的cap_effective能力集进行访问控制,cap_effective为cap_permitted的子集,进程可以通过取消cap_effective中的某些能力来放弃进程的一些特权。可执行文件也拥有三组能力集,对应于进程的三组能力集,分别称为cap_effective, cap_allowed 和 cap_forced(分别简记为fE,fI,fP),其中,cap_allowed表示程序运行时可从原进程的cap_inheritable中集成的能力集,cap_forced表示运行文件时必须拥有才能完成其服务的能力集;而cap_effective则表示文件开始运行时可以使用的能力。
Linux内核从2.2版本开始加入Capabilities的概念与机制,随着版本升级和root权限细化,分割成以下29种能力:
CAP_CHOWN:修改文件属主的权限
CAP_DAC_OVERRIDE:忽略文件的DAC访问限制
CAP_DAC_READ_SEARCH:忽略文件读及目录搜索的DAC访问限制
CAP_FOWNER:忽略文件属主ID必须和进程用户ID相匹配的限制
CAP_FSETID:允许设置文件的setuid位
CAP_KILL:允许对不属于自己的进程发送信号
CAP_SETGID:允许改变进程的组ID
CAP_SETUID:允许改变进程的用户ID
CAP_SETPCAP:允许向其他进程转移能力以及删除其他进程的能力
CAP_LINUX_IMMUTABLE:允许修改文件的IMMUTABLE和APPEND属性标志
CAP_NET_BIND_SERVICE:允许绑定到小于1024的端口
CAP_NET_BROADCAST:允许网络广播和多播访问
CAP_NET_ADMIN:允许执行网络管理任务
CAP_NET_RAW:允许使用原始套接字
CAP_IPC_LOCK:允许锁定共享内存片段
CAP_IPC_OWNER:忽略IPC所有权检查
CAP_SYS_MODULE:允许插入和删除内核模块
CAP_SYS_RAWIO:允许直接访问/devport,/dev/mem,/dev/kmem及原始块设备
CAP_SYS_CHROOT:允许使用chroot()系统调用
CAP_SYS_PTRACE:允许跟踪任何进程
CAP_SYS_PACCT:允许执行进程的BSD式审计
CAP_SYS_ADMIN:允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
CAP_SYS_BOOT:允许重新启动系统
CAP_SYS_NICE:允许提升优先级及设置其他进程的优先级
CAP_SYS_RESOURCE:忽略资源限制
CAP_SYS_TIME:允许改变系统时钟
CAP_SYS_TTY_CONFIG:允许配置TTY设备
CAP_MKNOD:允许使用mknod()系统调用
CAP_LEASE:允许修改文件锁的FL_LEASE标志