• ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源
  • pip  install  scapy
  • scapy使用手册
    • https://scapy.readthedocs.io/en/latest/

      命令行版

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      from scapy.all import *
      import optparse
      import threading
      import os
      def scan(ipt):
          arppkt=Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ipt)
          res=srp1(arppkt,timeout=0.5,verbose=0)
          res_list = []
          if res:
              res_list.append(res.psrc)
              res_list.append(res.hwsrc)
              print(res_list)
      def main():
          parser=optparse.OptionParser('%prog'+"-t <target> -f <filename>")
          parser.add_option('-t',dest='target',type='string',help='Target')
          parser.add_option('-f',dest='fil',type='string',help='File')
          (options,args)=parser.parse_args()
          target=options.target
          fil=options.fil
          if(target==Noneand (fil==None):
              print('Please input target(-t) or file(-f)')
              exit(0)
          if target:
              iplist=target.split('.')
              ip=iplist[0]+'.'+iplist[1]+'.'+iplist[2]+'.'
              for t in range(1,255):
                  ipt=ip+str(t)
                  t=threading.Thread(target=scan,args=(ipt,))
                  t.start()
          if fil:
              if os.path.exists(fil):
                  with open(fil) as f:
                      for i in f.readlines():
                          ipt=i.strip('\n')
                          t=threading.Thread(target=scan,args=(ipt,))
                          t.start()
              else:
                  print('File is not exists!')
                  exit(0)
      if __name__=='__main__':
          main()

API版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

from scapy.all import *
import threading

class ARP_SCANF:
    def __init__(self):
        self._ret_list = []

    def scan(self,ip):
        arppkt=Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst=ip)
        res=srp1(arppkt,timeout=0.1,verbose=0)
        res_list = []
        if res:
            res_list.append(res.psrc)
            res_list.append(res.hwsrc)
            self._ret_list.append(res_list)

    def run(self,ip_data):
"""
handle
param:
ip_data: 一个IP或一个C段,段用/
ret:
self._ret_list: [[IP,MAC]]
"""
        data_list = ip_data.split(".")
        my_thr = []
        if data_list[3].find("/") != -1:
            ip=data_list[0] + '.' + data_list[1] + '.' + data_list[2]+'.'
            for t in range(1,255):
                t_ip = ip + str(t)
                thr=threading.Thread(target=self.scan,args=(t_ip,))
                my_thr.append(thr)
                thr.start()
        else:
            thr=threading.Thread(target=self.scan,args=(ip_data,))
            my_thr.append(thr)
            thr.start()
        for t in my_thr:
            t.join()
        return self._ret_list

def main():
    arp_scan = ARP_SCANF()
    arp_r = arp_scan.run("192.168.2.70")
    print(arp_r)

if __name__=='__main__':
    main()