5.3黑客成长日记——scapy学习
目标:不装逼,就搞懂这个鬼东西是啥
reference
1.0 黑客成长日记
2.0 知乎治学
3.0 简书治学
4.0 IP、TCP、UDP、ARP、ICMP结构
scapy
Scapy是一个强大的,用Python编写的交互式数据包处理程序,它能让用户发送、嗅探、解析,以及伪造网络报文,从而用来侦测、扫描和向网络发动攻击。Scapy可以轻松地处理扫描(scanning)、路由跟踪(tracerouting)、探测(probing)、单元测试(unit tests)、攻击(attacks)和发现网络(network discorvery)之类的传统任务。它可以代替hping,arpspoof,arp-sk,arping,p0f 甚至是部分的Nmap,tcpdump和tshark 的功能。
简单来讲就是网络偏底层的黑客工具。
# sudo is needed
进入scapy后,可以用ls()函数来查看scapy支持的网络协议
可以看到网工们耳熟能详的ARP, BOOTP, Dot1Q, DHCP, DNS, GRE, HSRP, ICMP, IP, NTP, RIP, SNMP, STP, PPPoE, TCP, TFTP, UDP等等统统都支持
python交互模式中:ls(*)*=Ether、IP、ICMP、TCP、UDP、ARP 等等,查看可以配置的参数
>>> package = IP()
>>> ls(IP) # or package.show()
version : BitField (4 bits) = (4)
ihl : BitField (4 bits) = (None)
tos : XByteField = (0)
len : ShortField = (None)
id : ShortField = (1)
flags : FlagsField (3 bits) = (<Flag 0 ()>)
frag : BitField (13 bits) = (0)
ttl : ByteField = (64)
proto : ByteEnumField = (0)
chksum : XShortField = (None)
src : SourceIPField = (None)
dst : DestIPField = (None)
options : PacketListField = ([])
上面的字段对应于下面的数据包中的各个字段
防止冗余:更多的头结构请参考:IP、TCP、UDP、ARP、ICMP结构
实地考察请使用LS命令
ps:四层结构:
应用程序
TCP层 # scapy 用send(第三层)
IP层 # scapy 用senddp(第二层)
EtherNet层(物理层/数据链路层)网络接口层
回到正题
字段的修改很方便,可以定义时候改,也可以作为属性修改
>>> ip = IP(ttl=520, dst='192.168.1.1')
>>> ip.version = 6
>>> ip.show()
###[ IP ]###
version = 6
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 520
proto = ip
chksum = None
src = 10.0.0.14
dst = 192.168.1.1
\options \
如果想从数据链路层将数据发送出去,就需要构造以太网帧数据,IP数据报文和TCP报文,并将三者组合起来发送出去。看下面的示例:
>>> b = Ether()/IP(dst='www.baidu.com')/TCP()/"GET /index/html HTTP/1.0 \n\n"
>>> hexdump(b)
WARNING: getmacbyip failed on Sniffing and sending packets is not available at layer 2: winpcap is not installed. You may use conf.L3socket orconf.L3socket6 to access layer 3
WARNING: Mac address to reach destination not found. Using broadcast.
0000 FF FF FF FF FF FF 00 FF 6A 6E FC 9A 08 00 45 00 ........jn....E.
0010 00 43 00 01 00 00 40 06 08 0B 0A 00 00 0E 70 50 .C....@.......pP
0020 F8 4B 00 14 00 50 00 00 00 00 00 00 00 00 50 02 .K...P........P.
0030 20 00 4A 08 00 00 47 45 54 20 2F 69 6E 64 65 78 .J...GET /index
0040 2F 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A /html HTTP/1.0 .
0050 0A
上面是构造包,然后我们开始发送和接受部分
只发送
二层:sendp() //给定网卡接口
三层:send() //自动根据路由表进行路由发送
发送并返回
二层:
srp() //发送包, 返回答复和没有答复的包的数量
srp1() //发送包, 返回只答复或者发送的包的详细信息| .参数,显示这个参数的返回数据
三层:
sr( ) //发送包, 返回答复和没有答复的包的数量
sr1( ) //发送包, 返回只答复或者发送的包的详细信息|.参数,显示这个参数的返回数据
>>> send(IP(dst="192.168.30.2")/ICMP())
.
Sent 1 packets.
#报错可能是需要安装一些例如winpcap的东西来抓包和发包
#错误如下Sniffing and sending packets is not available at layer 2: winpcap is not installed
>>> sendp(Ether()/IP(dst="192.168.1.1", ttl=(1,4)))
....
Sent 4 packets.
#收包
>>> res = sr(IP(dst="8.8.8.8")/UDP()/DNS(rd=1, qd=DNSQR(qname='www.baidu.com')))
Begin emission:
Finished sending 1 packets.
...*
Received 4 packets, got 1 answers, remaining 0 packets
>>> res[0][0]
(<IP frag=0 proto=udp dst=8.8.8.8 |<UDP sport=domain |<DNS rd=1 qd=<DNSQR qname='www.baidu.com' |> |>>>, <IP version=4 ihl=5 tos=0x0 len=75 id=0 flags=DF frag=0 ttl=63 proto=udp chksum=0x2185 src=8.8.8.8 dst=10.0.0.14 |<UDP sport=domain dport=domain len=55 chksum=0x21cd |<DNS id=0 qr=1 opcode=QUERY aa=0 tc=0 rd=0 ra=0 z=0 ad=0 cd=0 rcode=ok qdcount=1 ancount=1 nscount=0 arcount=0 qd=<DNSQR qname='www.baidu.com.' qtype=A qclass=IN |> an=<DNSRR rrname='www.baidu.com.' type=A rclass=IN ttl=216 rdlen=None rdata=112.80.248.76 |> ns=None ar=None |>>>)
##当然上面两个操作合成一个就是sr1(IP(dst="8.8.8.8")/UDP()/DNS(rd=1, qd=DNSQR(qname='www.baidu.com')))
但是上面的这个其实还有别的
>>> res[0].summary()
IP / UDP / DNS Qry "b'www.baidu.com'" ==> IP / UDP / DNS Ans "112.80.248.76"
>>> res[1] #空包列表
<bound method PacketList.summary of <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>>
注意上图中我们使用了DNS()方法帮助构造应用层(DNS)的报文内容。
实际上接收的数据返回两个列表,第一个就是发送的数据包及其应答组成的列表,第二个是无应答数据包组成的列表。
具体来说上面例子中的操作就是再8.8.8.8DNS服务器查询www.baidu.com域名的IP地址是多少。最后返回的数据就是一个数据包,rdata=112.80.248.76就是百度的IP了
对上面的结果,我们可以采用wireshark来查看,这就需要先存为pcap格式,然后读取
ans, unans = sr(IP(dst="8.8.8.8")/UDP()/DNS(rd=1, qd=DNSQR(qname='www.baidu.com')))
wrpcap('first.pcap', ans)
ans = rdcap(''first.pcap')
ans.show()
附录——ICMP
ICMP(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。 [1]
ICMP 是 TCP/IP 模型中网络层的重要成员,与 IP 协议、ARP 协议、RARP 协议及 IGMP 协议共同构成 TCP/IP 模型中的网络层。ping 和 tracert是两个常用网络管理命令,ping 用来测试网络可达性,tracert 用来显示到达目的主机的路径。ping和 tracert 都利用 ICMP 协议来实现网络功能,它们是把网络协议应用到日常网络管理的典型实例。
下面这两个有趣的命令等我有空了再重新好好看看。(搜tracert命令详解)
PS C:\Users\Feem> tracert www.baidu.com
通过最多 30 个跃点跟踪
到 www.a.shifen.com [112.80.248.76] 的路由: #这个域名本身也很有趣
1 <1 毫秒 <1 毫秒 <1 毫秒 害怕泄露隐私 [10.0.0.1]
2 2 ms 1 ms 1 ms 害怕泄露隐私 [192.168.1.1]
3 6 ms 4 ms 3 ms 124.90.192.1
4 4 ms 4 ms 4 ms 124.90.33.185
5 23 ms 16 ms 16 ms 124.160.233.153
6 16 ms 15 ms 56 ms 219.158.96.86
7 16 ms 15 ms 14 ms 122.96.66.102
8 16 ms 15 ms 17 ms 58.240.96.130
9 * * * 请求超时。
10 14 ms 14 ms 14 ms 112.80.248.76
跟踪完成。
PS C:\Users\Feem> ping baidu.com
正在 Ping baidu.com [220.181.38.148] 具有 32 字节的数据:
来自 220.181.38.148 的回复: 字节=32 时间=43ms TTL=49
来自 220.181.38.148 的回复: 字节=32 时间=43ms TTL=49
来自 220.181.38.148 的回复: 字节=32 时间=43ms TTL=49
来自 220.181.38.148 的回复: 字节=32 时间=43ms TTL=49
220.181.38.148 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 43ms,最长 = 43ms,平均 = 43ms
附录——效果查看
除此之外,如果您已经安装PyX,您可以做一个数据包的图形PostScript/ PDF转储,完整的输出命令列表如下:得到的结果为
附录——python 中使用scapy
这个破电脑真的是太垃圾了,居然怎么都跑不动scapy,最后报错都报到端口去了,弃坑
from scapy.all import *
就可以了,但是要主要怎么获取管理员权限的问题。