C#编写IP_MAC防欺骗程序

2024-04-24 01:58

本文主要是介绍C#编写IP_MAC防欺骗程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

单 位的学生成绩管理系统是ASP.NET做的,很担心非法人员修改。为了方便管理,单位的每台机子IP是固定的。由于只是允许办公计算机访问成绩修改的页 面,计算机数量并不多,所以我把所有办公计算机的IP-MAC专门做一张数据库表,且一一对应。操作之前判断来访的IP-MAC地址,且IP-MAC成对 限制。两个地址必须同时正确才可以访问,若不一致则拒绝访问,并且记录该信息,方便我们找出非法操作者。这是我们最初方案,但是程序做好以后,却发现了新 的问题。当有人要做非法操作,会出现以下情况:只修改IP、只修改MAC、同时修改IP-MAC。对于前两种情况,我们的服务器端已全可以判断、限制了。 但是对于情况三,非法操作者成对修改IP-MAC,而且该IP-MAC对是其他被授权的主机的正确IP-MAC对,在服务器端我们已经无力限制。于是便有 了方案二:做一个判断MAC地址是否被修改的Windows服务,这个服务安装在每个客户机上,如果MAC地址被修改,关闭客户端的IE,从而限制访问,
方案一
服务器端实现,实现的关键代码如下:
using System.Runtime.InteropServices ;//请注意引用动态链接库,则需要此命名空间,它提供各种各样支持 COM interop 及平台调用服务的成员。其中最重要的属性有 DllImportAttribute(可以用来定义用于访问非托管 API 的平台调用方法)
[DllImport("iphlpapi.dll", ExactSpelling=true)] //在.net中使用动态链接库
public static int SendARP( int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen );
[DllImport("Ws2_32.dll")]
private static extern Int32 inet_addr(string ip);
private void Button1_Click(object sender, System.EventArgs e)
{
string client_ip=Request.UserHostAddress ;//获得客户端IP
Label_ip.Text =client_ip;
Int32 ldest= inet_addr(client_ip);//将客户端IP转换成目的地的ip
Int32 lhost= inet_addr("192.168.1.80");//本地的ip,也可以自动生成
try
{
byte[] macinfo=new byte[6]; //做一个数组,准备存储MAC地址
int len=macinfo.Length; //得到数组长度
int ii=SendARP(ldest,lhost, macinfo,ref len);//①macinfo就是返回的MAC地址指针
Label_mac.Text ="Mac Add:"+BitConverter.ToString(macinfo,0,len);//将获得的MAC地址转换成易读 的形式
}
catch(Exception err)
{
Label_ip.Text=err.ToString ();//获取系统给出的错误信息
}
}
SendARPSendARP的函数原型如下:
DWORD SendARP(
IPAddr DestIP, // 目标IP地址
IPAddr SrcIP, // 源IP地址
PULONG pMacAddr, // 返回MAC地址指针
PULONG PhyAddrLen // 返回MAC地址长度
);

当有人进行非法操作,会出现如下情况:
1. 只修改IP
2. 只修改MAC
3. 同时修改IP和MAC
情况1,非法操作者做如下修改:选择“本地连接”的属性,进入Internet协议,修改自己IP。
情况2,非法操作者做如下修改:选择“本地连接”的属性。选择“配置”,修改网卡属性。
在 “高级”选项卡选中“Network Address”,默认“值”是“不存在”,非法操作者在“值”中随便填入一个MAC值,达到修改MAC的目的。MAC地址存储在网卡的EEPROM中并 且唯一确定,但网卡驱动在发送Ethernet报文时,并不从EEPROM中读取MAC地址,而是在内存中来建立一块缓存区,Ethernet报文从中读 取源MAC地址。而且,用户可以通过上述方式或者三方软件修改实际发送的Ethernet报文中的源MAC地址。
方案二
它作为一个服务安装在每个客户机上,把服务设置为随Windows启动而启动,禁止“暂停”和“停止”该服务。
加 入一个Timer控件(timer_watchmac),用于确定监控MAC地址值的时间间隔。注意,该控件一定是“工具箱/组件”中的Timer,C# 中有3个Timer控件, System.Timers.Timer(基于服务器的计时器);System.Windows.Forms.Timer(基于 Windows 的标准计时器,位于“工具箱”的“Windows 窗体”选项卡);;System.Threading.Timer(仅可在编程时使用的线程计时器)。它们是不一样的。
服务监控的关键代码如下:
using System.Management ;//要操作WMI需要此命名空间
public string mymac1;//记录原始MAC
public string mymac2;//服务监控当前MAC
初始化服务的时候,就读取本机MAC地址:
protected override void OnStart(string[] args)
{ // TODO: 在此处添加代码以启动服务。
timer_watchmac.Enabled =true;
ManagementClass mcMAC = new anagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection mocMAC = mcMAC.GetInstances();
foreach(ManagementObject m in mocMAC)
{
if((bool)m["IPEnabled"])
{
mymac1= m["MacAddress"].ToString();
break;
}
}
}
在Timer控件的Elapsed(达到间隔时发生)事件添加如下代码:
private void timer_watchmac_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{ //WMI在c#中的使用
ManagementClass mcMAC = new anagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection mocMAC = mcMAC.GetInstances();
foreach(ManagementObject m in mocMAC)//循环实例化管理对象
{
if((bool)m["IPEnabled"])
{ mymac2= m["MacAddress"].ToString();//管理对象(NIC)的当前mac地址
if (mymac2!=mymac1)//发现mac地址被修改
{ //关闭ie浏览器
Process[] myProcesses = Process.GetProcesses();
string test="";
foreach(Process myProcess in myProcesses)//枚举系统当前进程
{ test =myProcess.ProcessName ;
if (test=="IEXPLORE")//发现ie进程,还可以添加其他浏览器进程名称
{ myProcess.Kill (); //关闭ie进程 }
}
}
break;
}
}
}
WMI中Win32_NetworkAdapterConfiguration的定义:
MACAddress
Data type: string
Access type: Read-only //mac地址是只读的
Media Access Control (MAC) address of the network adapter. A MAC address is assigned by the manufacturer to uniquely identify the network adapter.
Example: "00:80:C7:8F:6C:96"
总 结一下我自己的防范方式:在服务器上和客户机上作了双重限制,更为保险的方式是找一个能够直接读取EEPROM地址的三方软件,将它读取的值作为初始值提 供给监视服务,再和当前MAC做比较。这样的话,非法操作者就只有通过修改数据包的方式来进行破坏了。当然现在流行的做法是把IP-MAC和交换机端口绑 定,只是我们公司没有用这种能绑定端口的交换机

这篇关于C#编写IP_MAC防欺骗程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/930469

相关文章

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用

C#中的Converter的具体应用

《C#中的Converter的具体应用》C#中的Converter提供了一种灵活的类型转换机制,本文详细介绍了Converter的基本概念、使用场景,具有一定的参考价值,感兴趣的可以了解一下... 目录Converter的基本概念1. Converter委托2. 使用场景布尔型转换示例示例1:简单的字符串到

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

C#连接SQL server数据库命令的基本步骤

《C#连接SQLserver数据库命令的基本步骤》文章讲解了连接SQLServer数据库的步骤,包括引入命名空间、构建连接字符串、使用SqlConnection和SqlCommand执行SQL操作,... 目录建议配合使用:如何下载和安装SQL server数据库-CSDN博客1. 引入必要的命名空间2.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建