scapy的功能强大且灵活,它的潜力几乎是无穷无尽的。该测试建议在Linux上进行实验,因为scapy最开始就是为Linux设计的。(不过最新版本的scapy已经支持windows了)现在假设你已经渗透进了某个攻击目标的局域网内。
一、随机抓取一个包
我们要使用sniff函数来嗅探流量。现在我们编写一个非常简单的嗅探器来捕捉指定的包。
Scapy(作为python的一个包,但是因为好用所以被单独拿出来作为一个工具)提供了一个非常简明扼要的接口sniff函数。
from scapy.all import sniff
def packet_callback(packet):
print(packet.show())
def main():
sniff(prn=packet_callback,count=1)
main()
该代码需要root权限才能运行,可以在Linux的终端输入
sudo python yourfile.py
来运行这个代码。sniff函数的意义是,嗅探到包以后就执行回调函数packet_callback(),在这个回调函数中会使用show方法输出包里面的基本数据。而count代表总共接收1个包。
运行上面的代码我们可以得到:
因为没有添加过滤和筛选,所以这个包的属性无法确定,它是随即抓取的包。
二、sniff函数的使用方法
sniff函数的传参当然不止上面的两个,它还包括:
1.iface:指定捕获数据包的网络接口。例如,iface="eth0"
表示在名为“eth0”的网络接口上捕获数据包。如果不指定此参数,sniff
函数会在所有可用的网络接口上捕获数据包。
2.count:指定要捕获的数据包数量。例如,count=10
表示只捕获前10个数据包。如果不指定此参数,sniff
函数会一直捕获数据包,直到被手动停止。
3.filter:通过BPF(Berkeley Packet Filter)语法来过滤捕获的数据包。例如,filter="tcp"
表示只捕获TCP协议的数据包。BPF语法非常强大,可以用于指定复杂的过滤条件。
4.prn:指定一个回调函数,用于处理捕获到的每个数据包。回调函数会接收一个参数,即捕获到的数据包对象。
5.store:指定是否存储捕获到的数据包。如果设置为1或True,则捕获到的数据包会被存储在内存中,可以通过sniff
函数的返回值访问。如果设置为0或False,则捕获到的数据包不会被存储,只是被监视和处理。
6.timeout:指定捕获数据包的超时时间(以秒为单位)。如果在此时间内没有捕获到任何数据包,则sniff
函数会停止捕获。
三、filter的写法(BPF语法)
1.限定词
type:设置名称或者数字所指示类型,如host(主机)、net(网络)等。
dir:规定流量是从标识符流进还是流出的,或两种兼有。可能的取值有src(源)、dst(目的)、src or dst(源或目的)、src and dst(源和目的)等。
proto:指定具体的协议,如ether(以太网)、ip(IP协议)、tcp(TCP协议)、udp(UDP协议)等。
2标识符
可以是主机名、IP地址、端口号等。
举例来说,用表达式src 192.168.1.100构造的过滤器会捕获所有的来自192.168.1.100的数据包,与之相反的过滤器是dst 192.168.1.100它会捕获所有发给192.168.1.100的数据包。类似的表达式tcp port 8000 or tcp port 9998只会捕获放行在8000或9998端口上的数据包。
四、实战
接下来构造一个可以发送数据包的代码:
from scapy.all import IP, TCP, send
def create_and_send_packet(target_ip, target_port, payload):
ip_layer = IP(dst=target_ip)
tcp_layer = TCP(dport=target_port, flags='S', seq=100)
packet = ip_layer / tcp_layer / payload
# 发送数据包
send(packet)
print(f"已发送数据包到 {target_ip}:{target_port}")
if __name__ == "__main__":
target_ip = '192.168.1.100' # 目标IP地址
target_port = 8000 # 目标端口
payload = 'i am packet' # 负载
create_and_send_packet(target_ip, target_port, payload)
这个代码会发送一个数据包给ip地址为192.168.1.100的8000端口。接下来只需要在发送之前提前打开嗅探的代码即可。
from scapy.all import sniff,IP,TCP
def packet_callback(packet):
print('i got a packet')
#如果包有负载
if packet[TCP].payload:
#把负载打印出来
mypacket = str(packet[TCP].payload)
#如果有的话就提取出用户名和密码
if 'user' in mypacket.lower() or 'pass' in mypacket.lower():
print(f'这个包要去>{packet[IP].dst}')
print(f'这个包的内容是{packet[TCP].payload}')
def main():
print('Listening ... ...')
sniff(filter = 'tcp port 8000',prn = packet_callback,store=0)#
main()
运行代码捕获数据包之后,会运行packet_callback()函数,首先会打印出i got a packet这样你就可以知道捕获了包。最终解析包得到想要的数据。
以下为测试结果