Scapy

Scapy

一、基础

1.介绍

  • 监听数据包(与wireshark相同),分析流量,编辑流量数据包(链路层,网络层,传输层),应用层 也可以编辑,但是意义不大
  • scapy提供两种操作方式:基于命令行进行交互,直接在python代码中调用。

2.命令

show_interfaces()                # 显示所有网卡
sniff(count=10)                  # 在所有网卡监听,一共10个数据包

pkg=sniff(count=10)              
pkg[0].show()                    # 显示第一个数据包的信息
pkg.summary()                    # 显示捕获到的数据包的摘要

pkg=sniff(count=8,filter=*icmp*)             # 只监听8个icmp的数据包

3.sniff参数

sniff(count=0,
      store=1,
      offline=None,
      prn=None,
      filter=None,
      L2socket=None,
      timeout=None,
      opened_socket=None,
      stop_filter=None,
      iface=None)

# 参数含义
count:指定最多嗅探多少个符合要求的报文,设置为0时则一直捕获
store:指定保存抓取的数据包或者丢弃,1为保存,0为丢弃
offline:从pcap文件中读取数据包,而不进行嗅探,默认为None
prn:为每个数据包定义一个回调函数,回调函数会在捕获到符合 filter 的报文时被调用,通常使用 lambda 表达式来编写
filter:用来筛选抓取的信息,其用法与常见抓包软件WireShark 等相同,遵循 BPF 语法
L2socket:使用给定的L2socket
timeout:在给定的事件后停止嗅探,默认为None
opened_socket:对指定的对象使用.recv进行读取
stop_filter:定义一个函数,决定在抓到指定的数据之后停止
iface:指定抓包的网卡,不指定则代表所有网卡

二、数据包编辑

  • 编辑Ping数据包

    send(IP(dst="192.168.101.9")/ICMP())
    send(IP(dst="192.168.101.9")/ICMP()/"hello,world")        # 附加数据hello,world
    
    # 发送并接收回应,将回应赋值给pkg
    pkg=sr1(IP(dst="192.168.101.9")/ICMP()/"hello,world")     
  • 编辑ARP数据包

    pkg=sr1(ARP(psrc="192.168.101.2",pdst="192.168.101.9"))

三、网络扫描

import threading, socket
from scapy.sendrecv import sr1
from scapy.layers.l2 import ARP
# 配置日志记录的级别为ERROR级别
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

# 扫描IP
def scapy_ip(start):
    for i in range(start, start+20)
        ip = f'192.168.101.{i}
        try:
            pkg = ARP(psrc='192.168.101.2',pdst=ip)
            reply = sr1(pkg.timeout=3,verbose=False)
            print(f"{ip}在线,MAC地址为{reply[ARP],hwsrc}")
            # socket_port(ip)
            for i in range(1,10241,50):
                threding.Thread(target=scapy_port, args=(ip,i)),start()
        except:
            pass    

# 使用socket扫描端口的方法
def socket_port(ip):
    for port in range(1, 65536):
        try:
            s = socket.socket()
            s.settimeout(0.5)
            s.connect((ip,port))
            print(f"   端口{port}开放.")
            s.close()
        except ConnectionRefusedError:
            pass
        except socket.timeout;
            pass

# 使用scapy构造基于半连接扫描端口的方法
def scapy_port(ip,start):
    pkg = IP(src='192.168.101.2', dst=ip)/TCP(dport=port, flags='s')
    reply = sr1(pkg,timeout=0.7,verbose=False)        # 设置超时时间,取消将信息在屏幕显示
    for port in range(start,start+50):
        try:
            if reply[TCP].flags == 0x12: 
                print(f"   端口{port}开放")
        except:
            pass
        time.sleep(3)

if __name__ == '__main__':
    # 使用多线程扫描
    for i in range(1,255,20):
        threding.Thread(target=scapy_ip, args=(i,)),start()

四、完成三次握手

  • 三次握手必要:源IP,源端口,协议,目标IP,目标端口,标志位

    seq = random.randint(10000, 20000)
    sport = rangom.randint(2049, 4096)
    pkg1 = IP(dst='192.168.101.9')/TCP(sport=sport,dport=80,flags='S',seq=seq)
    reply = sr1(pkg)
    seq = reply[TCP].ack
    ack = reply[TCP].sreq + 1
    pkg2 = IP(dst='192.168.101.9')/TCP(sport=sport,dport=80,flags='A',seq=seq)
    sr1(pkg2)
上一篇
下一篇