• Python3+Scapy安装使用教程


    一、说明

    之前写DoS程序的时候(见"拒绝服务(DoS)理解、防御与实现"),数据包完全是自己构造的,这其中的难处一是要清楚各层协议的字段、字段长度、字段是数值还是字符、大头还是小头,二是计算校验和。整个过程比较痛苦。

    其实构造DoS数据包,我们经常只是想伪造一下源IP等少数字段,而事实上大量时间花在其他大多数不想关心的字段的构造上。

    在查找资料过程中发现很多DoS程序直接使用一个“Scapy”的包(开始还以为是Scrapy心想Scrapy什么时候可以用来构造数据包了,后来才注意到少了个“r”)。当时没太在意,现在回头看Scapy确实堪称“神器”,值得记录一番。

    本文主要参考官方文档,更多用法也请见:https://scapy.readthedocs.io/en/latest/usage.html

    二、安装

    直接使用pip安装:

    pip install scapy

    一些扩展功能安装,可选:

    pip install matplotlib pyx cryptography

    三、生成数据包

    3.1 启动scapy交互shell

    切换到Python的Scripts文件夹下,直接使用scapy命令启动(本质是scapy.bat):

    scapy

    启动界面如下图(由于我没装PyX所以提示不能使用psdump()和pdfdump(),另外还有一些告警,都无关紧要就不处理了):

    3.2 生成数据包

    在scapy中,应用层之下的数据包,基本使用协议大写对应的方法就可以直接生成。如:

    # 使用Ether()方法生成一个以太网层数据包
    eth_packet = Ether()
    # 使用IP()方法生成一个网络层数据包
    ip_packet = IP()
    # 使用TCP()方法生成一个tcp数据包
    tcp_packet = TCP()
    # 使用UDP()方法生成一个udp数据包
    udp_packet = UDP()
    # 使用ICMP()方法生成一个udp数据包
    icmp_packet = ICMP()

    3.3 查看数据包内容

    上一小节中生成数据包,如果就长这样的话完全就是一个黑盒,我们需要一些方法来知道数据包(各字段)是什么内容。

    哪个协议的数据包查看都是类似的,我们这里以一个tcp数据包为例,查看其他协议的数据包类似操作即可。

    # 使用IP()方法生成一个tcp数据包
    ip_packet = IP()
    
    # 方法一、使用raw()方法查看
    raw(ip_packet)
    
    # 方法二、使用hexdump()查看。类似Wireshark
    hexdump(ip_packet)
    
    # 方法三、raw()配合协议类查看。最佳
    # 查看该数据包以太网层内容(下层内容不层示,上层内容不解析只以load形式展示)
    Ether(raw(ip_packet))
    # 查看该数据包网络层内容(下层内容不层示,上层内容不解析只以load形式展示)
    IP(raw(ip_packet))

    3.4 自定义字段值

    上一小节中我们使用raw配合协议方法的方式清楚地看到了数据包中各字段的值,这些值是根据本机信息自动生成的,我们来看如何自定义各字段的值。

    定义字段的值有两个种方法,一种是在构造时直接传递参数,另一种是在生成后重新赋值;至于参数名即是上一小节中打出的那些项。

    以修改源IP地址和TTL为例,在上一小节中可以看到默认生成的源IP地址叫“src”值为“10.10.6.91”(这是我本机当前的IP地址),TTL叫ttl默认值64。

    # 方法一,在构造时直接传递参数
    # 给src传值10.10.6.92,ttl传值128;字段为字符的以字符串形式传,字段为数值的以数值形式传
    ip_packet = IP(src="10.10.6.92",ttl=128)
    # 查看数据包各项值,确认src项是否为10.10.6.92,ttl项是否为128
    IP(raw(ip_packet))
    
    # 方法二,在生成后重新赋值
    # 给src赋值10.10.6.92,ttl赋值128;字段为字符的以字符串形式赋,字段为数值的以数值形式赋
    ip_packet.src = "10.10.6.93"
    ip_packet.ttl = 200
    # 查看数据包各项值,确认src项是否为10.10.6.93,ttl项是否为200
    IP(raw(ip_packet))

    3.5 同时自定义多层协议的字段

    在上一小节中我们自定义了源IP地址,但有一个问题:如果此时我想自定义源MAC地址该如何操作呢。想在构造时直接传递参数使用的是IP()又不是Ether();想在生成后重新赋值,上一小节已试验过了src改的是源ip,源mac没法通过src项改。

    构造多层协议,构造函数可使用“/”隔开,低层函数在前高层函数在后;最后使用构造函数中的最低层函数即可查看数据包内容。

    # 构造一个IP数据包,源mac设置为"00:00:00:00:00:11",源ip设置为"10.10.6.92"
    ip_packet = Ether(src="00:00:00:00:00:11")/IP(src="10.10.6.92")
    # 当前构造函中最低层为Ether
    Ether(raw(ip_packet))
    
    # 定义一个TCP数据包,源mac设置为"00:00:00:00:00:11",源ip设置为"10.10.6.92",源端口设置为1234
    tcp_packet = Ether(src="00:00:00:00:00:11")/IP(src="10.10.6.92")/TCP(sport=1234)
    # 当前构造函中最低层为Ether
    Ether(raw(tcp_packet))
    
    # 定义一个应用层数据包,应用层内容为"GET / HTTP/1.0
    
    "
    app_packet = IP()/TCP()/"GET / HTTP/1.0
    
    "
    # 当前构造函中最低层为IP
    IP(raw(app_packet))

    四、发送和接收数据包

    4.1 只发送数据包不接收数据包

    send()函数允许自定义网络层,sendp()函数允许自定义以太网层。

    不管TCP还是UDP都一样直接使用send()等函数即可,scapy会自己选择socket类型,不我们关心。

    send(IP(dst="10.10.6.92")/ICMP())
    
    sendp(Ether()/IP(dst="10.10.6.92")/ICMP())

    4.2 发送并接收响应数据包

    sr1()函数参许自定义网络层,srp()函数允许自定层数据链路层

    rec_packet = sr1(IP(dst="10.10.6.92")/ICMP()/"abcdefg")
    rec_packet
    # 直接读取某项值
    rec_packet.src
    # 使用show()方法格式化输出
    rec_packet.show()

    4.3 syn扫描

    所谓syn扫描就是把Flags字段明确指定为SYN

    rec_packet = sr1(IP(dst="10.10.6.92")/TCP(dport=80,flags="S"))
    rec_packet.show()

    五、在代码中使用

    前面我们都是基于交互shell进行了,如果是在文件中该如何使用scapy呢。

    交互shell和文件在代码书写上没有区别,唯一的区别就是交互shell导入好了scapy的所有类,而到文件上导入scapy所有类最简单的方式就是:

    from scapy.all import *

    (实践发现,这种写法在Pycharm中还是会提示“Unresloved reference”但运行是不报错的;实在不行使用“Alt+Enter”键把使用到的类逐个导入即可。)

    参考:

    https://scapy.readthedocs.io/en/latest/usage.html

    https://github.com/secdev/scapy/

  • 相关阅读:
    C/C++指针精髓转载
    彻底搞定c指针系列转载
    vc根据域名获取IP地址 gethostbyname()函数
    try catch finally的执行顺序
    vc2008中mfc字符串转换待续
    C++字符串完全指引(二)转载
    vc随机字符串
    C++字符串完全指引转载
    编写c++程序的优良习惯
    ReportViewer一些技巧
  • 原文地址:https://www.cnblogs.com/lsdb/p/10496171.html
Copyright © 2020-2023  润新知