本系列文章主要講述自己如何從零開始研究,用C語言寫一個Arp欺騙程序.(以記錄過程為主,教程的話,有空開專題詳談.)
前言:今天已經搞了整整一天了,算是有點小成就,欺騙的核心代碼非常簡單,知道本機以及目標主機的mac地址,然后修改arp應答包即可.
但,作為一個工具,其用法總不能如下吧:
Useage:./arpspoof [interface] [your_ip] [your_mac] [target_mac] [your_ip] [your_mac] [target_ip] [target_mac]
這樣的工具用起來多累?那么為了簡化用戶的操作,那我們的程序就需要默默額做很多事情.....不廢話,正文開始!
一、找接口
昨天寫完一個簡單的tcp服務器后,今天早上突然有種很強烈的欲望想把arp欺騙寫出來.
但,空有一身理論:arp協議、arp報文格式...實際上,我並不知道要想發送arp報文需要什么接口.
所以,趁着等舍友洗漱完的時間手機了一波,c語言實現arp欺騙,最后總算找了一個看上去應該可以運行的源代碼,分析了一下其所用的接口.
(原文地址:http://blog.csdn.net/smstong/article/details/7221184)
此時才發現,原來也需要創建套接字啊!!!!!只不過其參數不同,TCP使用的是SOCK_STREAM....
然后再看一下其發送請求的函數:sendto,這個沒見過,不過無所謂,man page在手,天下我有!!!
知道了相關接口,我就要開始構建arp請求包了!
二、構建Arp包的數據類型
為毛這個家伙的Arp包全是char?這樣賦值起來多累?網絡字節序是大端,那么arp請求包字節序也是大端嘛?我用的是wifi,在struct in_addr的sa_data中填寫eth0還是能發出去嘛?.....
在構建arp數據包時,腦海中浮現出來了一系列疑問!
看到那位仁兄的博客,潛移默化的把所有數據的數據類型都設置為了unsigned char,當我照着arp報文格式終於把arp數據包構建完畢時,突然發現,有些數據是2字節、有些數據是6字節、有些數據是4字節....
突然覺得2、4、字節都是有現成數據類型可以滿足的,全部用unsigned char數組來表示,賦值起來真的麻煩!!!!
於是乎,我便把2、4字節的數據用short和int表示了起來.
當然,編程經驗比較豐富的我,也意識到如果這樣寫會存在內存對齊的問題,因此我將內存對其通過#pragma pack(1)設置為1.
三、構建Arp請求包
當我把整個struct arp定義完畢時,准備先構建一個arp請求包,然后發出去試試看包構建的是否正確之類的.
當我千辛萬苦把arp請求數據包構建好,發送出去后,問題又來了,該用什么函數來接受arp回應數據呢?
百度找了半天,沒有相關信息,最后心想:罷了,用read讀一下試試看.
果然讀到了一些莫名其妙的arp廣播,雖然沒讀到回應包,但這足以說明至少read是可以讀到數據的.
四、調試
數據發出去,為什么沒有回應呢?誰能保證數據一定發出去了?
好吧,一系列問題.因此,打開一個簡易的抓包工具,tcpdump.然后再次運行程序
誒?果然有一個arp請求出去了!但是....為什么沒有人回應我???
后來經過千方百計調試發現一系列諸多問題:
1.自己的mac地址寫錯了!
2.用short、int等數據類型,這部分字節序是小端.
3.在wifi情況下,將struct addr_in中的sa_data填寫為eth0,數據是不會發出去的.
4.即使什么也不發,如果循環讀取,還是能發現一系列arp廣播,這說明只要打開某個類型的套接字,一直讀取便可監聽該類數據.
5.有一次手賤把#pargma pack(1)刪掉了,但數據結構中存在一個int,導致發出去的包總是被丟棄(通過wireshark看到的).
五、增強用戶使用體驗
至此,發送arp欺騙的核心功能已經實現了,想欺騙,改改代碼重新編譯一下,然后再手動數據自己mac、自己ip、目標mac、目標ip即可.....
當然,如果把這樣的東西拿出去當工具使用,打死我,我都不會說這玩意兒是我自己寫的!
因此,接下來就是要提高用戶使用體驗,要求功能:
1.你要欺騙哪台主機,我只需要知道ip即可.剩下的信息,交給程序自己搞定.
2.要通過哪個接口去欺騙,把接口因素也考慮進去(eth0還是wlan0?由用戶手動輸入)
基於以上,我需要為程序添加很多功能:
1.獲取自身ip與mac
2.獲取目標主機ip與mac
六、獲取自身ip與mac
百度一搜,很多方法:
方法1:http://blog.csdn.net/langeldep/article/details/8306603
方法2:http://www.cnblogs.com/fnlingnzb-learner/p/6425860.html
本來覺得方法一不錯,分析之,手敲之,修改之.....突然發現,誒?為毛我獲取的ip是0.0.0.3?
仔細對比之,原來我沒有做AF_INET判斷....
后來發現方法一,只能獲取ip地址.因此我又對方法二分析之、手敲之、運行之、Ok!
七、獲取目標主機mac
這個就不要百度了,知道目標主機ip,想知道目標主機mac,這不就是arp存在的意義?
因此,我通過想目標主機發送arp請求,根據其arp回應,不就可以獲得其arp???
這么想的同時,我也就這么做了!
結果並不令人滿意.
要么,向某主機發arp,其很久才回.要么,其干脆不回.
這.....這僅僅是arp欺騙的前項步驟,獲取個mac這么慢...還怎么愉快的玩耍?
八、偷師學習之
而且我有些好奇,那我本機上有的arpspoof工具,它是什么獲取目標mac地址的?
運行之,抓包之,分析之,發現:
原來人家做了兩手准備:
1.arp請求之,如果收到回應則獲取成功!
2.udp請求之,udp隨意向某個端口發消息,結果收到了目標主機ICMP報告:目標不可達!!!
看到這里,感嘆其奧妙,默默學習之....
明天再實現udp部分,今天就到此了!
