首页 > 技术文章 > 嗅探与伪造原理

PsgQ 2020-12-09 21:06 原文

嗅探


程序接收数据包的过程:

1.数据包在传播介质中流动时,网络中的每个网卡都能收到所有的数据帧,这些数据帧会被复制到网卡的内存中,然后检查目的MAC地址,是否为自己的MAC地址,是,则会通过直接存储器(DMA)的方式被复制到操作系统内核的缓存中,否则拒绝接收。然后网卡会以中断的方式告诉CPU,接收到了新数据,CPU会将这些数据从缓存复制到一个队列中(链路层驱动),为新数据的到来腾出空间。

2.然后通过协议栈,检查网络层头部,目的IP地址,目的IP地址不是自己的IP,会进行丢弃,在检查传输层的目的端口,交给相应的程序。会依次去掉各层的头部,交给程序的是数据部分。


如下图:

Sniffer 程 序  链 路 一 驱  缓 存  网 卡  网 络  用 户 空 间  协 议 栈  OS 内 核

Q: Sniffer程序位于用户空间部分,想观察到完整的(包含首部信息)、未经处理的、没有进行丢弃的数据包,怎么办?

A: OS内核 为嗅探程序 提供了 一个Raw Socket API ,当数据包到达链路层驱动位置,会进行复制,通过raw socket 交给嗅探程序,如果有多个嗅探程序,会复制多份,分别交付。如下图:

Sniffer 程 序  raw socket  co PY  链 路 一 驱 一  缓 存  网 卡  网 络  用 户 空 间  协 议 栈  OS 内 核

Sniffer程序并不需要获得所有的报文,可能只需要获得其中的一小部分报文,比如UDP报文,这里就需要进行过滤,UNIX系统添加了一个BSD 数据包过滤器(BSD packet filter,BPF),如下图:

Sniffer 程 序  raw socket  B P F 过 滤 器  链 路 一 驱 一  缓 存  网 卡  网 络  用 户 空 间  协 议 栈  OS 内 核

Q:为什么不在Sniffer程序处过滤,而在OS内核里面进行过滤?

A: 可以节省资源,在数据包复制之前进行过滤,之后进行复制的数据包相应大大减少。

注意:Sniffer程序,嗅探的是收包的过程。(站在攻击者的角度)


伪造


正常的应用程序 仅仅向OS 内核提供数据,目的IP地址,目的端口等信息,其他构造数据包的过程都交给OS内核去完成,而不能随意的去构造各个包头。与嗅探一样,这列也可用raw socket API,进行数据包的构造,然后交给下层,发送出去。如下图:

应 用 程 序  ocket AP  协 议 栈  网 络  spoof 不 帛  aw socket  网 卡

注意:该图是简化的图,大体理解一下过程,没有具体提及OS内核中的链路层操作。

另外,进行伪造,一般是发包的过程。(站在攻击者的角度)





SEED Sniff and Spoof lab:

from scapy.all import *

def spoof_pkt(pkt):
    if ICMP in pkt and pkt[ICMP].type==8:
        print("Original Packet...")
        print("Source IP:",pkt[IP].src)
        print("Destination IP:",pkt[IP].dst)

        ip = IP(src=pkt[IP].dst,dst=pkt[IP].src,ihl=pkt[IP].ihl)
        ip.ttl = 99
        icmp = ICMP(type=0,id=pkt[ICMP].id,seq=pkt[ICMP].seq)
    
        if pkt.haslayer(Raw):
                data = pkt[Raw].load
                newpkt = ip/icmp/data
        else:
                newpkt = ip/icmp
    
        print("Spoof Packet...")
        print("Source IP: ",newpkt[IP].src)
        print("Destination IP:",newpkt[IP].dst)
    
    send(newpkt,verbose=0)

pkt=sniff(filter='icmp and src host 10.0.2.4',prn = spoof_pkt)

具体实验指导书,可见:https://seedsecuritylabs.org/

推荐阅读