阅读量: 434
-
监听数据包(与 wireshark 相同),分析流量,编辑流量数据包(链路层,网络层,传输层),应用层 也可以编辑,但是意义不大
-
scapy 提供两种操作方式:基于命令行进行交互,直接在 python 代码中调用。
| show_interfaces() |
| sniff(count=10) |
| |
| pkg=sniff(count=10) |
| pkg[0].show() |
| pkg.summary() |
| |
| pkg=sniff(count=8,filter=*icmp*) |
| 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") |
| |
| |
| 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 |
| |
| import logging |
| logging.getLogger("scapy.runtime").setLevel(logging.ERROR) |
| |
| |
| 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) |