单位的学生成绩管理系统是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 ;//获得客户端IPLabel_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. 只修改IP2. 只修改MAC3. 同时修改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;//记录原始MACpublic 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: stringAccess 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和交换机端口绑定,只是我们公司没有用这种能绑定端口的交换机。因此只能靠软件了,上帝保佑,阿门!

评论