[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[特效代码] 利用mshta下载跨站文件

本帖最后由 wwjjyyff 于 2018-5-11 17:56 编辑

写了一个小的demo,具体如下:
利用mshta加载服务器的页面,例如mshta http://192.168.1.10/a.php
加载后自动下载一个文件到本地指定目录,但是提示不能跨域,下载脚本如下:
try{
var http = new ActiveXObject('MSXML2.ServerXMLHTTP');
http.open("Get", "http://192.168.1.20/t.exe", false);
http.send();
var adodbStream = new ActiveXObject('ADODB.Stream');
with(adodbStream){
        Type = 1;
        Mode = 3;
        Open();
        write(http.responseBody);
        SaveToFile("D:\\t.exe", 2);
}
}catch (e){alert(e.message);}

但是通过论坛的公开接口却可以实现:
echo download('http://192.168.1.20/t.exe','D:\\t.exe') | mshta http://bathome.net/s/hta/ eval(WSH.StdIn.ReadAll())
同样是跨域,求助大神教我论坛是什么原理,如何实现的?


=================
已解决了,有两个办法:
1、论坛接口的代码,有一个root函数修改了注册表键值,允许跨站
2、通过服务器页面代理的方式,不修改本地注册表,服务器页面接受要下载的url,将url下载后转为base64编码,
再通过$.ajax给客户端取得这个编码,客户端解码以后通过ADODB.Stream对象写入到本地磁盘,相当完美
                        $.ajax({
                                type: "GET",
                                url: "init.php?id=" + id + "&key=" + key,
                                async: false,
                                dataType: "json",
                                success: function(data){
                                        if (data.key != key) throw {"message":"key not valid"};
                                        with(objStream){
                                                Type = 2;//1=adTypeBinary,2=adTypeText
                                                Mode = 3;
                                                Charset = "iso-8859-1";
                                                Open();
                                                writeText(BASE64.decode(data.value));
                                                SaveToFile(SaveFile, 2);
                                                Close();
                                        }
                                        if (objFSO.GetFile(SaveFile).size != URL.size) throw {"message":"filesize not valid"};
                                },
                                error: function(http, msg){
                                        throw {"message":"downloaded failed, " + msg};
                                }
                        });
==================
再次修改,已发现第二种方法无效,实际上也是跨站而已。因为无意中修改了注册表,导致第二种可以取得数据,大错误,再此更正。
现在的新问题是,按照论坛接口的办法,如果不采用临时文件,而用root函数改注册表,怎么样才能保证当前的mshta进程可以跨域呢?
刚才测试了一下发现,重新除非新开一个mshta进程,否则当前的mshta仍然是无法跨域的
1

评分人数

哈哈哈,被发现了。。
还有一种解决办法,是改用本地hta中转提权,就不存在跨域问题了
简单说,就是先写入一个临时hta到本地,然后调用本地hta文件去下载其他域名的文件(因为本地hta的权限高于网页)
1

评分人数

TOP

回复 2# CrLf


    确实是这样的,论坛的接口代码写的确实太强了
再请教一个问题,root函数运行以后,除非重新开一个mshta进程,否则当前mshta进程仍然是无法跨域的?
这个问题如何解决呢?

TOP

本帖最后由 CrLf 于 2018-5-11 20:28 编辑

回复 3# wwjjyyff


    我记得是写入注册表后立即生效的,不知道有没记错
    实在不行,就检测是否root之后,开个子进程
    或者干脆用临时文件的办法,先用 FSO 写入 hta 临时文件,再通过这个 hta 用 ADO 写入非文本文件

TOP

本帖最后由 CrLf 于 2018-5-11 20:38 编辑

不用临时文件也可以直接通过管道控制,原理大概类似这样:
  1. echo 1+3 | mshta "javascript:fs=new ActiveXObject('Scripting.FileSystemObject');fs.GetStandardStream(1).Write(eval(fs.GetStandardStream(0).ReadAll()));close()" | more
复制代码
改成 hta 的实现就好了
2

评分人数

TOP

本帖最后由 wwjjyyff 于 2018-5-12 14:33 编辑

回复 5# CrLf


    非常好的启发

================
经测试,用mshta执行javascript协议,仍然没有权限利用xmlhttp和ado下载文件,只能用临时文件了,
为了下载过程中友好显示一定的窗口提示,所以临时文件采用了批处理和js混编的方式,调用时run方法用同步方式,
另外也借鉴了论坛中另一个帖子:http://www.bathome.net/thread-48095-1-1.html
最终的代码如下,已测试可用:
//声明函数,利用locald4cdtag作为临时文件标志,d4cdfile为路径
function locald4cd(){
        //~生成本地临时文件
        //~调用临时文件,安全绿色
        //~后期可能会加入其它功能
        var d4cdfile = objFSO.BuildPath(objFSO.GetSpecialFolder(2), "download4cd.cmd");
        if (typeof(window.locald4cdtag)!="undefined" && window.locald4cdtag) return d4cdfile;
        try{
                var objFile = objFSO.CreateTextFile(d4cdfile, true);
                with(objFile){
                        WriteLine("@set @a=0;/* & @echo off & setlocal enableextensions enabledelayedexpansion");
                        WriteLine("color 0F & mode con cols=80 lines=18");
                        WriteLine("title Download - %*");
                        WriteLine("for %%a in (\"%~2\") do (set \"ffn=%%~dpnxa\" & set \"fd=%%~dpa\")");
                        WriteLine("pushd \"%fd%\" && popd || mkdir \"%fd%\"");
                        WriteLine("echo Source: %~1");
                        WriteLine("echo Destination: %ffn%");
                        WriteLine("echo Start Downloading ...");
                        WriteLine("set \"excode=0\" & set \"ret=Success\" & set \"ffn=%ffn:\\=\\\\%\"");
                        WriteLine("for /f \"tokens=*\" %%i in ('call cscript \"%~f0\" //nologo //e:jscript \"%~1\" \"%ffn%\"') do (set \"excode=1\" & set \"ret=Failed: %%~i\")");
                        WriteLine("echo %ret%, %excode%");
                        WriteLine("endlocal & set \"@a=\" & exit/b %excode%");
                        WriteLine("rem */");
                        WriteLine("try{");
                        WriteLine("http = new ActiveXObject(\"Msxml2.XMLHTTP\");");
                        WriteLine("with(http){Open(\"GET\",WScript.Arguments(0),0);Send();}");
                        WriteLine("ado = new ActiveXObject(\"ADODB.Stream\");");
                        WriteLine("with(ado){Type=1;Mode=3;Open();write(http.responseBody);SaveToFile(WScript.Arguments(1),2);}");
                        WriteLine("}catch(e){WScript.Echo(e.message);}");
                        Close();
                }
        }catch(e){
                alert(e.message);
                return false;
        }
        window.locald4cdtag = true;
        return d4cdfile;
}
//调用
        if (d4cdfile=locald4cd()) {
                objShell.Run("\"" + d4cdfile + "\" \"" + DownURL + "\" \"" + SaveFile + "\"", 1, true);
        }
        if (objFSO.GetFile(SaveFile).size != URL.size) throw {"message":"Get filesize error"};

TOP

返回列表