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

[[405637]]

 在早期互联网还不发达的时候,病毒都是通过软盘、光盘等媒介进行传播的。到后来互联网被普及以后,通过互联网进行传播的病毒大面积地相继出现。虽然软盘已经被淘汰,但是并没有使移动磁盘的病毒减少。相反,U盘的普及使得移动磁盘对病毒的传播更加方便。U盘的数据传输速度和数据存储容量等多方面都比软盘要先进很多,因此,软盘可以传播病毒,U盘当然也可以传播病毒。

通过U盘来传播病毒通常是使用操作系统的自动运行功能,并配合U盘下的Autorun.inf文件来实现的。著名的“摆渡攻击”就是依靠此Autorun.inf来进行实施的。如果让操作系统不自动运行移动磁盘,或者保证移动磁盘下不存在Autorun.inf文件,那么通过U盘感染病毒的几率就小很多了。

1. 通过系统配置禁止自动运行

先来介绍如何通过系统配置禁止U盘中Autorun.inf的自动运行。通常情况下需要进行两方面的设置,一方面是通过“管理工具”中的“服务”来进行设置,另一方面是通过“组策略”来进行设置。一般这两处都需要进行修改。下面分别介绍如何对这两处进行设置。

先来看如何在“服务”中进行设置。首先打开控制面板中的“管理工具”,然后找到“服务”,将其双击打开。在服务列表中找到名称为“Shell Hardware Detection”的服务,双击该服务,打开“Shell Hardware Detection的属性”对话框。单击“停止”按钮将该服务停止,再把“启动类型”修改为“已禁用”状态,如图1所示。

图1  禁用“Shell Hardware Detection”服务

将服务中的“Shell Hardware Detection”禁用后,再对“组策略”进行设置。首先在“运行”中输入“gpedit.msc”,然后依次单击左边的树形控件“计算机配置”→“管理模板”→“系统”,再在右边双击“关闭自动播放”选项,弹出“关闭自动播放属性”对话框。在“设置”选项卡中选择“已启用”单选项,在“关闭自动播放”处选择“所有驱动器”选项,设置完成后单击“确定”按钮。再到左边的树形控件中选择“用户配置”→“管理模板”→“系统”,到右边找到“自动关闭播放”选项,设置方法同上,如图2所示。

图2  组策略中的“关闭自动播放”

通过以上设置,的确可以相对有效地保护计算机不中U盘相关的病毒。不过,不能因此而满足,因为目的是打造一个U盘防御的软件。

2. 打造一个简易的U盘防御软件

这里打造一个U盘防火墙,当插入U盘时会有提示,并且自动检查U盘下是否有Autorun.inf文件,并解析Autorun.inf文件。除此之外,通过U盘防火墙可以打开U盘,从而安全地使用U盘。

如何才能知道有U盘被插入电脑呢?可以使用定时器不断地检查,也可以开启一个线程不断地检查,还可以通过Windows的消息得到通知。前两种方法笨了些,这里主动不断地检查是否有U盘插入,不如被动地等待Windows的消息来通知。

在Windows下有一个消息可以通知应用程序计算机配置发生了变化,这个消息是WM_ DEVICECHANGE。消息过程定义如下: 

  1. LRESULT CALLBACK WindowProc(  
  2.  HWND hwnd, 
  3.  UINT uMsg,  
  4.  WPARAM wParam,  
  5.  LPARAM lParam  
  6. ); 

该消息通过两个附加参数来进行使用,其中wParam表示设备改变的事件,lParam表示事件对应的数据。要得到设备被插入的消息类型,因此wParam的取值为DBT_DEVIC EARRIVAL,而该消息对应的数据类型为DEV_BROADCAST_HDR,该结构体的定义如下: 

  1. typedef struct _DEV_BROADCAST_HDR {  
  2.  DWORD dbch_size;  
  3.  DWORD dbch_devicetype;  
  4.  DWORD dbch_reserved;  
  5. } DEV_BROADCAST_HDR;  
  6. typedef DEV_BROADCAST_HDR *PDEV_BROADCAST_HDR; 

在该结构体中,主要看的是dbch_devicetype,也就是设备的类型。如果设备类型为DBT_DEVTYP_VOLUME,则把当前结构体转换为DEV_BROADCAST_VOLUME结构体,该结构体定义如下: 

  1. typedef struct _DEV_BROADCAST_VOLUME {  
  2.  DWORD dbcv_size;  
  3.  DWORD dbcv_devicetype;  
  4.  DWORD dbcv_reserved;  
  5.  DWORD dbcv_unitmask;  
  6.  WORD dbcv_flags;  
  7. } DEV_BROADCAST_VOLUME;  
  8. typedef DEV_BROADCAST_VOLUME *PDEV_BROADCAST_VOLUME; 

在该结构体中,主要看的是dbcv_unitmask和dbcv_flags。dbcv_unitmask通过位表示逻辑盘符,第0位表示A盘,第1位表示B盘。dbcv_flags表示受影响的盘符或媒介,其值为0时表示U盘或移动硬盘。

上面介绍了WM_DEVICECHANGE消息,由于是在MFC下进行开发的,因此可以使用OnDeviceChange()消息响应函数来代替WM_DEVICECHANGE消息。虽然使用了OnDeviceChange()消息响应函数而没有使用WM_DEVICECHANGE,但是响应函数的附加参数与WM_DEVICECHANGE相同。OnDeviceChange()函数定义如下:

  1. afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData ); 

3. 通过OnDeviceChange()消息获得被插入U盘的盘符

下面使用MFC下的OnDeviceChange()消息响应函数来编写一个获取被插入U盘的盘符的小程序,为编写U盘防火墙做简单的准备工作。首先来添加消息映射,具体代码如下: 

  1. BEGIN_MESSAGE_MAP(CUFirewallDlg, CDialog)  
  2.  //{{AFX_MSG_MAP(CUFirewallDlg)  
  3.  ON_MESSAGE(WM_DEVICECHANGE, OnDeviceChange)  
  4.  ON_WM_SYSCOMMAND()  
  5.  ON_WM_PAINT()  
  6.  ON_WM_QUERYDRAGICON()  
  7.  //}}AFX_MSG_MAP  
  8. END_MESSAGE_MAP() 

在头文件中添加消息响应函数的定义,具体如下: 

  1. // Generated message map functions  
  2. //{{AFX_MSG(CUFirewallDlg)  
  3. afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData); // 消息响应函数  
  4. virtual BOOL OnInitDialog();  
  5. afx_msg void OnSysCommand(UINT nID, LPARAM lParam);  
  6. afx_msg void OnPaint();  
  7. afx_msg HCURSOR OnQueryDragIcon();  
  8. //}}AFX_MSG 

最后添加消息响应函数的实现,具体代码如下: 

  1. BOOL CUFirewallDlg::OnDeviceChange(UINT nEventType, DWORD dwData)  
  2.  
  3.   if ( nEventType == DBT_DEVICEARRIVAL )  
  4.   {  
  5.     PDEV_BROADCAST_HDR pDevHdr = (PDEV_BROADCAST_HDR)dwData;  
  6.     if ( pDevHdr->dbch_devicetype == DBT_DEVTYP_VOLUME )  
  7.     {  
  8.       PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pDevHdr;  
  9.       // pDevVolume->dbcv_flags 为 0 表示为 U 盘  
  10.       if ( pDevVolume->dbcv_flags == 0 )  
  11.       {  
  12.         CString DriverName;  
  13.         char i;  
  14.         // 通过将 pDevVolume->dbcv_unitmask 移位来判断盘符  
  15.         DWORD dwUnitmask = pDevVolume->dbcv_unitmask;  
  16.         for (i = 0; i < 26; ++i)  
  17.         {  
  18.           if ( dwUnitmask & 0x1)  
  19.           {  
  20.             break;  
  21.           }  
  22.           dwUnitmaskdwUnitmask = dwUnitmask >> 1;  
  23.         }  
  24.         if ( i >= 26 )  
  25.         {  
  26.           return ;  
  27.         }  
  28.         DriverName.Format("检测到的 U 盘盘符为: %c \r\n", i + 'A');  
  29.         // 显示盘符  
  30.         MessageBox(DriverName);  
  31.       }  
  32.     }  
  33.   }  

将其编译连接并运行,插入一个U盘,得到如图3所示的提示。

[[405638]]

图3  检测到的U盘盘符

上面的这段代码可以将其封装为一个函数,封装后的函数定义如下: 

  1. VOID GetDriverName(DWORD dwData); 

在使用类似DBT_DEVICEARRIVAL的以DBT_开头的宏时,应包含头文件“dbt.h”文件。

4. U盘防火墙的完善

前面已经获得了被插入U盘的盘符,接下来就可以对U盘上的Autorun.inf文件进行分析,并删除要运行的程序,还可以安全地打开U盘。改写OnDeviceChange()函数,以实现要完成的功能,具体代码如下: 

  1. BOOL CUFirewallDlg::OnDeviceChange(UINT nEventType, DWORD dwData)  
  2.  
  3.   if ( nEventType == DBT_DEVICEARRIVAL )  
  4.   { 
  5.     GetDriverName(dwData);  
  6.     MessageBox(DriverName);  
  7.     if ( DriverName != "" )  
  8.     {  
  9.       m_SafeOpen.EnableWindow(TRUE);  
  10.       CString File = DriverName 
  11.       File += "\\autorun.inf";  
  12.       char szBuff[MAX_PATH] = { 0 };  
  13.       if ( GetFileAttributes(File.GetBuffer(0)) == -1 )  
  14.       {  
  15.         m_SafeOpen.EnableWindow(FALSE);  
  16.         return FALSE;  
  17.       }  
  18.       // 获取 open 后面的内容  
  19.       GetPrivateProfileString("AutoRun","open",  
  20.         NULL,szBuff,MAX_PATH,File.GetBuffer(0));  
  21.       CString str;  
  22.       str = "是否删除:" 
  23.       str += szBuff;  
  24.       if ( MessageBox(str, NULL, MB_YESNO) == IDYES )  
  25.       {  
  26.         // 删除要执行的文件  
  27.         DeleteFile(str.GetBuffer(0));  
  28.       }  
  29.     }  
  30.   }  
  31.   else if ( nEventType == DBT_DEVICEREMOVECOMPLETE )  
  32.   {  
  33.     m_SafeOpen.EnableWindow(FALSE);  
  34.   }  
  35.   return TRUE;  

安全打开U盘的实现代码如下: 

  1. void CUFirewallDlg::OnBtnSafeopen()  
  2.  
  3.   // TODO: Add your control notification handler code here  
  4.   ShellExecute(NULL, "open", DriverName.GetBuffer(0), NULL, NULL, SW_SHOW);  

用DeleteFile()函数删除U盘中要运行的程序可能会失败,因为有时U盘并没有完全准备好。可以通过判断来完成,但这里就不给出代码了,大家可自行修改完成。代码中涉及两个新的API函数,分别是GetPrivateProfileString()和ShellExecute()。这两个函数的功能分别是获取配置文件中指定键的键值、运行指定的文件或文件夹。

在上面的程序中,通过提示让用户选择是否要删除U盘中要被执行的文件。如果用户对此并没有太多的了解和认识的话,很有可能不删除。如果删了本不该删的文件,那么用户对该软件的友好感便会降低。应该如何做呢?应该建立一个白名单和黑名单,无论是通过散列进行比较,还是通过文件名进行比较,都可以。当然,越精确的匹配方法越好。这样,就可以提早为用户进行判断了,然后给出一个安全建议,这样不但提高了软件的友好度,而且会显得相对较为专业。 

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/132643.html<

(0)
运维的头像运维
上一篇2025-02-27 02:57
下一篇 2025-02-27 02:59

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注