☰
VBS整人代码拆解:从wscript.exe执行链到清理加固
2026/10/29 11:14:25 网站建设 项目流程

简介:这份资源是一份VBS整人代码合集文档,面向对VBS脚本感兴趣的初学者、脚本爱好者以及希望在虚拟机中做安全演示的教学者。内容涵盖MsgBox消息框弹窗、模拟系统警告、通过WScript.Shell调用shutdown等系统命令、Do...Loop无限循环、If...Then...Else条件判断与InputBox输入验证、SendKeys键盘模拟以及WMPlayer.ocx媒体播放等典型脚本技巧,可帮助读者理解VBS的基础语法与对象调用方式。压缩包内仅1个docx文档,约192KB,以代码段与效果说明穿插的方式编排,便于对照阅读和按需检索。目前已有11804人学习下载,适合作为脚本语法的反面案例参考,也提醒读者在尊重他人电脑使用权的前提下,用技术创造积极体验。

1. 一段会自我复制的“玩笑”:VBS 整人代码为什么值得认真拆一遍

早上开机,屏幕弹出一个标题写着“系统提示”的对话框,告诉你输入一句话就能取消关机,否则 300 秒后倒计时归零。你以为是驱动出了问题,重装系统,第二天一早又发生了;最后发现根源是一根借来用过的 U 盘,根目录里躺着autorun.inf和两个隐藏属性的.vbs。这套流程里没有任何编译、没有管理员密码、没有第三方工具,全部由 Windows 自带的脚本宿主完成——这就是 VBS 整人代码的真实成本:写的人花十分钟,清的人花半天。

把这份“大全”当作攻击面教材读,价值远高于当作玩具读。它几乎覆盖了脚本层能做的全部“低技术”动作:伪造弹窗、调用系统命令、模拟按键、写文件并借移动介质扩散。下面按执行链、手法、复现、排查、加固的顺序拆开,每一段都落到能照着做的步骤上。适合两类人:想搞清楚脚本层到底能干什么的运维和安全初学者,以及被这类东西烦过一次、想给自己机器上个笼子的普通用户。

2. VBScript 能碰到系统哪几层:从双击到 wscript.exe 的执行链

2.1 双击一个 .vbs 之后,系统做了什么

.vbs是纯文本,Windows 靠文件关联把它交给脚本宿主解释执行,不产生.exe,所以杀毒软件的静态特征库对它的识别率天然偏低。关联关系写在注册表的HKEY_CLASSES_ROOT\.vbs下,默认指向VBSFile,再由VBSFile\Shell\Open\Command决定用哪个宿主。

宿主有两个:wscript.exe是窗口版,MsgBox弹的是图形对话框;cscript.exe是控制台版,MsgBox会退化成交互式命令行提示。整人脚本清一色走wscript.exe,因为图形弹窗更有欺骗性,也因为wscript.exe不带控制台窗口——任务栏上看不见,任务管理器里只能看到一个同名进程,普通用户第一反应是“我没开这个啊”。

关键的一点是权限继承:脚本以当前登录用户的令牌运行,不需要 UAC 提权就能弹窗、读写用户目录、调用shutdown。关机权限(SeShutdownPrivilege)普通用户默认持有,这就是为什么一个几十行的脚本能真的把机器关掉。反过来,写C:\Windows、改HKLM下的键、装服务,就必须提权,所以整人脚本的落地位置基本集中在三类:当前用户目录、各盘根目录、以及可移动介质。

2.2 四个对象撑起几乎所有手法

整人脚本翻来覆去就那几个 COM 对象。把能力边界列清楚,后面看任何一段代码都能立刻判断它想干什么、能造成多大影响。

对象 ProgID创建方式常用方法/属性能做到做不到
WScript.ShellCreateObject("WScript.Shell")Run、SendKeys、RegRead/RegWrite、Popup启动任意命令、注入按键、读写HKCU直接操作窗口句柄、绕过 UAC
Scripting.FileSystemObjectCreateObject("Scripting.FileSystemObject")GetFile、Copy、Delete、CreateTextFile、Attributes复制自身、改隐藏属性、写autorun.inf修改被占用的系统文件
WScript.NetworkCreateObject("WScript.Network")MapNetworkDrive、EnumNetworkDrives映射共享盘、枚举已映射盘符无凭据访问受限共享
WMPlayer.OCX/SAPI.SpVoiceCreateObject("WMPlayer.OCX")、CreateObject("SAPI.SpVoice")cdromcollection.item(0).eject()、Speak弹光驱、循环朗读需要对应组件存在

WScript.Shell.Run的签名是Run(strCommand, intWindowStyle, bWaitOnReturn)。第二个参数0表示隐藏窗口,第三参数True表示等命令结束再往下走。整人脚本最爱写Run "cmd /c shutdown -s -t 5", 0, True——隐藏、阻塞、用户看不到任何命令行痕迹,只能看着关机倒计时。

2.3 六行代码验证你的环境,且随时能停

先确认这台机器到底还能不能跑 VBScript,用一段带取消按钮、有次数上限的脚本试水。别上来就跑死循环,那是给自己找麻烦。

' env_check.vbs —— 有上限的弹窗测试,随时可停 Option Explicit Dim sh, i, ret Set sh = CreateObject("WScript.Shell") For i = 1 To 3 ' 上限 3 次,不是死循环 ret = MsgBox("第 " & i & " 次弹窗,点取消结束测试", _ vbOKCancel + vbInformation, "环境检查") If ret = vbCancel Then Exit For ' 用户主动退出 Next MsgBox "脚本宿主可用,系统版本 " & sh.RegRead( _ "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion"), _ vbInformation, "结果"

逻辑很直白:For循环给死上限,vbOKCancel让用户永远有一条退路,vbInformation只是图标不影响行为。RegRead读版本号是为了证明这个对象确实能碰注册表——能读就能写HKCU下的键,这也是后面自启动排查要盯的位置。Option Explicit建议每个脚本都加,拼错变量名会直接报错而不是静默变成Empty,调试时能省很多时间。

如果这段跑起来直接弹“没有文件关联的程序”,或者双击后记事本打开了文件,说明这台机器的.vbs关联被改过,或者脚本引擎被关掉了。较新的系统版本里,VBScript 已经作为按需功能提供,默认不一定启用,这也意味着很多老脚本在新机器上根本跑不起来——这一点在评估“这份资源还能不能用”时很关键。

2.4 执行策略与位数:哪些机器上它压根不生效

wscript.exe有 32 位和 64 位两份,分别在System32和SysWOW64下,文件关联指向哪一份会影响CreateObject的解析。64 位宿主创建 32 位专用组件会失败,报“ActiveX 部件不能创建对象”。这也是很多人复制粘贴脚本后一脸茫然的原因:代码没错,宿主选错了。

另一层是软件限制策略。企业环境里常见做法是通过 AppLocker 或 SRP 禁止%SystemRoot%\System32\wscript.exe与cscript.exe执行,一旦生效,双击.vbs只会得到一句“此程序被组策略阻止”。个人机器上更轻的做法是直接把.vbs的文件关联改成记事本,双击只查看不执行——粗暴但有效,代价是自己也没法跑正常的运维脚本。

3. 拆解四类整人手法:弹窗伪装、关机倒计时、按键注入与自复制

3.1 MsgBox 的四个参数,和“假系统提示”的伪装原理

MsgBox(prompt, buttons, title, helpfile, context)只有前三个参数常被用到,但就这三个足以做出以假乱真的系统对话框。buttons是按钮、图标、默认按钮三组值的按位相加,常用的取值如下。

常量值效果
vbOKOnly0只有一个“确定”
vbOKCancel1确定 / 取消
vbYesNo4是 / 否
vbRetryCancel5重试 / 取消
vbCritical16红色叉号图标
vbExclamation48黄色感叹号图标
vbInformation64蓝色信息图标
vbDefaultButton2256默认焦点落在第二个按钮

返回值是vbOK=1、vbCancel=2、vbYes=6、vbNo=7。伪装的关键不在代码,在文案和图标组合:标题写“系统提示”、正文写“您灌水太多需要重新启动计算机”、图标用vbInformation,用户的心理预期就被拉到了“系统在通知我”这一侧,很少有人会去想这句话为什么是这种措辞。

' fake_prompt.vbs —— 演示两种分支,取消分支什么都不做 Option Explicit Dim ret ret = MsgBox("检测到系统资源占用过高,是否立即重启?", _ vbOKCancel + vbExclamation + vbDefaultButton2, _ "系统提示") If ret = vbOK Then MsgBox "这里才是真正要执行动作的位置", vbInformation, "分支一" Else MsgBox "取消分支:生产中应该什么都不做", vbInformation, "分支二" End If

vbDefaultButton2是这类脚本里最阴的一个细节:默认焦点落在“取消”上,用户随手一回车反而是取消,但脚本作者经常故意反过来,把默认焦点放在会触发动作的按钮上。看任何一段可疑脚本,先找MsgBox的返回值被拿去做了什么判断,比看文案快得多。

3.2 shutdown 倒计时:交互式胁迫的套路与三个破绽

shutdown命令是整套把戏的核心。常用参数:-s关机、-r重启、-t 秒设置倒计时、-c "注释"在系统提示里显示一行自定义文案、-a中止倒计时、-f强制关闭未响应程序。整人脚本的典型写法是先-s -t 300起一个五分钟的倒计时,再用InputBox循环逼用户输入某个词,输对了才执行-a。

它的三个破绽几乎每次都一样。第一,shutdown -a一条命令就能中止,不需要密码,也不需要先找到脚本进程;第二,倒计时期间系统托盘会弹出通知,Windows 10 之后这条通知无法被脚本屏蔽;第三,InputBox是模态的,用户按Esc或者点关闭,返回值是空字符串,很多脚本没处理这种情况,判断逻辑直接走偏,甚至自己卡死。

' coercive_demo.vbs —— 只演示结构,启动后立刻可撤销 Option Explicit Dim sh, ans Set sh = CreateObject("WScript.Shell") sh.Run "shutdown -r -t 60 -c ""演示:60 秒后重启""", 0, False Do ans = InputBox("请输入 stop 取消重启", "提示", "", 3000, 3000) If ans = "stop" Then sh.Run "shutdown -a", 0, True Exit Do ElseIf ans = "" Then sh.Run "shutdown -a", 0, True ' 用户关掉输入框也要能退出 Exit Do End If Loop MsgBox "已撤销", vbInformation, "结束"

InputBox的后两个数字参数是窗口的横纵坐标,不是超时时间,很多人误以为是“几秒后自动关闭”,实际它不会自动关。这一点在写防御脚本时反而有用:如果发现屏幕上有InputBox停在奇怪的位置,基本可以确定不是正常业务的输入框。

3.3 SendKeys 与光驱弹出:为什么这两类最容易翻车

WScript.Shell.SendKeys把按键消息发给当前前台窗口,不指定目标、不检查焦点。脚本写SendKeys "{F5}"放进死循环,本意是让浏览器不停刷新,实际效果取决于执行瞬间谁在前台——可能是资源管理器、可能是聊天窗口、可能是正在编辑的文档。这就是玄学感的来源:同一段代码在两台机器上表现完全不同。

光驱那段更直接,WMPlayer.OCX的cdromcollection.item(0).eject()循环调用,物理托盘反复进出。这类脚本对硬件的损耗是实打实的,而且中断起来很别扭——wscript.exe没有窗口,用户只能去任务管理器里找进程结束,笔记本用户甚至找不到托盘按钮。

还有一类是用系统调试工具向关键进程发退出信号制造崩溃,这在 NT 内核的早期版本上能直接蓝屏。现代系统上这条路径基本被堵死,需要调试权限且默认不启用,但把这段代码留在“大全”里传播,风险不在技术可行性,在于它教的是“如何让别人的机器不可用”这个思路本身。

3.4 从恶作剧到蠕虫,只差一步自复制

这一节只讲机制,不贴可运行代码。那段被原作者标为“太毒了”的脚本,传播链可以拆成五步。

步骤动作用到的能力
1枚举所有就绪盘符,与上一轮快照做差集FSO.Drives、Drive.IsReady
2把自己的源码读出来写成新文件OpenTextFile(scriptfullname)+CreateTextFile
3把副本属性设为 7(只读+隐藏+系统)File.Attributes = 7
4在根目录写autorun.inf,把shell\open\command指向副本CreateTextFile
5用desktop.ini配 CLSID 把回收站目录伪装成正常文件夹desktop.ini的.ShellClassInfo段

第 1 到第 3 步是“整人”,第 4 步开始就是“传播”,第 5 步是“藏”。属性值 7 是只读(1)+隐藏(2)+系统(4)的按位或,普通用户在资源管理器里必须打开“显示隐藏的系统文件”才看得见,这一步把发现成本抬高了一个量级。autorun.inf在现代系统上对 U 盘已默认禁用自动运行,但对光盘和部分映射盘仍有效,而且就算不自动执行,用户双击盘符时走shell\open\command一样会被引到脚本上。

识别这类东西不需要读完整代码,看三处就够了:有没有scriptfullname(读自身)、有没有Attributes = 7(藏身)、有没有autorun.inf(传播)。三者同时出现,直接判定为恶意,不用犹豫。

4. 隔离环境复现:快照、断网与三个观察点

4.1 实验台怎么搭:快照、断网、独立磁盘

任何一段来源不明的脚本,先在虚拟机里跑,这条规矩没有例外。搭法不复杂,但每一步都别省。

步骤一,建一台虚拟机,装好系统后先打一次快照,命名成“干净基线”。快照要在装任何测试工具之前打,否则回滚回来还是脏的。

步骤二,断网。虚拟机的网络适配器设成“仅主机”或者直接移除,防止脚本里有下载行为把外部资源拉进来,也防止自复制跑到共享盘上。

步骤三,挂一块独立的虚拟磁盘当靶盘,专门用来观察自复制行为。靶盘和系统盘分开,回滚时只丢靶盘,不动基线。

步骤四,把脚本拷进去之前,先在宿主机上改扩展名成.txt存一份,用编辑器过一遍,确认没有你不认识的外部调用。这一步是血泪经验:直接双击和在记事本里读一遍,成本差着一个数量级。

观察项位置关注点
进程任务管理器“详细信息”页是否出现wscript.exe/cscript.exe,命令行参数是什么
文件落地各盘根目录、%APPDATA%、%TEMP%新增的.vbs、.inf、.ini,属性是否被改成隐藏+系统
自启动HKCU\...\Run、启动文件夹是否写入指向脚本的键值
计划任务任务计划程序根目录是否注册了定时触发的项

4.2 一段可取消的倒计时演练,含完整参数说明

用一个自带“后悔药”的脚本走完整流程:起倒计时、观察系统通知、主动撤销、复核状态。全程不会真的关机。

' drill_shutdown.vbs —— 演示倒计时的完整生命周期,8 秒后自动撤销 Option Explicit Dim sh, ret Set sh = CreateObject("WScript.Shell") ret = MsgBox("将启动 60 秒关机倒计时,8 秒后自动撤销。" & vbCrLf & _ "期间可手动执行 shutdown -a 验证", _ vbOKCancel + vbExclamation, "演练") If ret = vbCancel Then WScript.Quit ' 第二个参数 0=隐藏窗口,第三个参数 False=不等待命令返回 sh.Run "shutdown -s -t 60 -c ""演练用倒计时,shutdown -a 可取消""", 0, False WScript.Sleep 8000 ' True 表示等 shutdown -a 执行完再继续 sh.Run "shutdown -a", 0, True MsgBox "已撤销。若系统提示"没有正在进行的关机",说明倒计时已过期或未生效", _ vbInformation, "演练结束"

三处参数值得单独说。Run的第三个参数用False是故意的——若用True,脚本会阻塞在shutdown上直到关机动作为止,后面的Sleep和撤销根本执行不到,这是很多人写演练脚本时踩的第一个坑。WScript.Sleep 8000的单位是毫秒,不是秒,写成8000是八秒,写成8就是八毫秒,撤销会立刻执行,观察不到任何现象。shutdown -a放在Run里而不是用Exec,是因为-a的返回码对结果判断更有用,Exec拿到的StdOut在部分系统上是空的。

演练时盯两件事:托盘是否弹出系统级的关机通知(脚本无法屏蔽,这是识别倒计时最可靠的信号),以及shutdown -a执行后是否返回“没有正在进行的关机”——如果是这句话,说明倒计时根本没起来,得回头查-t的单位和脚本里的权限。

4.3 观察点一:进程与命令行

脚本跑起来之后,最快的定位手段是看命令行,而不是看进程名。wscript.exe可能同时有好几个实例,光看名字分不清哪个是你点的。

# 列出所有脚本宿主进程及其命令行 Get-CimInstance Win32_Process -Filter "Name='wscript.exe' OR Name='cscript.exe'" | Select-Object ProcessId, Name, CommandLine | Format-List

Win32_Process的CommandLine属性是这里唯一的有效信息源:能直接看到宿主后面跟的.vbs完整路径,路径在%TEMP%或者盘根目录的,基本可以直接判死。如果命令行是空的,通常是因为进程以更高完整性级别运行,当前用户查不到,这种情况就得换到管理员权限的会话里再查一次。

结束进程之前先想清楚:脚本会自我重启,把wscript.exe杀掉之后,如果autorun.inf还在,插一次 U 盘它又回来了。所以正确顺序是先断传播路径(改autorun.inf属性、拔移动介质),再杀进程,最后清落地文件。

4.4 观察点二:落地文件与自启动位置

文件层面盯三样东西:新增的隐藏+系统属性文件、盘根目录的autorun.inf、以及回收站目录里的异常子文件夹。属性值等于 7 的文件用普通dir看不到,得加参数。

# 在 cmd 中列出根目录下隐藏+系统属性的文件 attrib C:\*.* /s /d | findstr /i "SH" # 只看特定盘根目录 dir D:\ /a:sh

attrib输出里的SH前缀就是隐藏+系统,SHR是再加上只读。正常的系统文件也会带这些属性,判断标准是“位置异常”:出现在盘根目录、文件名是随机串、内容是 VBS 文本,这三条同时满足就该处理了。改属性用attrib -s -h -r 文件名,删之前先把.txt备份一份留作样本分析。

自启动位置优先查两处:HKCU\Software\Microsoft\Windows\CurrentVersion\Run和%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup。前者用注册表编辑器直接看,后者在资源管理器地址栏粘进去。整人脚本很少用HKLM,因为那需要提权,而HKCU对当前用户完全够用,也更隐蔽——重装系统才会清掉,改用户配置不会。

5. 避坑与排查:五条踩过的记录

5.1 现象:任务管理器里wscript.exe结束不掉,杀掉又出现

原因通常是两件事叠加:脚本里对自身路径再调了一次Run,形成重启循环;或者进程有多个实例,你只杀了其中一个,另一个还在按Sleep的节奏重新拉起。还有一种少见情况是脚本被注册成了计划任务,触发间隔很短。

解决顺序是断链再杀。先查计划任务和Run键有没有指向该脚本的项,清掉;再去任务管理器用“详细信息”页按命令行排序,把同一路径的所有实例一次勾选结束;最后删落地文件。只做最后一步等于没做,因为前面两个触发源还在。

5.2 现象:改回文件关联后,双击.vbs还是被记事本打开

原因不是关联没改对,是改了错的位置。.vbs的关联有两层:HKEY_CLASSES_ROOT\.vbs的默认值指向一个 ProgID,再由HKEY_CLASSES_ROOT\<ProgID>\Shell\Open\Command指定命令行。只改第一层,第二层还指着记事本,行为不变。

解决是两层一起看。先读.vbs的默认值拿到 ProgID 名,再展开对应的Shell\Open\Command,正常应该是"%SystemRoot%\System32\WScript.exe" "%1" %*。改完用assoc .vbs和ftype两条命令在命令行复核一遍,比在图形界面里点“打开方式”可靠。

5.3 现象:删了autorun.inf,重启之后又在

原因是文件属性是隐藏+系统+只读,普通的删除操作在资源管理器里根本看不到它,你以为删了其实没删。另一个来源是回收站目录下被desktop.ini伪装过的副本,脚本下次运行时从那里恢复。

解决是先改属性再删:attrib -r -s -h D:\autorun.inf,然后用del删。同时检查各盘的回收站目录(D:\$Recycle.Bin或者脚本自定义的类似recyc1ed这种拼写近似的目录),把里面的desktop.ini和异常子文件夹一起清掉。这个拼写近似的手法很常见,1和l、0和o互换,肉眼扫一遍很容易漏。

5.4 现象:虚拟机回滚快照之后,脚本还在跑

原因多半是传播路径没断干净:共享文件夹、剪贴板、挂载的宿主机目录,这三条都能把文件带出去带回来。回滚只还原虚拟磁盘,不还原这些通道。

解决是把虚拟机的共享文件夹和剪贴板共享在测试期间全部关掉,测试完再开。宿主机那边也要扫一遍,尤其是插过的 U 盘和映射过的网络盘。这条是后悔药级别的经验:快照不是万能的,它只保护磁盘状态,不保护数据通道。

5.5 现象:执行shutdown -a提示“没有正在进行的关机”,但机器还是在倒计时

原因是倒计时不是shutdown起的,而是脚本用WScript.Shell.Popup或者自绘窗口做的假倒计时,到点之后才调shutdown -s -t 0。这种假倒计时不受-a控制,只能杀进程。

解决是先看进程里有没有可疑的wscript.exe,有就杀掉;再检查是不是有第三方程序在调用关机接口。另一个变种是先-t 0立即关机再补一个-a,这种根本来不及撤销,所以演练时把-t设成 60 秒以上是有意义的——给自己留出反应窗口。

6. 清理与加固:从一台机器到一份策略

6.1 一台已中招机器的手工清理顺序

顺序错了会返工,按这个走:断传播、停触发、杀进程、清落地、改配置、复核。

断传播指拔掉所有可移动介质并设为只读,防止清理过程中被重新写入。停触发指清掉Run键、启动文件夹和计划任务里所有指向脚本的项。杀进程用命令行核对路径后再结束,别按名字一把杀。清落地文件时先attrib -r -s -h再删,删完扫一遍各盘根目录和回收站目录。改配置指把.vbs关联临时指向记事本。复核就是重跑一遍前面那几个观察点,确认没有新增。

# 复核:列出所有脚本宿主进程、根目录可疑文件、自启动项 Get-CimInstance Win32_Process -Filter "Name='wscript.exe'" | Select ProcessId, CommandLine Get-ChildItem C:\,D:\ -Force -File -Include *.vbs,autorun.inf -ErrorAction SilentlyContinue Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"

-Force参数不能少,否则隐藏和系统属性文件直接被过滤掉,你会得到一个“干净”的假象。

6.2 把脚本宿主限制住:几处值得改的开关

加固的核心思路不是删掉wscript.exe(很多正常运维脚本依赖它),而是限制它能被谁、以什么方式调用。

位置调整效果副作用
.vbs文件关联改为notepad.exe "%1"双击只能查看自己也没法双击运行
软件限制策略对wscript.exe设“不允许”全线禁用脚本宿主依赖 VBS 的登录脚本失效
组策略关闭移动介质自动运行autorun.inf不再触发光盘自动播放也没了
用户权限收紧SeShutdownPrivilege普通用户无法发起关机需要走正规关机流程
文件夹选项勾选“显示隐藏的系统文件”隐藏文件可见系统文件看着乱

个人机器上最省事的是前两条加第四条里的关机权限收紧;企业环境用组策略把软件限制策略推下去,一次配置覆盖一批机器。这里有个容易被忽略的点:禁用wscript.exe之后,cscript.exe还是能跑,两个都得管,否则等于只关了一扇窗。

我一直有个习惯,拿到任何.vbs文件,先改后缀成.txt通读一遍,确认里面没有scriptfullname、没有Attributes = 7、没有shutdown,再放进虚拟机双击。这个动作只花两分钟,但省下的是重装系统和找回文件的时间。从那以后我每次帮人看“电脑中邪”的问题,都强制走一遍“断链、停触发、杀进程、清落地”的顺序,不再凭感觉先杀进程。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询