远程邮件终端(Windows批处理实现邮件远程控制电脑(第三方批处理))
最近网上看到了电子邮箱的新利用方法如题 ,下载了几个此类软件 ,发现好几个不是不好用 ,就是功能不全 。上博客园搜了一下,那么可以看到有使用java和python实现的 ,这里我们用Windows的批处理实现 。
我们要实现的最基础的功能 ,自然是执行cmd命令 ,有了这个其他都好说 。Windows批处理的优点:
1.一个批处理文件 ,配合第三方批处理等 ,在几乎所有Windows电脑上 ,可以直接运行 。
2.代码编写容易 ,逻辑比较简单 ,基本上都是cmd命令 。
批处理的缺点:
1.我们远程控制 ,邮件发送过来的也是命令,由于Windows命令解释的预处理机制 ,会把原批处理命令和发送的命令(变量)混在一起 。此处会涉及到不是非常复杂 、但总是令人晕头转向的空格问题 、引号问题 、转义问题等 。
2.上面这步若没有处理好 ,很容易发生语法错误 。如果是较轻的错误,命令完成还能给你返回一个errorlevel ,若是比较严重的语法错误 ,可能直接导致命令行闪退 。(就什么都没有了 。)for和if命令最易出现此问题 。1.收发邮件
Windows不自带能够通过命令行收发邮件的程序 ,因此我们的程序需要自带第三方命令行 。这里我们使用工具getmail来接收邮件。getmail使用pop3协议 ,可以将邮件下载为txt ,并下载其附件 。
发送邮件则使用blat进行 。blat使用SMTP发送邮件 ,同样支持上传附件。
可以通过输入--help或/?来获取它们的详细用法 ,或者可以访问批处理之家的说明 。虽然翻译不是非常专业 。下面仅简单说明一下 。getmail收邮件的用法
帮助文件中的参数我们不是每一个都用到 。下面介绍的是本例中用到的几个 。
-u
-pw
-s
-delete下载后删除下载的邮件 。不加此参数则不删除 。
-xtract下载邮件带有的附件 ,并且解码邮件内容的明文 。不加此参数则不会下载附件 ,也不会解码明文 ,只会下载一个MSG文件 ,含有附件的有关信息,并且保存邮件内容经过base64编码后得到的字符串。
-headersonly只下载邮件头部信息 ,即发送者 、接收者 、邮件subject等 。理论上这会加快获取的速度 。
-n <n>总共获取n封邮件。貌似是从最早收到的一封邮件开始数 。getmail还可以将配置写入注册表 ,以后每次都使用注册表中的配置,可以简化参数 ,不过我这次没有使用 。
因此我们配置好上述参数后 ,获得的回显如下(此次服务器上没有任何邮件): Failed to open registry key for GetMail profile , using default. Failed to open registry key for GetMail Getting *********@sina.cns mailbox contents from server pop.sina.cn:110 There are 0 messages on the server.blat发邮件的使用
参数非常多 。想看详细的同样可以去访问上面说过的页面 ,这里只介绍会用到的 。
若不想从文件指定发送内容 ,在上面这个参数只输入-,之后可以在后面加一个参数-body "<邮件的内容>" 。
-to
收件人的电邮地址 。
-charset
-subject邮件的主题 。
-server输入smtp服务器地址 ,可以在邮箱设置界面找到 。
-ffrom的缩写 ,指定登录用来发件的邮箱 。
-u登陆邮箱用的用户名 。大部分是你邮件地址@前的部分 ,若登录不成功请翻找邮箱的帮助界面。
-pw登录密码 。与上文getmail的密码相同 。
-attach附加附件到邮件。2.电脑使用的邮箱
我们的策略是电脑独立使用一个邮箱地址 ,你可以使用其他的邮箱向这个地址发件来实现控制 。
我推荐电脑使用的是新浪邮箱 ,一个手机号可以注册多个独立邮箱 。并且连接比较稳定,很少出现获取/发送不成功的情况 ,5s的获取邮件间隔毫无压力 ,不会遭到阻止 。
发件的邮箱几乎没有什么限制了,但是钉钉自带的钉邮在这里无法使用 ,因为会将邮件的subject也一起加密(或者是使用了utf8编码什么的 ,记不清了) ,批处理直接读取比较麻烦 。目前试过好用的是阿里邮箱和qq邮箱 。163应该是好用 ,但是没试过 。3.原理概述
3.1执行命令
由于在getmail接收到的文本文件里 ,subject没有加密 ,而content经过base64编码了 。所以一开始的计划是只读取subject ,命令全部放到subject里 。
程序首先要实现的功能是执行cmd命令 ,后面我们还会加几个自定义功能 ,需要通过命令来指定我们这里选择的功能 。这里我的实现方法是使用#号分隔 ,功能选择用第一个#包裹 ,加的参数放在第二个#后面 。批处理中可以使用for命令分别取得这两个字符串 。
例如 ,我们将执行cmd命令的功能命名为cmd,需要执行命令start a.exe
那么我们发邮件的主题会输入成:#cmd#start a.exe
这个邮件经过getmail下载后 ,出现在MSG1.TXT文件里的一行是:Subject: #cmd#start a.exe
我们通过for来解读输入: echo off for /f "tokens=2,* delims=#" %%i in (type MSG1.TXT ^| findstr /b Subject:) do ( set mode=%%i set para="%%j" ) echo mode:%mode% echo command:%para% pause得到结果:
mode:cmd command:"start a.exe"之后我们调用cmd执行这个命令即可 。这里最好是新开一个cmd。加min最小化运行 。
start /MIN cmd.exe /c %para%我们也可以调用另一个bat文件 ,这样也会新开一个cmd窗口 。同时可以写入一些命令一并执行,还可以将回显输入到文件中 ,再利用blat发送出去 ,这样邮件端也可以看到回显。
同时 ,执行其他功能时也最好都新开一个批处理运行 。这样若执行命令耗时较长 ,或者执行的命令一直在后台运行时 ,不会阻断检查邮件的进程 ,仍然可以邮件执行其他命令 。
3.2文件传输
这就比较简单了 。getmail只要加上-xtract参数 ,就会直接下载附件 。要使用blat上传附件 ,我们可以将其命名为upfile功能 ,使用if判断%mode% ,若为upfile就调用另一个批处理执行blat ,将发送的文件名附加到-attach即可 。
利用这个功能 ,我们也可以发送批处理文件,将多个命令写入文件实现命令批量执行 。通过start命令调用这个批处理即可 。需要注意的是 ,一些邮箱(比如新浪邮箱就是)会自动拦截bat扩展名等一些可执行程序作为附件的邮件 。解决方法也很简单 ,可以更改文件扩展名再发送,例如改为.txt 。附件接收之后 ,再通过邮件执行重命名命令 ,改回扩展名 ,即可运行 。3.3含有中文的命令
带有中文subject无法在msg文件中直接显示 。例如会显示为:
Subject: =?UTF-8?B?4oCq4oCqZGltb0BhbGl5dW4uY29t4oCs4oCs?=这样解码就比较麻烦 。而下面的content使用base64解码之后就能直接看到中文 ,getmail的-xtract参数添加后也会自动将内容给解码出来 ,比较方便。因此我们可以在邮件正文中输入命令 ,程序读取后执行 。
然而getmail解码出来的内容是html(点击查看详细) ,这个批处理想要直接读取文本比较麻烦 。前面这个页面也有解决方法。3.4隐藏运行
也比较简单 。使用vbs命令即可实现完全隐藏cmd的黑框 ,同时还能顺便获取UAC管理员权限 。
此处假设我们要运行的是run.bat: REM 仅隐藏运行 echo set ws=WScript.CreateObject("WScript.Shell") > start.vbs echo ws.Run "%~dp0run.bat /start",0 >> start.vbs start.vbs del /f /q start.vbs REM 隐藏运行并获取管理员权限 ECHO SET UAC = CreateObject^("Shell.Application"^) > Getadmin.vbs ECHO UAC.ShellExecute "run.bat", "此处可以加一个参数", "", "runas", 0 >> Getadmin.vbs Getadmin.vbs del /f /q Getadmin.vbs3.5开机运行&防止关闭
开机运行可以通过设置任务计划实现 。可以使用任务计划程序来窗口化配置任务 ,也可以使用schtasks命令 ,编写一个批处理实现一键添加任务 。同时我们还可以在程序启动时发送提醒邮件 ,实现对开机时间的监控 。
rem 此处需要开机启动的批处理文件为startgo.bat set file=%~dp0startgo.bat schtasks /Create /SC ONLOGON /TN \Windows\MailService /TR "%file%" /F /RL HIGHEST /DELAY 0001:00 rem 延时启动用于防止电脑还未联网导致开机邮件发送失败 pause有关防止进程被杀死 ,批处理之家中也有相关讨论 。
3.6配置文件
由于许多不同的批处理文件都要实现接受/发送邮件,我们需要将邮箱地址 、登录用户名 、密码都写入一个配置文件中 ,便于邮件收发 。当然也可以使用程序将配置储存在注册表的功能 。
在配置文件中 ,我们只需要将不同的配置写入单独一行即可用批处理分别读取,这样也便于文件的编辑 。
利用for命令可以读取文件的每一行并对每行执行相同的操作 。想要使用for读取单独一行的内容 ,需要在执行的末尾添加goto跳出for命令 。多次使用这样的for即可读取到配置文件各个行的内容 。有关内容可见网页链接。3.7更多功能
我们还可以添加更多实用的功能 ,通过if判断和goto跳转到功能 。
例如 ,我们想要通过命令弹出一个提示框 ,代码比较长 ,输入不方便 。 mshta vbscript:msgbox("content",64,"title")(window.close)此时就可以将命令保存到bat中。把功能命名为popup ,使用if判断%mode%即可 。跳转后执行对应的bat文件 ,并将显示的内容作为参数输送给bat 。例如我们规定用$作分隔字符 ,则发送邮件时输入:#popup#title$64$content
主程序按照#分隔输入 ,判断出需要跳转到popup;之后popup.bat会接收到输入:"title$64$content"
此时再按$分割输入 ,即可得到每部分内容 ,并用于弹窗: echo off for /f "tokens=1,2,3 delims=$" %%i in (echo %~1) do ( set tit=%%i set num=%%j set text=%%k ) mshta vbscript:msgbox("%text%",%num%,"%tit%")(window.close) exit4.最终代码
由于使用了不少功能 ,放在一个程序文件夹里的第三方和bat文件也有不少 。
点击查看代码下面的代码都可以这样点击展开 。
start.bat echo off cd /d "%~dp0" echo set ws=WScript.CreateObject("WScript.Shell") > start.vbs echo ws.Run "%~dp0run.bat /start",0 >> start.vbs start.vbs rem 发送开机提醒邮件;读取配置文件 :euser for /f "eol=# tokens=* delims=" %%i in (mail.cfg) do ( set euser=%%i goto ename ) :ename for /f "eol=# skip=4 tokens=* delims=" %%i in (mail.cfg) do ( set ename=%%i goto epw ) :epw for /f "eol=# skip=6 tokens=* delims=" %%i in (mail.cfg) do ( set epw=%%i goto smtp ) :smtp for /f "eol=# skip=10 tokens=* delims=" %%i in (mail.cfg) do ( set smtp=%%i goto eto ) :eto for /f "eol=# skip=12 tokens=* delims=" %%i in (mail.cfg) do ( set eto=%%i goto getcfgend ) :getcfgend set subj="[MailCTRL]%DATE% %TIME% %COMPUTERNAME%" echo host has started.>hello.txt echo for more info:>> hello.txt echo date and time:%DATE% %TIME%>> hello.txt echo computer:%COMPUTERNAME%>> hello.txt echo userdomain:%USERDOMAIN%>> hello.txt echo username:%USERNAME%>> hello.txt echo -------------------->>hello.txt systeminfo >> hello.txt ipconfig >> hello.txt set content=hello.txt ::------------------ blat %content% -to %eto% -charset gbk -subject %subj% -server %smtp% -f %euser% -u %ename% -pw %epw% del /f /q %content% del /f /q start.vbs exit run.bat cd /d "%~dp0" del /F /Q z*.todo del /F /Q Extract*.out del /F /Q html*.out @echo off timeout /t 3 cls echo "mail.cfg"> usedcfg.cfg ::echo %~dp0> dir.cfg echo ########################## echo setting email service...... :euser for /f "tokens=* delims=" %%i in (usedcfg.cfg) do set cfgfile=%%~i echo setted cfgfile:%cfgfile% for /f "eol=# tokens=* delims=" %%i in (%cfgfile%) do ( set euser=%%i goto epw ) :epw for /f "eol=# skip=6 tokens=* delims=" %%i in (%cfgfile%) do ( set epw=%%i goto pop ) :pop for /f "eol=# skip=8 tokens=* delims=" %%i in (%cfgfile%) do ( set pop=%%i goto getcfgend ) :getcfgend echo service started successfully AT %DATE% %TIME% echo ------------------------------------ :see TIMEOUT /T 5 echo checking new messages at %TIME% for /f "skip=3 tokens=3 delims=# " %%i in (getmail -u %euser% -pw %epw% -s %pop% -headersonly) do set newmsg=%%i echo new message received:%newmsg% if %newmsg% GEQ 1 goto get goto see :get set mode= set para= del /F /Q MSG*.TXT del /F /Q Extract*.out echo downloading the new messages... getmail -u %euser% -pw %epw% -s %pop% -delete -xtract -n 1 :: -delete :tell for /f "tokens=2,* delims=#" %%i in (type MSG1.TXT ^| findstr /b Subject:) do ( set mode=%%i set para="%%j" ) set htext=%RANDOM% del /f /q html%htext%.out echo use html2txt.exe------------------------ html2txt Extract1.out html%htext%.out echo ---------------------------------------- echo information read from MSG.TXT: echo mode: %mode% echo command: %para% echo html file:html%htext%.out echo RUNNING THE PROGRAM...... ::if %mode%==cmd goto directcmd ::if %mode%==back goto backcmd ::if %mode%==xcmd goto xcmd ::if %mode%==xback goto xbackcmd if %mode%==cmd goto textcmd if %mode%==back goto textback if %mode%==xcmd goto textX if %mode%==xback goto textXback if %mode%==popup goto popup if %mode%==poptext goto poptext if %mode%==upfile goto upfile if %mode%==use goto changecfg ::if %mode%==dir goto changedir rem 还有一些功能未开发 。下面还有几个功能被替换 。 goto see :directcmd start /MIN cmdDirect.bat %para% goto see :backcmd start /MIN backDirect.bat %para% goto see :xcmd set xmark=%RANDOM% echo %para%> z%xmark%.todo ECHO SET UAC = CreateObject^("Shell.Application"^) > Getadmin.vbs ECHO UAC.ShellExecute "cmdAdmin.bat", "z%xmark%", "", "runas", 0 >> Getadmin.vbs echo using vbs to run an admin command. Getadmin.vbs del /f /q Getadmin.vbs goto see :xbackcmd set xmark=%RANDOM% echo %para%> z%xmark%.todo ECHO SET UAC = CreateObject^("Shell.Application"^) > Getadmin.vbs ECHO UAC.ShellExecute "backAdmin.bat", "z%xmark%", "", "runas", 0 >> Getadmin.vbs echo using vbs to run an admin command. Getadmin.vbs del /f /q Getadmin.vbs goto see :textcmd start /MIN cmdText.bat %htext% goto see :textback start /MIN backText.bat %htext% goto see :textX ECHO SET UAC = CreateObject^("Shell.Application"^) > Getadmin.vbs ECHO UAC.ShellExecute "cmdText.bat", "%htext%", "", "runas", 0 >> Getadmin.vbs echo using vbs to run an admin command. Getadmin.vbs del /f /q Getadmin.vbs goto see :textXback ECHO SET UAC = CreateObject^("Shell.Application"^) > Getadmin.vbs ECHO UAC.ShellExecute "backText.bat", "%htext%", "", "runas", 0 >> Getadmin.vbs echo using vbs to run an admin command. Getadmin.vbs del /f /q Getadmin.vbs goto see :popup start /MIN popup.bat %para% goto see :poptext start /MIN poptext.bat %htext% goto see :upfile start /MIN upfile.bat %para% goto see :changecfg echo %para%> usedcfg.cfg goto euser :changedir start /MIN changeDir.bat %htext% goto see backText.bat rem 用于命令回显 。 echo off cd /d "%~dp0" :euser for /f "tokens=* delims=" %%i in (usedcfg.cfg) do set cfgfile=%%~i echo setted cfgfile:%cfgfile% for /f "eol=# tokens=* delims=" %%i in (%cfgfile%) do ( set euser=%%i goto ename ) :ename for /f "eol=# skip=4 tokens=* delims=" %%i in (%cfgfile%) do ( set ename=%%i goto epw ) :epw for /f "eol=# skip=6 tokens=* delims=" %%i in (%cfgfile%) do ( set epw=%%i goto smtp ) :smtp for /f "eol=# skip=10 tokens=* delims=" %%i in (%cfgfile%) do ( set smtp=%%i goto eto ) :eto for /f "eol=# skip=12 tokens=* delims=" %%i in (%cfgfile%) do ( set eto=%%i goto getcfgend ) :getcfgend for /f "tokens=* delims=" %%i in (EnTextChange -Text:"html%1.out") do ( set todo=%%i goto out ) :out del /f /q html%1.out set remark=re%RANDOM% %todo%> %remark%.txt echo ----------------------------->> %remark%.txt echo the cmd you run BY ADMIN: %todo%>> %remark%.txt blat %remark%.txt -to %eto% -charset gbk -subject [MailCTRL]command"%TIME%" -server %smtp% -f %euser% -u %ename% -pw %epw% timeout /t 5 del /f /q %remark%.txt exit poptext.bat echo off ::需要显示中文,保存请使用ANSI编码 cd /d "%~dp0" for /f "tokens=1,2,3 delims=$" %%i in (EnTextChange -Text:"html%1.out") do ( set tit=%%i set num=%%j set text=%%k ) ::del /f /q html%1.out mshta vbscript:msgbox("%text%",%num%,"%tit%")(window.close) pause exit upfile.bat rem 用于上传文件 echo off cd /d "%~dp0" :euser for /f "tokens=* delims=" %%i in (usedcfg.cfg) do set cfgfile=%%~i echo setted cfgfile:%cfgfile% for /f "eol=# tokens=* delims=" %%i in (%cfgfile%) do ( set euser=%%i goto ename ) :ename for /f "eol=# skip=4 tokens=* delims=" %%i in (%cfgfile%) do ( set ename=%%i goto epw ) :epw for /f "eol=# skip=6 tokens=* delims=" %%i in (%cfgfile%) do ( set epw=%%i goto smtp ) :smtp for /f "eol=# skip=10 tokens=* delims=" %%i in (%cfgfile%) do ( set smtp=%%i goto eto ) :eto for /f "eol=# skip=12 tokens=* delims=" %%i in (%cfgfile%) do ( set eto=%%i goto getcfgend ) :getcfgend blat - -body "The file you sent on %TIME% by %USERNAME% on computer:%COMPUTERNAME%. Used email address:%euser%" -to %eto% -charset gbk -subject [MailCTRL]file:%1 -server %smtp% -f %euser% -u %ename% -pw %epw% -attach %~1 exit这里仅展示部分文件 。想查看所有文件,请下载 。
MailCTRL下载
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!