当前位置: 首页 > 科技观察

网络安全编程:U盘防御软件

时间:2023-03-20 19:38:51 科技观察

在互联网还不发达的早期,病毒是通过软盘、光盘等介质传播的。后来,互联网普及后,通过互联网传播的病毒也陆续出现。软盘虽然淘汰了,但并没有减少移动盘的病毒。相反,U盘的普及让移动盘更容易传播病毒。U盘的数据传输速度和数据存储容量都比软盘先进很多。所以,软盘可以传播病毒,U盘也可以传播病毒。通过U盘传播病毒通常是利用操作系统的自动运行功能,配合U盘下的Autorun.inf文件来实现的。著名的“渡口攻击”就是靠这个Autorun.inf来实现的。如果让操作系统不自动运行移动盘,或者确保移动盘下不存在Autorun.inf文件,那么通过U盘感染病毒的几率就会小很多。1、通过系统配置禁止自动运行首先介绍如何通过系统配置禁止U盘中的Autorun.inf自动运行。通常需要进行两种设置,一种是通过“管理工具”中的“服务”进行设置,另一种是通过“组策略”进行设置。通常这两个都需要修改。下面介绍如何设置这两个地方。我们先来看看如何在“服务”中进行设置。首先在控制面板中打开“管理工具”,然后找到“服务”,双击打开。在服务列表中找到名为“ShellHardwareDetection”的服务,双击该服务,打开“ShellHardwareDetectionProperties”对话框。单击“停止”按钮停止该服务,然后将“启动类型”改为“禁用”,如图1所示。图1禁用“ShellHardwareDetection”服务禁用服务中的“ShellHardwareDetection”,然后设置“组策略”。首先在“运行”中输入“gpedit.msc”,然后点击左侧的树状控件“计算机配置”→“管理模板”→“系统”,然后双击右侧的“关闭自动播放”选项,和“关闭自动播放属性”对话框。在“设置”选项卡中,选择“已启用”单项选项,在“关闭自动播放”中选择“所有驱动器”选项,设置完成后单击“确定”按钮然后在左侧树形控件中选择“用户配置”→“管理模板”→“系统”,在右侧找到“自动关闭播放”选项,设置方法同上,如图图2图2组策略中的“关闭自动播放”通过以上设置,对于保护电脑免受U盘相关病毒的侵害确实是比较有效的,但是不能满足,因为目的是制作U盘防御软件。2.制作一个简单的U盘防御软件。这里是一个U盘防火墙。when插入U盘,会有提示,会自动检查U盘中是否有Autorun.inf文件,并对Autorun.inf文件进行分析。另外可以通过U盘防火墙打开U盘,让U盘可以安全使用。怎么知道电脑有没有插U盘?可以用一个定时器持续检测,也可以开一个线程持续检测,也可以通过Windows消息通知。前两种方法有点笨。在这里,与其被动地等待Windows的通知,还不如主动不断地检查是否有U盘插入。在Windows下,有一条消息通知应用程序计算机配置已更改。此消息是WM_DEVICECHANGE。消息处理定义如下:LRESULTCALLBACKWindowProc(HWNDhwnd,UINTuMsg,WPARAMwParam,LPARAMlParam);该消息通过两个额外的参数来使用,其中wParam代表设备变化事件,lParam代表事件对应的数据。获取被插入设备的消息类型,wParam的值为DBT_DEVICEARRIVAL,消息对应的数据类型为DEV_BROADCAST_HDR。结构体定义如下:typedefstruct_DEV_BROADCAST_HDR{DWORDdbch_size;DWORDdbch_devicetype;DWORDdbch_reserved;}DEV_BROADCASTHDR;typedefPD*PDEV_BROADCAST_HDR在这个结构体中,主要看的是dbch_devicetype,也就是设备的类型。结构体转换为DEV_BROADCAST_VOLUME结构体,该结构体定义如下:typedefstruct_DEV_BROADCAST_VOLUME{DWORDdbcv_size;DWORDdbcv_devicetype;DWORDdbcv_reserved;DWORDdbcv_unitmask;WORDdbcv_flags;}DEV_BROADCAST_VOLUME;typedefDEV_BROADCAST_VOLUME*PDEV_BROADCAST_VOLUME;在该结构体中,主要看Theonesaredbcv_unitmaskanddbcv_flags.dbcv_unitmask按位表示逻辑盘符,第0位表示A盘,第1位表示B盘。dbcv_flags表示受影响的盘符或介质,其值为0表示U盘或移动硬盘。上面介绍了WM_DEVICECHANGE消息。由于是在MFC下开发,所以可以使用OnDeviceChange()消息响应函数代替WM_DEVICECHANGE消息。虽然使用OnDeviceChange()消息响应函数代替了WM_DEVICECHANGE,但是响应函数的附加参数与WM_DEVICECHANGE相同。OnDeviceChange()函数定义如下:afx_msgBOOLOnDeviceChange(UINTnEventType,DWORDdwData);3、通过OnDeviceChange()消息获取插入U盘的盘符。接下来用MFC下的OnDeviceChange()消息响应函数写一个方法获取插入的U盘。个性小程序,为编写U盘防火墙做简单的准备工作。首先添加消息映射,具体代码如下:头文件中的BEGIN_MESSAGE_MAP(CUFirewallDlg,CDialog)//{{AFX_MSG_MAP(CUFirewallDlg)ON_MESSAGE(WM_DEVICECHANGE,OnDeviceChange)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICONPE()//}}M_MSG_添加消息响应函数的定义,具体如下://Generatedmessagemapfunctions//{{AFX_MSG(CUFirewallDlg)afx_msgBOOLOnDeviceChange(UINTnEventType,DWORDdwData);//消息响应函数virtualBOOLOnInitDialog();afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);afx_msgvoidOnPaint();afx_msgHCURSOROnQueryDragIcon();//}}AFX_MSG最后加入了消息响应函数的实现,具体代码如下:(pDevHdr->dbch_devicetype==DBT_DEVTYP_VOLUME){PDEV_BROADCAST_VOLUMEpDevVolume=(PDEV_BROADCAST_VOLUME)pDevHdr;//pDevVolume->dbcv_flags为0表示U盘if(pDevVolume->dbcv_flags==0){CStringDriverName;chari;//通过移动pDevVolume->dbcv_unitmask确定盘符DWORDdwUnitmask=pDevVolume->dbcv_unitmask;for(i=0;i<26;++i){if(dwUnitmask&0x1){break;}dwUnitmaskdwUnitmask=dwUnitmask>>1;}if(i>=26){return;}DriverName.Format("检测到的U盘盘符为:%c\r\n",i+'A');//显示盘符MessageBox(DriverName);}}}}编译连接运行,插入U盘,得到提示如图3图3检测U盘盘符上面的代码可以封装成一个函数,封装后的函数定义如下:VOIDGetDriverName(DWORDdwData);当使用以DBT_开头的宏时,如DBT_DEVICEARRIVAL,头文件应包含“dbt.h”文件。4.改进U盘防火墙。之前已经获取到插入U盘的盘符,然后分析U盘中的Autorun.inf文件,删除要运行的程序,也可以安全打开U盘。重写OnDeviceChange()函数以实现所需的功能。具体代码如下:BOOLCUFirewallDlg::OnDeviceChange(UINTnEventType,DWORDdwData){if(nEventType==DBT_DEVICEARRIVAL){GetDriverName(dwData);MessageBox(DriverName);if(DriverName!=""){m_SafeOpen.EnableWindow(TRUE);CStringFile=DriverName;File+="\\autorun.inf";charszBuff[MAX_PATH]={0};if(GetFileAttributes(File.GetBuffer(0))==-1){m_SafeOpen.EnableWindow(FALSE);returnFALSE;}//打开后获取内容GetPrivateProfileString("AutoRun","open",NULL,szBuff,MAX_PATH,File.GetBuffer(0));CStringstr;str="是否删除:";str+=szBuff;if(MessageBox(str,NULL,MB_YESNO)==IDYES){//删除要执行的文件DeleteFile(str.GetBuffer(0));}}}elseif(nEventType==DBT_DEVICEREMOVECOMPLETE){m_SafeOpen.EnableWindow(FALSE);}returnTRUE;}安全打开U盘的实现代码如下:voidCUFirewallDlg::OnBtnSafeopen(){//TODO:AddyourcontrolnotificationhandlercodehereShellExecute(NULL,"open",DriverName.GetBuffer(0),NULL,NULL,SW_SHOW);}使用DeleteFile()函数删除U盘中要运行的程序可能会失败,因为有时候U盘还没有完全准备好。可以通过判断来实现,这里就不给出代码了,大家可以自行修改。该代码涉及两个新的API函数,GetPrivateProfileString()和ShellExecute()。这两个函数的作用分别是获取配置文件中指定键的键值,运行指定的文件或文件夹。上述程序中提示用户选择是否删除U盘中要执行的文件。如果用户对此没有太多的了解和了解,很可能不会删除。如果删除了不该删除的文件,用户对软件的友好度就会降低。我们应该怎么做?应该建立白名单和黑名单,不管是按hash比较,还是按文件名比较,都无所谓。当然,匹配方法越精确越好。这样可以提前判断用户,然后给出安全建议,既提高了软件的友好性,又显得相对专业。