剑走偏锋 您所在的位置:网站首页 剑走偏锋的出处 剑走偏锋

剑走偏锋

2024-07-14 16:01| 来源: 网络整理| 查看: 265

剑走偏锋-使用WMI获取远程计算机进程程序

集中查毒病毒打造内网安全环境

 

作者:高玉涵

时间:2019.04.18 15:45

博客:blog.csdn.net/cg_i

作者背景环境参见:

《由永恒之蓝病毒引发的运维安全思考——网络边界防御篇 》

《非常运维 一体化终端安全管理系统自动安装脚本详解》

 

TMOTWTDI -- Perl名言

真正见功夫的地方不在于代码本身,而在于对平台的理解和驾驭能力,可能这就是俗称的“内功”。-- 高玉涵

我希望不曾写过这个程序。--高玉涵

 

引言

信息安全是运维的根本,直接关系到企业的安危,稍有不慎会造成灾难性后果。比如近段时间,世界范围内爆发的“勒索病毒”事件,另外,国内知名门户网站因系统安全漏洞、病毒引发的数据外泄事件等。因此,信息安全体系建设已经被提到了前所未有的高度。如何提升企业的安全防范水准是目前普遍面临的问题。

很高兴在我写这篇文章时,公司内网环境,正全省统一部署“一体化”终端安全管理系统(简称:管理系统)。这套系统是一整套的内网安全管理解决方案,部署后将彻底解决,我一直苦恼的内网安全问题,提高内网抵御各种风险的能力,我想同样管理着上百台“裸奔”系统机器,并深受其害的同行,应该倍感鼓舞吧!

迫于硬件配置太低,我所在单位内网终端设备(硬件配置:Atom D2560 CPU2.0GHz、DDR2 2G内存、STAT2 160G硬盘、Windows XP Embedded (XPe) 32位)安装管理系统后,业务办理过程中,卡顿感明显(欣慰的是,总部已经意识到这些问题,正差手解决中),身为系统管理人员,在系统安全可控的前提下(《由永恒之蓝病毒引发的运维安全思考——网络边界防御篇 》文中简单介绍了,笔者在系统“祼奔”状态下,做的一些系统控制,防范系统安全的一些尝试,方法还是较为原始),确保各项业务正常办理是首要职责,无奈之下只好“壮士断腕”将防病毒模块卸载(防病毒模块资源占用较大、策略较为严格,会拦截业务系统调用的一些插件,导致某些业务无法理)。

显而易见“自己感冒了都会害怕,传染给电脑呢?”没有防病毒模块的保护,系统安全根本无从谈起。在等待总部给出最终解决方案之前,现有系统控制措施依然有效,安全依然可控。能否在这段过度期间,提高内网系统抵御病毒能力,做到全网范围内,某台终端设备中毒,早发现、早查杀,将风险与损失降到最低?

本文主要讲述,通过Windows管理规范(Windows Management Instrumentation,WMI)技术,实现集中式的病毒扫描机制的方法。显然,WMI是一个庞大的话题,用几本书的篇幅也讲不完,因此,我只能在本文中给出最简短的概览、设计思路、示例代码,同时与大家分享。希望,对你的工作有所帮助,起到举一反三的效果。

 

集中查毒设计思路图

(图 1 客户端程序与计算机的WMI服务通信)

图1一个WMI客户端程序,定期轮询内网所有计算机,获取远程计算机当前系统运行的进程信息,并将进程程序文件,上转至集中查毒服务器。服务器还提供FTP文件服务功能,用于存放待“抽检”的文件,以远程计算机IP地址命名的文件夹内,标识各自所属内网的那台计算机,一但杀毒程序发现病毒,通过文件夹名称,即可定位内网已中毒的计算机,及时了解内网健康情况,达到早发现、早查杀,将风险与损失降到最低的目的。

你可能会问的一些问题

1.SpotCheck.vbs是什么?

我称之为“抽样检查”程序。抽样检查,是从一批产品中随机抽取少量产品(样本) 进行检验,据以判断该批产品是否合格的统计方法和理论。就像我们人需要定期做体验一样,通过设置“抽检”程序定期执行,可及时了解内网健康情况,做出相对应的诊察手段。

2.为什么是进程程序文件?

远程计算机动辄数十GB至数百GB字节的数据,都传到服务器进行查毒是不现实的(也太傻了)。病毒或恶意程序,要保持传染、窃取、破坏等能力,就必须保持“活性”(驻留在系统进程中)。我们只需“抽检”这部份数据即可达到目地。

 

用Windows Script Host进行脚本编程

 

在我不长的从业生涯中,学习过数十种计算机语言,学习它们的背景都是因为系统间某些限制或更善长完成特定任务(有些纯粹是因为好奇)。这带来一个好处,让我避免了系统间的限制和兼容问题,根据要执行任务的平台,以它最自然的语言来完成任务。当然这也会带来一些困扰,如,编写代码时各种“方言”会混淆的写在一起。

显然我这个程序主要应用在Windows平台上,程序生命周期定位在“过渡”期内。所以,程序即要充分利用Windows平台提供的强大功能、编写过程也不能太复杂。

用VBScript脚本语言来完成此类任务,可以说是再合适不过了。VBScript是Microsoft自已的脚本语言很容易上手,其实编写之初,我几乎已经忘记这门语言,我从网上下了一份简明教程,通过几个小时的学习,就可以上手编写程序了。

另一方面,它直接可以同Windows对话,例如DLL对象、COM对象、Windows API类库等等,掌握后可以用它完成Windows下所有的工作,而不必通过复杂的编程环境。

 

Windows管理规范(WMI)

 

如果你有一台Windows计算机,维护可能是一项令人沮丧的、耗费时间的工作。将这放大数百倍或数千倍。想象一下公司IT经理每天所要面对的事情(我就是这个苦逼的IT经理)。仅仅是记录计算机库存就是很大的一项任务,然后,有频繁的网络设置更改、网络打印机的添加删除、更新应用程序和移动目标共享文件夹,更别提系统崩溃、硬件失效和用户导致的灾难了,将组织的计算机聚集在一起,就像是试图在水中用手握住50个乒乓球。IT工作是进入隔离病房接受一些正式药物治疗的章程票。

摆脱这种错乱的一种方法是,尽可能地避免从一台计算机走到另一台计算机去做更改。在较大的网络中需求更加迫切。WMI则可以帮助减轻维护负担。WMI提供了一种方式来深入查看Windows的内部工作,监视设置并做出修改。WMI伸手触及到Windows操作系统的每个方面,包括设备驱动、系统服务和应用程序。WMI通过网络来工作,因此,运行一个WMI监视程序(或脚本)的计算机可以进入到组织的网上的任何计算机。

 

别急“压轴好戏”就要上场了

 

我知道你们急着想看代码,前面的内容如让你感到无趣或啰嗦,先在此表示歉意。为了保证程序能够正常运行,在这之前,我们还是先看看程序运行后的样子和一些注意事项。

1.程序文件

SpotCheck.vbs主程序文件,log.txt是程序运行后生成的日志文件,内容如下面的样子:

......

GetCurrentProcess():C:\WINDOWS\System32\smss.exe,C:\WINDOWS\system32\csrss.exe,C:\WINDOWS\system32\winlogon.exe,C:\WINDOWS\system32\services.exe,C:\WINDOWS\system32\lsass.exe,C:\WINDOWS\system32\cmd.exe,C:\WINDOWS\system32\ftp.exe,

2019/4/8 15:20:22 remote_assembly_upload_file:Method returned result = 0 Id of new process is 3628

2019/4/8 15:20:23 package_team:Method returned result = 0 Id of new process is 1860

2019/4/8 15:20:23 package_team:Method returned result = 0 Id of new process is 6568

2019/4/8 15:20:24 package_team:Method returned result = 0 Id of new process is 6232

......

可以看出日志中记录了GetCurrentProcess()函数,获取的当前进程运行的所有程序,并给出它们的绝对路径,文件间以逗号分隔,这些就是送去“抽检”的文件。

日志文件中还有一些其它信息,它们是程序运行过程中,函数运行状态,有性趣的同学,可通过研究源来代码来了解它们。

1.远程计算机需要做的一些工作

如果远程计算机启用了防火墙,使用netsh firewall set service RemoteAdmin命令,使防火墙允许远程登录。

在工作组网络上WindowsXP系统,要禁用“简单共享”操作如下:1.单击“开始->运行”,输入“gpedit.msc”回车,打开“组策略编辑器”,计算机配置→Windows设置→安全设置→本地策略→安全选项”;2.右边双击“网络访问:本地帐户的共享和安全模式”打开其属性对话框,更改成“经典_本地用户以自己的身份验证”选项。

 

SpotCheck程序示例源码

'*********************************************************************************** '* '* File: SpotCheck.vbs '* Author: 高玉涵 '* Blog: blog.csdn.net/cg_i '* Created: 2019/4/6 '* Last Modified:2019/4/9 '* Version: 0.1 '* Declaration: '* 抽样检查程序,通过WMI技术获取远程计算机进程文件,传至指定集中杀毒服务器 '* 根据查杀结果了解内网计算机健康情况,做出相对应的诊察手段。 '*********************************************************************************** Option Explicit 'BUG = 1,显示错误信息; public const BUG = 1 public const output_log_file = "log.txt" public const ForReading = 1, ForWriting = 2, ForAppending = 8 public locator,svcs dim computer dim username dim password computer = "192.168.0.x" username = "你的用户名" password = "你的密码" '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2016/8/16 ' Version: 0.1 ' Name: output_log ' Declare: 写日志 ' parameter: ' strFileName 文件名 ' strMsg 信息 ' mode: ' ForReading = 1, ForWriting = 2, ForAppending = 8 '---------------------------------------------------------------------- Sub output_log(strFileName,mode,strMsg) Dim fso,file,stream Set fso = CreateObject("Scripting.FileSystemObject") Set stream = fso.OpenTextFile(strFileName,mode,True) stream.WriteLine(Now & vbTab & strMsg & vbcrlf) stream.close End Sub '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/6 ' Version: 0.1 ' Name: manage ' Declare: 管理计算机 ' parameter: ' computername 计算机名或IP ' username 用户名 ' password 密码 ' return: True,False '---------------------------------------------------------------------- function manage(computername, username, password) set locator = CreateObject("WbemScripting.SWbemLocator") on error resume next set svcs = locator.ConnectServer(computername, "root\CIMV2", username, password) if err 0 then if BUG then WScript.Echo "manage():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "manage():" & Err.Description, "0x" & Hex(Err.Number) manage = False exit function end if manage = True end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/6 ' Version: 0.1 ' Name: GetCurrentProcess ' Declare: 获取当前系统进程 ' parameter: ' svcs 计算机SWbemServices对象 ' return: 成功,返回每个进程执行路径字符串,以逗号分隔。失败,为空 '---------------------------------------------------------------------- function GetCurrentProcess(svcs) Const wbemFlagReturnImmediately = &h10 Const wbemFlagForwardOnly = &h20 dim processes,process,strTmp on error resume next set processes = svcs.ExecQuery("SELECT * FROM Win32_Process", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly) for each process in processes if process.ExecutablePath vbEmpty and process.ExecutablePath "" then strTmp = strTmp & process.ExecutablePath & "," next if err 0 then if BUG then WScript.Echo "GetCurrentProcess():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "GetCurrentProcess():" & Err.Description, "0x" & Hex(Err.Number) GetCurrentProcess = Nothing exit function end if GetCurrentProcess = strTmp end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/7 ' Version: 0.1 ' Name: remote_assembly_upload_file ' Declare: 远程组装上转文件 ' parameter: ' svcs 计算机SWbemServices对象 ' ftp_command_template FTP命令模板 ' ftp_command_file 组装到的远程目标文件(全路径) ' return: 成功,TRUE 失败,FALSE '---------------------------------------------------------------------- function remote_assembly_upload_file(svcs,ftp_command_template,ftp_command_file) dim result,process,processid,packages,pack on error resume next set process = svcs.Get("Win32_Process") result = process.Create("cmd /c echo.>" & ftp_command_file, null, null, processid) output_log output_log_file, ForAppending, "remote_assembly_upload_file:Method returned result = " & result & " " & "Id of new process is " & processid packages = split(ftp_command_template, vbcrlf) for each pack in packages if not package_team(svcs, pack, ftp_command_file) then exit for end if next if err 0 then if BUG then WScript.Echo "remote_assembly_upload_file():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "remote_assembly_upload_file():" & Err.Description, "0x" & Hex(Err.Number) remote_assembly_upload_file = False exit function end if remote_assembly_upload_file = True end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/7 ' Version: 0.1 ' Name: package_team ' Declare: 包装小队 - remote_assembly_upload_file函数的调用 ' parameter: ' svcs 计算机SWbemServices对象 ' ftp_command_file 组装到的远程目标文件(全路径) ' return: 成功,True 失败,False '---------------------------------------------------------------------- function package_team(svcs,pack,ftp_command_file) dim result,process,processid on error resume next set process = svcs.Get("Win32_Process") result = process.Create("cmd /c echo " & pack & ">>" & ftp_command_file,null,null,processid) output_log output_log_file, ForAppending, "package_team:Method returned result = " & result & " " & "Id of new process is " & processid if err 0 then if BUG then WScript.Echo "package_team():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "package_team():" & Err.Description, "0x" & Hex(Err.Number) package_team = False exit function end if package_team = True end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/8 ' Version: 0.1 ' Name: ftp_upload ' Declare: FTP上转 ' parameter: ' svcs 计算机SWbemServices对象 ' ftp_command_file FTP配置文件(全路径) ' return: 成功,True 失败,False '---------------------------------------------------------------------- function ftp_upload(svcs,ftp_command_file) dim result,process,processid on error resume next set process = svcs.Get("Win32_Process") result = process.Create("cmd /c ftp -i -s:" & ftp_command_file,null,null,processid) output_log output_log_file, ForAppending, "ftp_upload:Method returned result = " & result & " " & "Id of new process is " & processid if err 0 then if BUG then WScript.Echo "ftp_upload():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "ftp_upload():" & Err.Description, "0x" & Hex(Err.Number) ftp_upload = False exit function end if ftp_upload = True end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/6 ' Version: 0.1 ' Name: IPAddress ' Declare: 获取IP地址 ' parameter: ' svcs 计算机SWbemServices对象 ' ip_prefix IP前缀 ' return: 成功,返回指定前缀的IP。失败,返回NULL '---------------------------------------------------------------------- function IPAddress(svcs, ip_prefix) dim interface,inter,ip,i on error resume next set interface = svcs.InstancesOf("Win32_NetworkAdapterConfiguration") for each inter in interface if not isnull(inter.IPAddress) then for each ip in inter.IPAddress if instr(ip, ip_prefix) then IPAddress = ip exit function end if next end if next if err 0 then if BUG then WScript.Echo "IPAddress():" & Err.Description, "0x" & Hex(Err.Number) output_log output_log_file, ForAppending, "IPAddress():" & Err.Description, "0x" & Hex(Err.Number) end if IPAddress = Nothing end function '---------------------------------------------------------------------- ' Author: 高玉涵 ' Created: 2019/4/6 ' Version: 0.1 ' Name: generate_Upload_Template ' Declare: 生成FTP上转模板 ' parameter: ' LocalIPAddress 本地IP ' arrayProcess 本地进程数组 ' ftp_host FTP服务器 ' ftp_user FTP用户名 ' ftp_password FTP密码 ' return: 成功,返回组装后的模板。失败,未知 '---------------------------------------------------------------------- function generate_upload_template(LocalIPAddress,arrayProcess,ftp_host,ftp_user,ftp_password) dim template,process template = template & "open " & ftp_host & vbcrlf template = template & ftp_user & vbcrlf template = template & ftp_password & vbcrlf template = template & "mkdir " & LocalIPAddress & vbcrlf template = template & "cd " & LocalIPAddress & vbcrlf template = template & "BINARY" & vbcrlf for each process in arrayProcess if not process = " " then template = template & "put " & process & vbcrlf end if next generate_Upload_Template = template end function dim arrayProcess,LocalIPAddress,template,ftp_command_file,result ftp_command_file = "c:\\upload.txt" if manage(computer, username, password) then result = GetCurrentProcess(svcs) if not result = vbEmpty then output_log output_log_file, ForAppending, "GetCurrentProcess():" & result arrayProcess = split(result, ",") LocalIPAddress = IPAddress(svcs, "192") template = generate_Upload_Template(LocalIPAddress,arrayProcess,"192.168.0.x","ftp01","ftp01") remote_assembly_upload_file svcs,template,ftp_command_file ftp_upload svcs,ftp_command_file end if end if wscript.echo "exit"

写在最后

 

最后,向和我一样为确保全省IT系统安全,奋斗在基层一线的全体同仁致敬!

不抱怨的世界。

只是别让时间,

消磨了我们心中的火焰......

 

2019/4/9

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有