[探索]Linux下用C语言写Arp欺骗工具(一)

  本系列文章主要讲述自己如何从零开始研究,用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部分,今天就到此了!

posted @ 2017-07-05 20:52  Linux专题站  阅读(2848)  评论(0编辑  收藏  举报