python scapy初探

在python的交互界面,推荐使用bpython,有语法高亮,补全提示等

pip install bpython

导入scapy包,使用sniff对网卡‘eth0’进行嗅探100个包

TCP包62个,UDP38个

>>> from scapy.all import *
>>> dpkt = sniff(iface = 'eth0',count = 100)
>>> wrpcap("demo.pcap",dpkt)
>>> dpkt
<Sniffed: TCP:62 UDP:38 ICMP:0 Other:0>

 查看抓到的第一个包,udp,dhcp分配ipv6地址的包

>>> dpkt[0]
<Ether  dst=33:33:00:01:00:02 src=00:50:56:c0:00:08 type=0x86dd 
|<IPv6  version=6L tc=0L fl=0L plen=94 nh=UDP hlim=1 src=fe80::3980:2ab9:418a:c334 dst=ff02::1:2 |<UDP  sport=dhcpv6_client dport=dhcpv6_server len=94 chksum=0xb1f 
|<DHCP6_Solicit  msgtype=SOLICIT trid=0xcef8cb 
|<DHCP6OptElapsedTime  optcode=ELAPSED_TIME optlen=2 elapsedtime=31.00 sec 
|<DHCP6OptClientId  optcode=CLIENTID optlen=14 duid=<DUID_LLT  type=Link-layer address plus time hwtype=Ethernet (10Mb) timeval=Thu, 06 Jul 2017 17:17:12 +0000 (1499361432) lladdr=18:cf:5e:d0:37:7e |> 
|<DHCP6OptIA_NA  optcode=IA_NA optlen=12 iaid=0x1c005056 T1=0 T2=0 ianaopts=[] 
|<DHCP6OptClientFQDN  optcode=OPTION_CLIENT_FQDN optlen=8 res=0L flags= fqdn='lmx-PC' 
|<DHCP6OptVendorClass  optcode=VENDOR_CLASS optlen=14 enterprisenum=Microsoft vcdata=
[<VENDOR_CLASS_DATA  len=8 data='MSFT 5.0' |>] |<DHCP6OptOptReq  optcode=ORO optlen=8 reqopts=
[Domain Search List option, DNS Recursive Name Server Option, VENDOR_OPTS, OPTION_CLIENT_FQDN] 
|>>>>>>>>>>

 查看第二个包,tcp包,其中Raw为发送的报文信息。

可以通过报文中的关键字来直接显示要查询的信息

>>> dpkt[1]
<Ether  dst=00:50:56:e0:18:5b src=00:0c:29:b0:68:47 type=0x800 |
<IP  version=4L ihl=5L tos=0x0 len=86 id=63422 flags=DF frag=0L ttl=64 proto=tcp chksum=0x1fba src=192.168.199.142 dst=58.216.96.26 options=[] |
<TCP  sport=43146 dport=https seq=4172819415 ack=1228561729 dataofs=5L reserved=0L flags=PA window=45260 chksum=0x2372 urgptr=0 options=[] |
<Raw  load="\x17\x03\x03\x00)\x00\x00\x00\x00\x00\x00\x00\x06\x17C\xa6\xadc\xaa+\x1b\xc4\xe7/K)S\x1b\xdf\x99\x19'\xdb\x8b\x8akY\xe5\x00\xf2\x91\x04\x92%\xcaw" |>>>>
>>> dpkt[1][IP].proto
6
>>> dpkt[1][IP].dst
'58.216.96.26'
>>> dpkt[1][IP][TCP].sport
43146

 访问baidu,进而dns查询

其中本机(vmware中的kali)直接将dns查询的包递送给了物理机网卡(虚拟机网关)。


>>> dpkt[22]
<Ether  dst=00:0c:29:b0:68:47 src=00:50:56:e0:18:5b type=0x800 |
<IP  version=4L ihl=5L tos=0x0 len=288 id=62122 flags= frag=0L ttl=128 proto=udp chksum=0x3740 src=192.168.199.2 dst=192.168.199.142 options=[] |
<UDP  sport=domain dport=49581 len=268 chksum=0x8873 |
<DNS  id=37357 qr=1L opcode=QUERY aa=0L tc=0L rd=1L ra=1L z=0L ad=0L cd=0L rcode=ok qdcount=1 
ancount=3 nscount=5 arcount=5 qd=<DNSQR  qname='www.baidu.com.' qtype=A qclass=IN |> an=<DNSRR  
rrname='www.baidu.com.' type=CNAME rclass=IN ttl=5 rdata='www.a.shifen.com.' |<DNSRR  
rrname='www.a.shifen.com.' type=A rclass=IN ttl=5 rdata='180.97.33.108' |<DNSRR  
rrname='www.a.shifen.com.' type=A rclass=IN ttl=5 rdata='180.97.33.107' |>>> ns=<DNSRR  
rrname='a.shifen.com.' type=NS rclass=IN ttl=5 rdata='ns2.a.shifen.com.' |<DNSRR  
rrname='a.shifen.com.' type=NS rclass=IN ttl=5 rdata='ns1.a.shifen.com.' |<DNSRR  
rrname='a.shifen.com.' type=NS rclass=IN ttl=5 rdata='ns3.a.shifen.com.' |<DNSRR  
rrname='a.shifen.com.' type=NS rclass=IN ttl=5 rdata='ns4.a.shifen.com.' |<DNSRR  
rrname='a.shifen.com.' type=NS rclass=IN ttl=5 rdata='ns5.a.shifen.com.' |>>>>> ar=<DNSRR  
rrname='ns1.a.shifen.com.' type=A rclass=IN ttl=5 rdata='61.135.165.224' |<DNSRR  
rrname='ns2.a.shifen.com.' type=A rclass=IN ttl=5 rdata='180.149.133.241' |<DNSRR  
rrname='ns3.a.shifen.com.' type=A rclass=IN ttl=5 rdata='61.135.162.215' |<DNSRR  
rrname='ns4.a.shifen.com.' type=A rclass=IN ttl=5 rdata='115.239.210.176' |<DNSRR  
rrname='ns5.a.shifen.com.' type=A rclass=IN ttl=5 rdata='119.75.222.17' |>>>>> |>>>>

--------------------------------------------------------------------------------------------------------

下面的命令环境是在物理机的kali

root@kali:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Kali
Description:	Kali GNU/Linux Rolling
Release:	kali-rolling
Codename:	kali-rolling
root@kali:~# uname -a
Linux kali 4.13.0-kali1-amd64 #1 SMP Debian 4.13.10-1kali2 (2017-11-08) x86_64 GNU/Linux

 kali的无线网卡wlan0在工作

root@kali:~# ifconfig
eth0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether f8:a9:63:4a:97:69  txqueuelen 1000  (Ethernet)
        RX packets 339  bytes 131476 (128.3 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 481  bytes 54219 (52.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 18  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1760  bytes 142538 (139.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1760  bytes 142538 (139.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.241.238  netmask 255.255.248.0  broadcast 172.18.247.255
        inet6 fe80::95c3:1281:93e7:3dc4  prefixlen 64  scopeid 0x20<link>
        ether 18:cf:5e:d0:37:7e  txqueuelen 1000  (Ethernet)
        RX packets 164269  bytes 187244390 (178.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 128422  bytes 16546842 (15.7 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

针对wlan0进行嗅探抓包,没有进行数据报格式限定,但此时网卡上只有tco报文

1.本地(172.18.241.238)随机高端口 ----->不同的ip:80发出tcp报文

2.不同的ip:80-------->本地:(刚刚发给服务器所使用的端口)

如其中有https则是443端口。

>>> dpkt1 = sniff(iface = "wlan0",prn = lambda x:x.summary())
Ether / IP / TCP 23.219.133.44:http > 172.18.241.238:43980 A
Ether / IP / TCP 2.17.30.102:http > 172.18.241.238:50304 A
Ether / IP / TCP 172.18.241.238:42386 > 64.156.167.98:http FA
Ether / IP / TCP 172.18.241.238:46774 > 204.11.109.65:http A
Ether / IP / TCP 64.156.167.98:http > 172.18.241.238:42386 A / Padding
Ether / IP / TCP 106.10.193.31:http > 172.18.241.238:39460 FA
Ether / IP / TCP 172.18.241.238:39460 > 106.10.193.31:http FA
Ether / IP / TCP 204.11.109.65:http > 172.18.241.238:46774 A
Ether / IP / TCP 172.18.241.238:50302 > 2.17.30.102:http A
Ether / IP / TCP 106.10.193.31:http > 172.18.241.238:39460 A
Ether / IP / TCP 2.17.30.102:http > 172.18.241.238:50302 A
Ether / IP / TCP 64.156.167.98:http > 172.18.241.238:42386 FA / Padding

写了个python脚本用于抓包

#!/usr/bin/python2.7
from scapy.all import *
print ("[protocol:protocol-name]")
print ("all:all"'\n'"icmp:icmp"'\n'"tcp:tcp"'\n'"udp:udp"'\n'"arp:arp")
protocol = raw_input("[please input protocol.number:]");
print "[received input is:]",protocol
number = input("[input count number:]")
print ("[the count number is:]"),number
interface = raw_input('[please input the interface(eth0 or wlan0 ):]')
print ('[the interface is:]'),interface
def start_sniff(interface,number):
    if (protocol == 'all'):
        pkts = sniff(iface = interface,prn = lambda x:x.summary(),count = number)
        save = raw_input('[save this packer? yes or no :]')
        if (save == 'yes'):
            wrpcap('demo.pcap',pkts)
        return pkts
    elif (protocol != 'tcp'):
        pkts = sniff(filter = protocol,iface = interface,prn = lambda x:x.summary(),count = number)
        save = raw_input('[save this packer? yes or no :]')
        if (save == 'yes'):
            wrpcap('demo.pcap',pkts)
        return pkts
    if (protocol == 'tcp'):
        pkts = sniff(filter = 'tcp',iface = interface,count = number)
        save = raw_input('[are you need hexdump?yes or no:]')
        try:
            for i in range(a):
                if pkts[i][IP]:
                    ip_src = str(pkts[i][IP].src)
                    ip_dst = str(pkts[i][IP].dst)
                    if pkts[i][TCP]:
                        tcp_sport = str(pkts[i][TCP].sport)
                        tcp_dport = str(pkts[i][TCP].dport)
                        eth_src = str(pkts[i][Ether].src)
                        eth_dst = str(pkts[i][Ether].dst)
                        print ('%s'%eth_src, '---------->' , '%s'%eth_dst,"TCP")
                        print ('%s'%ip_src,'%s'%tcp_sport,    '----------->',    '%s'%ip_dst,'%s'%tcp_dport)
                        print '                                                                            '
                    if (save == 'yes'):
                        hexdump(pkts[i])
        except:
            print ("[this sniff failure]")
start = start_sniff(interface,number)

猜你喜欢

转载自my.oschina.net/u/3331172/blog/1582538