Splitting the email atom: exploiting parsers to bypass access controls

Splitting the email atom: exploiting parsers to bypass access controls

Some websites parse email addresses to extract the domain and infer which organisation the owner belongs to. This pattern makes email-address parser discrepancies critical. Predicting which domain an email will be routed to should be simple, but is actually ludicrously difficult – even for ‘valid’, RFC-compliant addresses.
一些网站解析电子邮件地址以提取域并推断所有者属于哪个组织。这种模式使得电子邮件地址解析器的差异变得至关重要。预测电子邮件将被路由到哪个域应该很简单,但实际上却非常困难 – 即使对于“有效”、符合 RFC 的地址也是如此。

In this paper I’m going to show you how to turn email parsing discrepancies into access control bypasses and even RCE.
在本文中,我将向您展示如何将电子邮件解析差异转化为访问控制绕过甚至 RCE。

This paper is accompanied by a free online CTF, so you’ll be able to try out your new skill set immediately.
本文附有免费的在线 CTF,因此您将能够立即尝试您的新技能集。

You can also get this paper as a print/download friendly PDF.
您还可以将本文作为打印/下载的PDF 版本获取。

Outline 大纲

Introduction 介绍

Some of the RFCs that dictate the email address format have been around for over 50 years, they have been mangled together to form a standard for email addresses that is way too lenient. Emails can have quoted values, comments, escapes and various encodings. If you are faced with the job of writing an email parser technically you should follow the specification but because of all this complexity it’s a difficult job. Web applications farm this complexity out to email parsing libraries and as a result they don’t actually know how the email is parsed. This leads to problems when they decide to make security decisions based on the email domain.
一些规定电子邮件地址格式的 RFC 已经存在了 50 多年,它们被整合在一起形成了过于宽松的电子邮件地址标准。电子邮件可以包含引用值、注释、转义符和各种编码。如果您面临从技术上编写电子邮件解析器的工作,您应该遵循规范,但由于所有这些复杂性,这是一项困难的工作。 Web 应用程序将这种复杂性交给了电子邮件解析库,因此它们实际上并不知道电子邮件是如何解析的。当他们决定根据电子邮件域做出安全决策时,这会导致问题。

If you look at 3.2.5 and 3.2.2 of RFC2822 it allows you to use quoted values and escapes. They enable you to use characters not normally allowed in the local-part of the email address. Some examples are:
如果您查看 RFC2822 的3.2.53.2.2,它允许您使用带引号的值和转义。它们使您能够使用电子邮件地址本地部分通常不允许的字符。一些例子是:

"@"@example.com
"\""@example.com

In the first example because the local-part is quoted the at symbol will be used as a destination mailbox with the quotes removed. In the second example it shows how you can use escapes inside the quoted local-part to use the double quote as the destination mailbox. If we look deeper at the same RFC section 3.2.3 we can see it supports comments. Comments are constructed using parentheses and can contain whitespace and even nest. Here are some examples of “valid” emails that use comments:
在第一个示例中,因为本地部分被引用,所以 at 符号将被用作删除引号的目标邮箱。在第二个示例中,它展示了如何在带引号的本地部分内使用转义来使用双引号作为目标邮箱。如果我们更深入地查看同一个 RFC 第3.2.3节,我们可以看到它支持注释。注释是使用括号构建的,可以包含空格甚至嵌套。以下是使用评论的“有效”电子邮件的一些示例:

(foo)user@(bar)example.com

You’re not just limited to alphanumeric values either; you can place a multitude of characters within a comment. This all seems ripe for abuse by creating confusion between the parser, the application and the mailer. My journey started in this research by trying to create this confusion by abusing escapes and comments.
您不仅限于字母数字值;您可以在评论中放置多个字符。通过在解析器、应用程序和邮件程序之间造成混淆,这一切似乎都已经成熟,很容易被滥用。我的旅程始于这项研究,试图通过滥用转义和评论来制造这种混乱。

Creating email domain confusion
造成电子邮件域名混乱

I’m not proud of this story about how I discovered this but it’s the truth. I didn’t spend hours looking at the Postfix and Sendmail source code with a debugger and there’s definitely an element of randomness and luck.
我对这个关于我如何发现这一点的故事并不感到自豪,但这是事实。我没有花几个小时用调试器查看 Postfix 和 Sendmail 源代码,这肯定有随机性和运气的因素。

It started when I was logged into a box I was using for testing, I installed an unnamed app and began testing it for email parsing discrepancies. I was getting nowhere. Everything I tried was failing, I had thoughts of abandoning the research completely. Then out of an act of desperation I took the special characters the app was using and pasted it into my email address. I knew it would be valid since it was all the characters they allowed but I just wanted to see what would happen with the mailer.
当我登录到用于测试的盒子时,它开始了,我安装了一个未命名的应用程序并开始测试它的电子邮件解析差异。我毫无进展。我尝试的一切都失败了,我有彻底放弃研究的想法。然后,出于绝望,我采取了应用程序正在使用的特殊字符并将其粘贴到我的电子邮件地址中。我知道它是有效的,因为这是他们允许的所有字符,但我只是想看看邮件程序会发生什么。

I checked the syslog of the box and noticed that I was getting a DSN (delivery status notification) with an invalid host. Surprised at this, I began to dig deeper. I started to remove characters from the email address to narrow down why Sendmail thought it was an invalid host. Eventually, I narrowed it down to the exclamation mark and remembered about the UUCP protocol I’d read whilst conducting this research.
我检查了盒子的系统日志,发现我收到了带有无效主机的 DSN(传送状态通知)。对此感到惊讶,我开始更深入地挖掘。我开始从电子邮件地址中删除字符,以缩小 Sendmail 认为它是无效主机的原因。最终,我将范围缩小到感叹号,并想起了我在进行这项研究时读过的UUCP 协议

UUCP is an ancient protocol that existed before the Internet and email. It allowed you to send messages between Unix systems and stands for Unix To Unix Copy. It works by using the exclamation mark as a separator between the domain and user part but in the opposite order of the traditional email address.
UUCP 是一种古老的协议,早在互联网和电子邮件出现之前就已存在。它允许您在 Unix 系统之间发送消息,代表 Unix To Unix Copy。它的工作原理是使用感叹号作为域和用户部分之间的分隔符,但顺序与传统电子邮件地址相反。

This was bonkers, by sheer luck the characters I pasted ended with a backslash which escaped the at symbol and then the exclamation mark was treating the address as a UUCP address! Here is my discovery in all its glory:
这太疯狂了,纯粹是运气好,我粘贴的字符以转义了 at 符号的反斜杠结尾,然后感叹号将该地址视为 UUCP 地址!这是我的所有荣耀的发现:

Original discovery: 最初的发现:

!#$%&'*+\/=?^_`{|}~-collab\@psres.net

Naturally, I had to follow up with a different Collaborator domain to be sure it’s actually going to a different server:
当然,我必须跟进不同的协作者域,以确保它实际上会发送到不同的服务器:

oastify.com!collab\@example.com

The preceding example goes to the Collaborator domain “oastify.com” not example.com when using Sendmail 8.15.2. This was really exciting to me because I proved that this research was actually going somewhere. The next step was to find other characters that caused this behaviour so I wrote a SMTP fuzzer quite quickly. I discovered that Postfix didn’t have this behaviour because it’s more secure right? Well that’s what I thought until I found a variation in Postfix 3.6.4 via the fuzzer:
使用 Sendmail 8.15.2 时,前面的示例将转到协作者域“oastify.com”而不是 example.com。这对我来说真的很令人兴奋,因为我证明了这项研究确实取得了进展。下一步是找到导致此行为的其他字符,因此我很快编写了一个 SMTP 模糊器。我发现 Postfix 没有这种行为,因为它更安全,对吗?嗯,这就是我的想法,直到我通过模糊器发现 Postfix 3.6.4 中的一个变体:

collab%psres.net(@example.com

This actually goes to psres.net not example.com and uses yet another archaic protocol called source routes. Source routes allow you to use a chain of servers to send mail. The idea was you separate each host with a comma and then include the final destination at the end. There is also what is called the “percent hack”, this is where the mailer will convert the % or different chosen character to the at symbol and then forward on the email to the server. This example illustrates this:
这实际上会转到 psres.net 而不是 example.com,并使用另一个称为源路由的古老协议。源路由允许您使用服务器链来发送邮件。这个想法是用逗号分隔每个主机,然后在末尾包含最终目的地。还有所谓的“百分比黑客”,邮件程序会将 % 或不同的选定字符转换为 at 符号,然后将电子邮件转发到服务器。这个例子说明了这一点:

foo%[email protected]
[email protected]

In this process, the email is initially sent to example.com, after which the percent symbol is converted to an at symbol and an email is sent to [email protected]. This is exactly what is occurring with the vector, the parenthesis comments out the domain part of the email address which then Postfix uses the local-part as a source route that sends the email to the unexpected destination. Postfix actually supports UUCP too. I later found out if you use the single parenthesis trick.
在此过程中,电子邮件最初发送到 example.com,之后将百分号转换为 at 符号,并将电子邮件发送到 [email protected]。这正是向量所发生的情况,括号注释掉了电子邮件地址的域部分,然后 Postfix 使用本地部分作为将电子邮件发送到意外目的地的源路由。 Postfix 实际上也支持 UUCP。我后来发现你是否使用了单括号技巧。

These findings gave me confidence that there are a ton of bugs out there and so I began looking for more.
这些发现让我确信存在大量错误,因此我开始寻找更多错误。

Parser discrepancies  解析器差异

Unicode overflows  Unicode 溢出

One of the main problems I had to solve with this research was generating blocked characters. Since many web applications will block multiple at symbols. This is why I started to look into unicode overflows.
我在这项研究中必须解决的主要问题之一是生成阻塞字符。由于许多 Web 应用程序会阻止多个 at 符号。这就是我开始研究 unicode 溢出的原因。

I was testing an unnamed target and noticed that when using higher unicode characters they would generate other ASCII characters. This pattern seemed random at first but then I grasped what was going on. It’s probably best illustrated from an image of how the chr() algorithm works in PHP. The chr() function returns a character specified by an integer code point:
我正在测试一个未命名的目标,并注意到当使用更高的 unicode 字符时,它们会生成其他 ASCII 字符。这种模式一开始似乎是随机的,但后来我明白了发生了什么。最好用一张图片来说明 chr() 算法在 PHP 中的工作原理。 chr() 函数返回由整数代码点指定的字符:

Splitting the email atom: exploiting parsers to bypass access controls

In the example, PHP loops through the bytes and checks if it is less than zero, if it is it adds 256 until it’s positive. Then it performs a modulus operation to fit the value within 0-255. This means if you pass a byte value greater than 255 it will be overflowed and forced into the 0-255 range because of the modulus operation. This is exactly how unicode overflows work; we simply need to provide a character who’s codepoint is greater than 255 to generate other characters. This is best illustrated with a simple example:
在示例中,PHP 循环遍历字节并检查它是否小于零,如果是,则添加 256 直到为正数。然后它执行模运算以适应 0-255 之间的值。这意味着如果您传递大于 255 的字节值,它将溢出并由于模数运算而强制进入 0-255 范围。这正是 unicode 溢出的工作原理;我们只需要提供一个代码点大于 255 的字符即可生成其他字符。用一个简单的例子可以很好地说明这一点:

String.fromCodePoint(0x100 + 0x40)

In the preceding example I use the fromCodePoint function to generate a character, I pass a hex value of 0x100 which translates to 256 decimal then I add 0x40 which is the hex number for the at symbol. Then when the system performs an operation like the chr() function in PHP the unicode code point will be overflowed and fit within 0-255 which will then generate the at symbol.
在前面的示例中,我使用 fromCodePoint 函数生成字符,传递十六进制值 0x100,该值转换为十进制 256,然后添加 0x40,这是 at 符号的十六进制数。然后,当系统执行像 PHP 中的 chr() 函数这样的操作时,unicode 代码点将溢出并适合在 0-255 范围内,然后生成 at 符号。

After I discovered this I started fuzzing the unnamed target with Turbo Intruder and noticed that other characters were exhibiting this behaviour. At first it seemed random but then I realised what was happening, 0x100 is just one of the numbers you can use to perform an overflow. If you use higher characters, you can use any of the characters in-between.
发现这一点后,我开始使用 Turbo Intruder 对未命名的目标进行模糊测试,并注意到其他角色也表现出这种行为。起初它看起来是随机的,但后来我意识到发生了什么,0x100 只是可用于执行溢出的数字之一。如果您使用更高的字符,则可以使用中间的任何字符。

String.fromCodePoint(0x100 + 0x40) // ŀ → @
String.fromCodePoint(0x1000 + 0x40) // ၀ → @
String.fromCodePoint(0x10000 + 0x40) // 𐁀 → @
...
0x10ffff

Each of the hex values above create overflows because the modulus operation will result in zero and this can continue until the current maximum unicode codepoint which is 0x10ffff. This target was allowing all sort of unicode characters to create other characters:
上面的每个十六进制值都会产生溢出,因为模数运算将导致零,并且这种情况可以持续到当前最大 unicode 代码点 0x10ffff。该目标允许所有类型的 unicode 字符创建其他字符:

'✨' === '('
'✩' === ')'
'✻' === ';'
'✼' === '<'
'✽' === '='
'✾' === '>'
'❀' === '@'

If you perform a 256 modulus operation on each of the characters it will result in the generated character:
如果对每个字符执行 256 模运算,将生成生成的字符:

//Mod each code point by 256
'❀'.codePointAt(0) % 256 === 0x40
String.fromCodePoint(0x40)
// @

Although I was able to spoof a wide range of characters I was unable to split an email on this unnamed target with this technique. But this was just the start, I proved that it was possible to generate blocked characters. This gave me the confidence to look for more.
虽然我能够欺骗各种各样的字符,但我无法使用这种技术分割关于这个未命名目标的电子邮件。但这只是开始,我证明了生成阻塞字符是可能的。这让我有信心去寻找更多。

Encoded-word  编码字

The more I started to look, the more the email RFC’s wanted to give. I had assumed before this research that emails were generally alphanumeric with dots in the local-part. I never imagined that a whole complex encoding system existed that allowed you to perform layers of encoding. Yet this is what I discovered. Scouring the RFC’s I noticed rfc2047 and encoded-word, this encoding system allows you to represent characters using hex and base64.
我越看,RFC 想要提供的电子邮件就越多。在这项研究之前,我曾假设电子邮件通常是字母数字,本地部分带有点。我从未想象过存在一个完整的复杂编码系统,可以让您执行多层编码。但这就是我发现的。在搜索 RFC 时,我注意到 rfc2047 和encoded-word ,该编码系统允许您使用十六进制和 base64 表示字符。

If we use an encoded email as an example illustration:
如果我们使用编码的电子邮件作为示例说明:

Splitting the email atom: exploiting parsers to bypass access controls

The “=?” indicates the start of an encoded-word, then you specify the charset in this case UTF-8. Then the question mark separates the next command which is “q” which signifies “Q-Encoding” after that there’s another question mark that states the end of the encoding format and the beginning of the encoded data. Q-Encoding is simply hex with an equal prefix. In this example I use =41=42=43 which is an uppercase “ABC”. Finally, ?= indicates the end of the encoding. When parsed by an email library the email destination would be [email protected]!
“=?”指示编码字的开始,然后在本例中指定字符集 UTF-8。然后问号分隔下一个命令,即“q”,表示“Q-Encoding”,之后还有另一个问号,表示编码格式的结束和编码数据的开始。 Q 编码只是具有相同前缀的十六进制。在此示例中,我使用=41=42=43,它是大写“ABC”。最后,?=表示编码结束。当由电子邮件库解析时,电子邮件目的地将是 [email protected]

Armed with this information I started to look for real systems that parsed emails using this encoding. To help with this I came up with two probes that worked on most sites that had this behaviour:
有了这些信息,我开始寻找使用这种编码解析电子邮件的真实系统。为了帮助解决这个问题,我想出了两个适用于大多数具有此行为的网站的探测器:

Splitting the email atom: exploiting parsers to bypass access controls

Initially I was using the charset “x” to reduce the size of the probe, however some systems reject unknown charsets and would fail. It’s best to use these two probes as I’ve found them to be the most common allowed charsets after testing lots of sites. Use the Collaborator to generate a payload and replace “collab” above with the generated one. Then if you get an SMTP interaction with the email in the RCPT TO command of the SMTP conversation:
最初我使用字符集“x”来减小探测器的大小,但是有些系统拒绝未知的字符集并且会失败。最好使用这两个探针,因为在测试了大量站点后我发现它们是最常见的允许字符集。使用 Collaborator 生成有效负载,并将上面的“collab”替换为生成的有效负载。然后,如果您在 SMTP 会话的 RCPT TO 命令中获得与电子邮件的 SMTP 交互:

[email protected]

This then proves the email parser is decoding the email with “encoded word”.
这证明电子邮件解析器正在使用“编码字”对电子邮件进行解码。

I found a bunch of sites with this behaviour and they all had one thing in common. Ruby. It appeared they all used the same Ruby Gem called “Mail” which has over 508 million downloads. I started to look at the source and I found that the library was decoding UTF-7! In my test bed I tried to reproduce this:
我发现了很多有这种行为的网站,它们都有一个共同点。红宝石。看来他们都使用了同一个 Ruby Gem,名为“Mail”,下载量超过 5.08 亿次。我开始查看源代码,发现该库正在解码 UTF-7 !在我的测试台上,我尝试重现这一点:

Splitting the email atom: exploiting parsers to bypass access controls

This is insane! Emails can have UTF-7 now! Then an idea popped into my head: if there is Q-Encoding and charsets, can you have both? The surprising answer to this question is a resounding yes. You can blend UTF-7 with Q-Encoding!
疯了吧!电子邮件现在可以使用 UTF-7 了!然后一个想法突然出现在我的脑海中:如果有 Q-Encoding 和字符集,你能两者兼而有之吗?这个问题令人惊讶的答案是肯定的。您可以将 UTF-7 与 Q-Encoding 混合!

Splitting the email atom: exploiting parsers to bypass access controls

After that I started to play with base64 encoding because of course “encoded-word” supports that in emails! You simply use “b” instead of “q” in the encoding type and you can use it.
之后我开始使用 Base64 编码,因为“encoded-word”当然支持电子邮件中的编码!您只需在编码类型中使用“b”而不是“q”即可使用它。

Splitting the email atom: exploiting parsers to bypass access controls

The preceding example uses base64 encoded string “foobar” which gets decoded by the parser. I know what you are thinking or maybe it’s just me but yes you can use UTF-7 and base64 encoded data:
前面的示例使用 base64 编码的字符串“foobar”,该字符串由解析器解码。我知道你在想什么,或者也许只是我的想法,但是你可以使用 UTF-7 和 base64 编码数据:

Splitting the email atom: exploiting parsers to bypass access controls

In this example there is a base64 encoded address with a UTF-7 charset. First the email parser will decode the base64. Then the email parser will decode the UTF-7 charset. Finally the email will be decoded to [email protected]. At this point you might have a few doubts about following the RFC to the letter. Especially when I tell you this works in the domain part too when I tested the Mail library. Note I’m using alphanumeric values here but you can of course encode any special characters too.
在此示例中,有一个采用 UTF-7 字符集的 Base64 编码地址。首先,电子邮件解析器将解码 Base64。然后电子邮件解析器将解码 UTF-7 字符集。最后,电子邮件将被解码为 [email protected]。此时,您可能对严格遵循 RFC 有一些疑问。特别是当我告诉你当我测试邮件库时这也适用于域部分。请注意,我在这里使用字母数字值,但您当然也可以对任何特殊字符进行编码。

Encoded-word case studies
编码词案例研究

Github: Accessing internal networks protected by Cloudflare “Zero Trust”
Github:访问受 Cloudflare“零信任”保护的内部网络

So far we’ve seen how to create email domain confusion and surprising encodings but it was time to use this knowledge to exploit real systems. One of the first targets I tested was Github. I specifically went after Github because I knew it was written in Ruby.
到目前为止,我们已经了解了如何创建电子邮件域混淆和令人惊讶的编码,但现在是使用这些知识来利用真实系统的时候了。我测试的第一个目标是 Github。我特别关注了 Github,因为我知道它是用 Ruby 编写的。

I used the two probes I mentioned earlier to confirm Github supported “encoded-word”. The email was decoded in the Collaborator SMTP conversation! So I began testing further. What I needed to do was to use “encoded-word” to produce another at symbol. At first I started playing with quoted local-part values and I was successful embedding raw at symbols in the quoted value. Maybe I could use “encoded-word” inside a quoted local-part to break out of the quoted value and produce two different addresses? I experimented with =22 (double quote) and =40 (at symbol) but didn’t have any success.
我使用了之前提到的两个探针来确认 Github 支持“encoded-word”。电子邮件在协作者 SMTP 对话中被解码!所以我开始进一步测试。我需要做的是使用“编码字”来生成另一个 at 符号。首先,我开始使用引用的本地部分值,并且成功地将原始符号嵌入到引用值中。也许我可以在引用的本地部分中使用“编码字”来打破引用的值并产生两个不同的地址?我尝试了 =22 (双引号)和 =40 (at 符号),但没有取得任何成功。

The trouble with this research is you don’t get any feedback sometimes because it passes the email validation but fails before it hits the mailer. You can use DNS interactions as a clue but often they are next to useless because you can’t identify the cause of the failure to get to the mailer.
这项研究的问题在于,有时您不会收到任何反馈,因为它通过了电子邮件验证,但在发送邮件之前就失败了。您可以使用 DNS 交互作为线索,但它们通常几乎毫无用处,因为您无法确定无法访问邮件程序的原因。

After many attempts I started to think about the SMTP conversation and I attempt to place greater than characters. The thinking here is that I could use it to end the RCPT TO command in the SMTP conversation:
经过多次尝试后,我开始考虑 SMTP 对话,并尝试放置多个字符。这里的想法是,我可以使用它来结束 SMTP 会话中的 RCPT TO 命令:

RCPT TO:<"[email protected]>collab"@psres.net>

The preceding example shows a quoted local-part with a raw at symbol and greater than. You can start to see how an attack could take shape. You have two addresses and the idea to use greater than would then enable you to ignore the second address in the SMTP conversation. With this idea fixed in my head I began using encoded vectors to construct an attack.
前面的示例显示了带有原始 at 符号和大于号的带引号的本地部分。您可以开始了解攻击是如何形成的。您有两个地址,如果使用大于的地址,则可以忽略 SMTP 对话中的第二个地址。有了这个想法,我开始使用编码向量来构建攻击。

I quickly found that double quotes weren’t of any use for Github, the reason for this is it always left an open double quote which would fail validation. I tried encoding it and escaping of course but with no success. I removed the quotes and used “encoded-word” to generate the at symbol and greater than, it passed validation but I didn’t get an email. No SMTP conversation. Nothing. Thinking about this I thought maybe the trailing junk at the end of the email was causing the Mailer to fail either with an exception or validation. What if I could introduce some characters that would avoid the exception or validation? I tried encoded whitespace but that failed then I tried an encoded null and bingo! I had an interaction with the following email:
我很快发现双引号对 Github 没有任何用处,原因是它总是留下一个打开的双引号,这会导致验证失败。我尝试对其进行编码并当然进行转义,但没有成功。我删除了引号并使用“编码字”生成 at 符号和大于号,它通过了验证,但我没有收到电子邮件。无 SMTP 对话。没有什么。考虑到这一点,我认为电子邮件末尾的尾随垃圾邮件可能导致邮件程序因异常或验证而失败。如果我可以引入一些可以避免异常或验证的字符怎么办?我尝试了编码的空白,但失败了,然后我尝试了编码的 null 和宾果游戏!我与以下电子邮件进行了互动:

Splitting the email atom: exploiting parsers to bypass access controls

For Github the charset doesn’t matter so I used “x”, the encoded at symbol (=40) gets converted to an at and the greater than (=3e) finishes the RCPT TO command and finally the null (=00) makes the mailer ignore everything after, you need to place a valid local-part after the encoded so I used “foo” this successfully passes validation and splits the email. I could then verify any email domain I liked. I had verified addresses on my test account with microsoft.com, mozilla.com and github.com:
对于 Github 来说,字符集并不重要,所以我使用“x”,编码的 at 符号 (=40) 转换为 at,大于 (=3e) 完成 RCPT TO 命令,最后 null (=00) 使邮件程序会忽略之后的所有内容,您需要在编码后放置一个有效的本地部分,因此我使用“foo”,这成功地通过了验证并拆分了电子邮件。然后我可以验证我喜欢的任何电子邮件域。我已通过 microsoft.com、mozilla.com 和 github.com 验证了我的测试帐户上的地址:

Splitting the email atom: exploiting parsers to bypass access controls

This was already a bug since you shouldn’t be able to verify addresses you don’t own. Then my colleague James Kettle suggested I look at Cloudflare “Zero Trust” and see if it could be configured to trust certain email domains. I created a test account and dug into the configuration and found you could use Github as an IdP and use the email domain to determine if you had access to a site. This could be an internal network or any other domain protected with Zero Trust provided they use Github as an IdP.
这已经是一个错误,因为您不应该能够验证不属于您的地址。然后我的同事James Kettle建议我查看 Cloudflare“零信任”,看看是否可以将其配置为信任某些电子邮件域。我创建了一个测试帐户并深入研究了配置,发现您可以使用 Github 作为 IdP,并使用电子邮件域来确定您是否有权访问某个站点。这可以是内部网络或受零信任保护的任何其他域,前提是他们使用 Github 作为 IdP。

Splitting the email atom: exploiting parsers to bypass access controls

Zendesk: Access email domain protected support centres
Zendesk:访问电子邮件域保护的支持中心

After my success with Github I began to look for applications that used Ruby and had some form of email domain validation. One that stood out to me was Zendesk because maybe you could get access to a protected support desk? Before I tried splitting email addresses I searched through their documentation and found you need to turn on the support centre, allow registration and then select domains that are allowed to register.
在 Github 取得成功后,我开始寻找使用 Ruby 并具有某种形式的电子邮件域验证的应用程序。对我来说最突出的是 Zendesk,因为也许您可以获得受保护的支持台?在尝试拆分电子邮件地址之前,我搜索了他们的文档,发现您需要打开支持中心,允许注册,然后选择允许注册的域。

The Support centre was configured and I began testing. I tried all the attacks I used on Github but with no success. Maybe they were using a different mailer or validation? I tried some new ideas using a quoted local-part of the email and with the interactions I got back in the Collaborator it seemed more promising then when I tested Github.
支持中心已配置完毕,我开始测试。我尝试了在 Github 上使用的所有攻击,但没有成功。也许他们使用了不同的邮件程序或验证?我使用电子邮件中引用的本地部分尝试了一些新想法,并且通过我在 Collaborator 中得到的交互,它似乎比我测试 Github 时更有希望。

What I found useful is using two duplicate Collaborator domains so I always got the interaction and by examining the SMTP conversation you could see what was being converted. I sent the following:
我发现有用的是使用两个重复的协作者域,因此我总是能够进行交互,并且通过检查 SMTP 对话,您可以看到正在转换的内容。我发送了以下内容:

Input:
[email protected]

And got the following back:
并得到以下返回:

Output:
RCPT TO:<"[email protected]> "@psres.net>

This interaction told me a bunch of things, first is they allow uppercase. Next is they allow converted spaces and third they seem to quote values that aren’t normally allowed in the local-part when decoded. Maybe I could abuse this behaviour?
这次交互告诉我很多事情,首先是它们允许大写。其次,它们允许转换空格;第三,它们似乎引用了解码时本地部分通常不允许的值。也许我可以滥用这种行为?

After many more attempts I finally got somewhere. I fooled the parsing/validation to convert characters blocked characters, doubled encoded quotes and generated characters that would be removed by their code until finally I constructed a valid email splitting attack:
经过多次尝试,我终于到达了某个地方。我愚弄了解析/验证来转换字符、阻止字符、加倍编码引号并生成将被代码删除的字符,直到最后我构造了一个有效的电子邮件拆分攻击:

Splitting the email atom: exploiting parsers to bypass access controls

Using this “email” I was able to bypass the restrictions set on the support centre. The key to this attack was the embedded encoded quotes that were decoded by the parser. Then the =3c22 generates a less than character that gets removed which then completes the quote so it passes by their validation/exceptions. You’ll notice the “=3e=00” is the same sequence I used on Github, so they obviously share some of the same code but how they responded was a lot different hence the more completed attack.
使用这个“电子邮件”,我能够绕过支持中心设置的限制。此攻击的关键是由解析器解码的嵌入编码引号。然后 =3c22 生成一个小于字符,该字符被删除,然后完成引用,以便它通过验证/异常。你会注意到“=3e=00”与我在 Github 上使用的序列相同,因此它们显然共享一些相同的代码,但它们的响应方式有很大不同,因此攻击更为完整。

Gitlab: Gain unauthorized access to Gitlab Enterprise servers
Gitlab:未经授权访问 Gitlab Enterprise 服务器

Looking for more Ruby fresh meat I turned to Gitlab. They are an IdP and offer an Enterprise product so it seemed like a good target to test. James had a Gitlab server he previously tested so I began looking at that first. You could configure it to allow registrations with a specific domain. So this immediately caught my attention. I tried the vectors I used on Github and Zendesk but they didn’t work. Then I remembered “encoded-word” allows you to use underscore as a space and this vector is the most elegant I’ve demonstrated so far:
为了寻找更多 Ruby 新鲜事,我转向了 Gitlab。他们是 IdP 并提供企业产品,因此它似乎是一个很好的测试目标。 James 有一个他之前测试过的 Gitlab 服务器,所以我首先开始查看它。您可以将其配置为允许使用特定域进行注册。所以这立即引起了我的注意。我尝试了在 Github 和 Zendesk 上使用的向量,但它们不起作用。然后我记得“encoded-word”允许您使用下划线作为空格,这个向量是迄今为止我演示过的最优雅的向量:

Splitting the email atom: exploiting parsers to bypass access controls

I used Postfix as the mailer of the configured Enterprise instance. You can use =20 to do the same thing but underscore is 1 character and I love elegant vectors!
我使用 Postfix 作为已配置的 Enterprise 实例的邮件程序。你可以使用 =20 来做同样的事情,但下划线是 1 个字符,我喜欢优雅的向量!

This means I could have gained access to Gitlab Enterprise servers that use domain-based registration restrictions. As I mentioned Gitlab is also an IdP so I began testing the web app too. The Enterprise hack didn’t work here. I think that’s because they use a different Mailer. However, it didn’t take me long to find another vector. By now I collected a bunch of vectors so I had a Turbo Intruder script that went through all the known vectors and also tried others. It found a new vector using an encoded space, this made sense since this worked on the Enterprise product it just required a different method to exploit:
这意味着我可以访问使用基于域的注册限制的 Gitlab Enterprise 服务器。正如我提到的,Gitlab 也是一个 IdP,因此我也开始测试该 Web 应用程序。企业黑客在这里不起作用。我认为那是因为他们使用了不同的邮件程序。然而,没过多久我就找到了另一个向量。到目前为止,我收集了一堆向量,所以我有一个 Turbo Intruder 脚本,它可以遍历所有已知向量并尝试其他向量。它使用编码空间找到了一个新向量,这是有道理的,因为这适用于企业产品,它只需要一种不同的方法来利用:

Splitting the email atom: exploiting parsers to bypass access controls

It’s very similar to the Github exploit but it required a valid charset and needed space not null. In the diagram I used “x” but in a real attack you’d use “iso-8859-1”.
它与 Github 漏洞非常相似,但它需要有效的字符集,并且所需的空间不为空。在图中我使用了“x”,但在真正的攻击中你会使用“iso-8859-1”。

PHPMailer PHP邮件程序

Unfortunately, I didn’t exploit everything I tested and there were many failures. Each one was a learning process but what was interesting about this case study was that “encoded-word” was being parsed and decoded on a system other than a Ruby based system.
不幸的是,我没有充分利用我测试的所有内容,并且出现了很多失败。每个都是一个学习过程,但这个案例研究的有趣之处在于“编码词”是在基于 Ruby 的系统以外的系统上解析和解码的。

I had already constructed a test bed on the advice of James and so I began testing how PHPMailer parsed emails. I did a mixture of black-box and white-box testing and I discovered that it didn’t parse “encoded-word” inside the local-part or domain part of the email address. However, it did parse and decode it in the name part outside of the email address!
我已经根据 James 的建议构建了一个测试床,因此我开始测试 PHPMailer 如何解析电子邮件。我进行了黑盒和白盒测试的混合,我发现它没有解析电子邮件地址的本地部分或域部分内的“编码字”。但是,它确实在电子邮件地址之外的名称部分中解析和解码了它!

=?utf8?q?=61=62=63?=<[email protected]>

Analysing the code the angle brackets where required which meant that it would often fail validation in applications like WordPress. I attempted to embed payloads in the name parameter of various applications but wasn’t able to exploit this particular library. Still I bet you can embed XSS payloads with “encoded-word” and this will work somewhere. Please get in touch if you manage to do it, I’d love to hear about it.
分析代码时需要使用尖括号,这意味着在 WordPress 等应用程序中验证通常会失败。我尝试将有效负载嵌入到各种应用程序的名称参数中,但无法利用这个特定的库。不过我打赌你可以使用“encoded-word”嵌入 XSS 有效负载,这将在某个地方起作用。如果您能做到,请与我联系,我很想听听。

Punycode  普尼码

We’ve already explored how you can manipulate email parsing to sidestep access controls. But let’s take things a little further. What if an email address could be weaponized to gain Remote Code Execution (RCE)? In this section, we’ll cover Punycode attacks and how I exploited Joomla.
我们已经探讨了如何操纵电子邮件解析来避开访问控制。但让我们更进一步。如果电子邮件地址可以被武器化以获得远程代码执行(RCE)怎么办?在本节中,我们将介绍 Punycode 攻击以及我如何利用 Joomla。

What is Punycode? 什么是 Puny 代码?

Punycode is a way to represent unicode characters in the current DNS system. Punycode always starts with xn-- and is followed by hyphens and alphanumeric characters. Non-ASCII characters are encoded using a special algorithm that represents these characters. The algorithm converts the sequence of Unicode characters into a representation that utilizes only ASCII characters. The algorithm dictates that generally any ASCII characters in the input that do not form unicode characters are to be added to the output as is. For example the domain münchen.com is encoded with the following Punycode sequence.
Punycode是当前DNS系统中表示unicode字符的一种方式。 Punycode 始终以 xn-- 开头,后跟连字符和字母数字字符。非 ASCII 字符使用表示这些字符的特殊算法进行编码。该算法将 Unicode 字符序列转换为仅使用 ASCII 字符的表示形式。该算法规定,通常输入中不形成 unicode 字符的任何 ASCII 字符都将按原样添加到输出中。例如,域 münchen.com 使用以下 Punycode 序列进行编码。

xn--mnchen-3ya.com

The very nature of how Punycode works makes it difficult to test because changing one character can affect the entire output and the character position due to how the algorithm works. What we want to do is generate malicious characters when the encoded value is decoded and doing that is a big challenge. In the following examples you can see the position of the unicode character changes when one byte is modified.
Punycode 工作方式的本质使其难以测试,因为由于算法的工作方式,更改一个字符可能会影响整个输出和字符位置。我们想要做的是在解码编码值时生成恶意字符,这是一个很大的挑战。在下面的示例中,您可以看到当修改一个字节时,unicode 字符的位置会发生变化。

[email protected] → foo@ümnchen.com
[email protected] → foo@münchen.com
[email protected] → foo@mnüchen.com
[email protected] → foo@mncühen.com

Malformed Punycode 格式错误的 Punycode

After reading all about this on Wikipedia, I followed a link to an online Punycode converter. The converter used the IDN PHP library. and started to try various Punycode addresses. I discovered that if you used two zeros at the start you could generate unintended characters:
在阅读完 Wikipedia 上的所有相关内容后,我点击了一个在线 Punycode 转换器的链接。该转换器使用 IDN PHP 库。并开始尝试各种Punycode地址。我发现如果你在开始时使用两个零,你可能会生成意想不到的字符:

Input:
psres.net.com.xn--0049.com.psres.net


Output:
psres.net.com.,.com.psres.net

This was my first successful attempt at creating malformed Punycode. The input contains the Punycode “xn--0049” which decodes to a comma thanks to a defective library. I was able to generate many more characters using this technique:
这是我第一次成功尝试创建格式错误的 Punycode。输入包含 Punycode“xn--0049”,由于有缺陷的库,它解码为逗号。我能够使用这种技术生成更多的字符:

Input:
[email protected]

Output:
foo@@.example.com

There were many ways to generate the same character. I thought about email splitting attacks but I concluded that the Punycode address wouldn’t be decoded when the email is sent because it would be invalid. It’s far more likely that it would be decoded when displaying the email. Naturally, the question I asked myself was can you create an XSS vector?
生成同一个角色的方法有很多种。我考虑过电子邮件拆分攻击,但我得出的结论是,发送电子邮件时 Punycode 地址不会被解码,因为它是无效的。显示电子邮件时更有可能被解码。当然,我问自己的问题是你能创建一个XSS向量吗?

This was a job for a fuzzer. I started constructing one and it immediately started to produce interesting results:
这是模糊器的工作。我开始构建一个,它立即开始产生有趣的结果:

x@xn--42 → x@,
x@xn--024 → x@@
x@xn--694 → x@;
x@xn--svg/-9x6 → x@<svg/
x@xn--svg/-f18 → x@<svg/
x@xn--svg/-fq1 → x@<svg/

I thought this would be a good time to find applications using the IDN PHP library. After searching Github I found an interesting target using the library: Joomla! This was great because if I get XSS then I have RCE. Doing source code analysis I noticed that they were escaping the email of users before it was Punycode decoded. This means if I could produce some malformed Punycode that when decode produces HTML I could get XSS but it wouldn’t be that easy.
我认为现在是寻找使用 IDN PHP 库的应用程序的好时机。在搜索 Github 后,我发现了一个使用该库的有趣目标:Joomla!这太棒了,因为如果我遇到了 XSS,那么我就遇到了 RCE。在进行源代码分析时,我注意到他们在 Punycode 解码之前转义了用户的电子邮件。这意味着,如果我可以生成一些格式错误的 Punycode,当解码生成 HTML 时,我可能会遇到 XSS,但事情不会那么容易。

Splitting the email atom: exploiting parsers to bypass access controls

Trying to exploit Joomla 尝试利用 Joomla

I went back to my fuzzer with excitement and started generating millions of character combinations. I managed to construct partial XSS vectors, but encountered several issues. I could only generate two ASCII characters by using more than one Punycode subdomain. This limitation arose from the specific workings of the Punycode algorithm, PHP, and the quirks of the buggy PHP IDN library. As you can see in the examples I was close but these problems made exploiting Joomla very difficult.
我兴奋地回到模糊器并开始生成数百万个字符组合。我设法构建了部分 XSS 向量,但遇到了几个问题。我只能通过使用多个 Punycode 子域来生成两个 ASCII 字符。此限制源于 Punycode 算法、PHP 的特定工作原理以及有缺陷的 PHP IDN 库的怪癖。正如您在示例中看到的那样,我已经很接近了,但这些问题使得利用 Joomla 变得非常困难。

xn--x-0314.xn--0026.xn--0193.xn--0218 → <x.. .=
xn--x-0314.xn--0026.xn--0193.xn--54_52932 → <x.. .='

I concluded that XSS was not feasible because, although I was able to generate a single-quoted HTML attribute, it required an underscore character. Joomla, however, does not permit underscores in the domain part of an email address.
我的结论是 XSS 不可行,因为虽然我能够生成单引号 HTML 属性,但它需要下划线字符。但是,Joomla 不允许在电子邮件地址的域部分中使用下划线。

Exploiting Joomla to achieve RCE
利用Joomla实现RCE

So was that the end of the story? Not quite. I thought about this for a while and worked out that if you use a single Punycode subdomain you could generate any opening tag! Eventually after a lot of testing I concluded that the only exploitable vector was an opening style tag:
那么故事就这样结束了吗?不完全的。我想了一会儿,发现如果您使用单个 Punycode 子域,您可以生成任何开始标记!最终,经过大量测试,我得出结论,唯一可利用的向量是开放样式标签:

Splitting the email atom: exploiting parsers to bypass access controls

The rest of the preexisting Joomla HTML code would add a space and closing angle bracket. The email was outputted on the user list page. This means it was persistent and also didn’t even need an activated account. You could simply register a user and it would be persistent style injection! But how do we get our evil CSS in there? To do that you need a place to put the CSS without being blocked. The name field of the user was a good choice for this and you could use an @import to import the evil style.
先前存在的 Joomla HTML 代码的其余部分将添加空格和右尖括号。邮件已输出到用户列表页面。这意味着它是持久的,甚至不需要激活帐户。您可以简单地注册一个用户,这将是持久样式注入!但是我们如何将邪恶的 CSS 放在那里呢?为此,您需要一个放置 CSS 且不会被阻塞的地方。用户的名称字段是一个不错的选择,您可以使用 @import 来导入邪恶的样式。

The problem I had was all the HTML code that occurs after the style injection would be treated as CSS! To get around this you simply need to fool the CSS parser into thinking this is all an invalid CSS selector and this means just using {}. So if you place after at the start of your name field you can then import a style after. The attack works like this:
我遇到的问题是样式注入后发生的所有 HTML 代码都会被视为 CSS!要解决这个问题,您只需欺骗 CSS 解析器,让它认为这都是无效的 CSS 选择器,这意味着只需使用 {}。因此,如果您将 after 放在名称字段的开头,则可以在后面导入样式。攻击的原理如下:

Splitting the email atom: exploiting parsers to bypass access controls

Notice the first account name has an “a” and the second account name has “x”, this is to ensure the style injection occurs first and the second account uses a @import. The curly braces are used to treat all the HTML that occurs before the import as an invalid CSS selector. Chrome’s strict CSS mime type check doesn’t apply here either because an inline style was used.
请注意,第一个帐户名称有“a”,第二个帐户名称有“x”,这是为了确保样式注入首先发生,第二个帐户使用 @import。大括号用于将导入之前出现的所有 HTML 视为无效 CSS 选择器。 Chrome 严格的 CSS mime 类型检查在这里也不适用,因为使用了内联样式。

What we needed to do now is exfiltrate the CSRF token via CSS and thankfully there have been many good posts on this. The best way is to use import chaining and use one of the tools developed by d0nut and Pepe Vila. I decided to customise the tool I already developed with my blind CSS exfiltration research which involved making it extract the specific Joomla token. I’ll share the customised code in the Github repo later in the post.
我们现在需要做的是通过 CSS 窃取 CSRF 令牌,值得庆幸的是,有很多关于这方面的好文章。最好的方法是使用导入链并使用d0nutPepe Vila开发的工具之一。我决定定制我已经通过盲目 CSS 渗透研究开发的工具,其中涉及使其提取特定的 Joomla 令牌。我将在本文后面的 Github 存储库中分享自定义代码。

With my CSS exfiltrator running, I registered the two accounts and visited the users page with the super admin account. The exfiltrator showed the admin’s CSRF token so now the next step was to feed the admin the CSRF exploit that used the exfiltrated token. My exfiltrator also builds the CSRF exploit. The exploit then activates the attacker’s account and makes them super admin. Then the attacker can modify an admin template to get RCE!
当我的 CSS exfiltrator 运行时,我注册了两个帐户并使用超级管理员帐户访问了用户页面。泄露者显示了管理员的 CSRF 令牌,因此下一步是向管理员提供使用泄露令牌的 CSRF 漏洞。我的 exfiltrator 还构建了CSRF 漏洞。然后,该漏洞会激活攻击者的帐户并使他们成为超级管理员。然后攻击者可以修改管理模板来获取RCE!

Here is a demo of the attack:
这是攻击的演示:

In the video the admin browser in lighter colours is on the left and the attacker’s browser is in darker colours on the right. The attacker registers two accounts, the first to inject the style tag from a malformed Punycode address, and the second to inject the CSS exfiltration stylesheet. Then the admin visits the backend and the user list page, the malicious CSS gets loaded instantly and exfiltrates the token in seconds.
在视频中,管理浏览器的颜色较浅,位于左侧,攻击者的浏览器的颜色较深,位于右侧。攻击者注册两个帐户,第一个帐户从格式错误的 Punycode 地址注入样式标签,第二个帐户注入 CSS 渗透样式表。然后管理员访问后端和用户列表页面,恶意CSS立即加载并在几秒钟内窃取令牌。

 

As soon as this happens the attacker gets notified of the admin’s CSRF token and then starts an instant message conversation with the admin. The admin clicks the link from the attacker and gets CSRF’d to edit a backend template to inject some PHP that calls the system command to cat /etc/passed.
一旦发生这种情况,攻击者就会收到管理员的 CSRF 令牌的通知,然后开始与管理员进行即时消息对话。管理员单击来自攻击者的链接并获取 CSRF 来编辑后端模板以注入一些 PHP,该 PHP 调用系统命令到 cat /etc/passed。

Methodology/Tooling  方法/工具

Splitting the email atom: exploiting parsers to bypass access controls

Whilst conducting this research I developed a methodology that I found useful when testing. Probe, Observe, Encode and Exploit. First use the probes mentioned in this post and then observe the results in a tool like Collaborator. Repeat the process until you have the required characters for your attack. Then when this process is finished do the exploit. You can apply this methodology to both encoded-word and Punycode attacks.
在进行这项研究时,我开发了一种在测试时有用的方法。探测、观察、编码和利用。首先使用本文中提到的探针,然后在 Collaborator 等工具中观察结果。重复此过程,直到获得攻击所需的字符。然后,当这个过程完成时,进行漏洞利用。您可以将此方法应用于编码字攻击和 Punycode 攻击。

First probe for “encoded-word”, observe the decoded email to confirm that it is supported. Then encode various characters and observe how they are decoded. Then follow up with an exploit that abuses these characters.
首先探测“encoded-word”,观察解码的电子邮件以确认它受支持。然后对各种字符进行编码并观察它们是如何解码的。然后跟进滥用这些角色的漏洞。

To observe the results I used Burp Collaborator which allowed me to view SMTP interactions.
为了观察结果,我使用了Burp Collaborator ,它允许我查看 SMTP 交互。

Generating email splitting attacks with Hackvertor tags
使用 Hackvertor 标签生成电子邮件拆分攻击

To assist with finding email splitting attacks I’ve created a couple of Hackvertor tags. Hackvertor is a free Burp Suite extension I wrote that allows you to use tags in a request and perform nested conversions on the data. You simply place the tag where you want the unicode overflow to happen and then place the characters you want to convert inside the tag:
为了帮助查找电子邮件拆分攻击,我创建了几个 Hackvertor 标签。 Hackvertor是我编写的一个免费的 Burp Suite 扩展,它允许您在请求中使用标签并对数据执行嵌套转换。您只需将标记放置在希望发生 unicode 溢出的位置,然后将要转换的字符放置在标记内:

<@_unicode_overflow(0x100,'...')>@</@_unicode_overflow>
<@_unicode_overflow_variations(0xfff,'...')>@</@_unicode_overflow_variations>
foo<@_encoded_word_encode('...')>@<@/_encoded_word_encode>example.com
<@_encoded_word_decode('...')>=41=42=43<@/_encoded_word_decode> <@_email_utf7('...')><@/_email_utf7> <@_email_utf7_decode('...')><@/_email_utf7_decode> <@_encode_word_meta('iso-8859-1','...')><@/_encode_word_meta>

The first tag creates a single unicode overflow and uses the tag argument 0x100 which is 256 in decimal to create the overflow. The second uses the tag argument as the maximum unicode codepoint and generates as many characters as it can that overflow to the character specified inside the tag. The third tag will allow you to perform an encoded-word conversion, in the example I encode the @ symbol. The forth tag will decode the encoded-word sequence. There are further tags to help create and decode UTF-7 emails and the encoded-word meta characters.
第一个标记创建单个 unicode 溢出,并使用标记参数 0x100(十进制 256)来创建溢出。第二个使用标记参数作为最大 unicode 代码点,并生成尽可能多的字符,这些字符溢出到标记内指定的字符。第三个标签将允许您执行编码字转换,在示例中我对@符号进行编码。第四个标签将对编码字序列进行解码。还有更多标签可帮助创建和解码 UTF-7 电子邮件以及编码字元字符。

To use these tags you need to enable “Allow code execution tags” in the Hackvertor menu. Then click the “View Tag Store” in the same menu. You can then install both tags by clicking on their name and then using the install button.
要使用这些标签,您需要在 Hackvertor 菜单中启用“允许代码执行标签”。然后单击同一菜单中的“查看标签存储”。然后,您可以通过单击标签名称并使用安装按钮来安装这两个标签。

Automate exploitation of encoded-word with Turbo Intruder
使用 Turbo Intruder 自动利用编码字

When I found the first few bugs I found automation very useful for finding other bugs and often Turbo Intruder was very useful to automate this process. Turbo Intruder is another free Burp extension written by James Kettle. I’ve created a Turbo Intruder script to help exploit a mailer. This script is used when you’ve identified that the server supports encoded-word but you want to know if the mailer will allow you to split the email by using nulls or other characters.
当我发现前几个错误时,我发现自动化对于查找其他错误非常有用,并且Turbo Intruder通常对于自动化此过程非常有用。 Turbo Intruder 是James Kettle编写的另一个免费的 Burp 扩展。我创建了一个 Turbo Intruder 脚本来帮助利用邮件程序。当您确定服务器支持编码字,但您想知道邮件程序是否允许您使用空值或其他字符拆分电子邮件时,请使用此脚本。

It uses a list of known techniques that split an email that I’ve discovered whilst testing Github, Zendesk, Gitlab, Bugcrowd and many others. You can easily customise the script to perform other attacks mentioned in this presentation. To use it you just need to change the validServer variable to your target domain to spoof. You then place %s in the request where you want your email to be added and then right click on the request and send to Turbo Intruder and use the modified script. Then run the attack. If the attack works you should receive a collaborator interaction within Turbo Intruder. This means the email domain is spoofable. If you encounter applications with rate limits (as I did) you can change the REQUEST_SLEEP variable to play nicely with those servers.
它使用了我在测试 Github、Zendesk、Gitlab、Bugcrowd 等许多其他工具时发现的一系列已知技术来分割电子邮件。您可以轻松自定义脚本来执行本演示中提到的其他攻击。要使用它,您只需将 validServer 变量更改为您的目标域即可进行欺骗。然后,您将 %s 放入要添加电子邮件的请求中,然后右键单击该请求并将其发送到 Turbo Intruder 并使用修改后的脚本。然后发动攻击。如果攻击有效,您应该会在 Turbo Intruder 中收到协作者交互。这意味着电子邮件域是可欺骗的。如果您遇到有速率限制的应用程序(就像我所做的那样),您可以更改 REQUEST_SLEEP 变量以与这些服务器很好地配合。

Splitting the email atom: exploiting parsers to bypass access controls

Fuzzing for malformed Punycode
对格式错误的 Punycode 进行模糊测试

Splitting the email atom: exploiting parsers to bypass access controls

I created a Punycode fuzzer to help find malform Punycode. I shared it with my PortSwigger colleagues and I created a challenge to see if anyone could generate an XSS vector within the restrictions I had. Nobody managed it but I got RCE anyway via CSS exfiltration. The fuzzer works by giving it some input with a Punycode address and the placeholders are substituted with random numbers, characters or whitespace. Matches and contains are just regexes to match the fuzzed output. It was very effective in finding what characters could be generated.
我创建了一个 Punycode 模糊器来帮助查找错误的 Punycode。我与我的 PortSwigger 同事分享了它,并发起了一个挑战,看看是否有人可以在我的限制范围内生成 XSS 向量。没有人管理它,但我还是通过 CSS 渗透获得了 RCE。模糊器的工作原理是通过 Punycode 地址为其提供一些输入,并将占位符替换为随机数字、字符或空格。匹配和包含只是匹配模糊输出的正则表达式。它对于寻找可以生成哪些字符非常有效。

Defence  防御

I recommend you disable “encoded-word” when using an email parsing library. As a last resort you can prevent it from being used by looking for the opening and closing characters of “encoded-word” in the email address using the following regex:
我建议您在使用电子邮件解析库时禁用“编码字”。作为最后的手段,您可以通过使用以下正则表达式在电子邮件地址中查找“encoded-word”的开始和结束字符来防止它被使用:

=[?].+[?]=

You should always validate an email address even when it comes from a SSO provider such as Github. Never use the email domain as a sole means of authorisation, because it can be easily spoofed as we’ve seen.
您应该始终验证电子邮件地址,即使它来自 SSO 提供商(例如 Github)。切勿使用电子邮件域作为唯一的授权方式,因为正如我们所见,它很容易被欺骗。

Materials 材料

All materials for this research is available on the Github repository
本研究的所有材料均可在Github 存储库中获取

CTF

We’ve created a CTF on the Web Security Academy so you can try out your new skills. For your convenience I’ve also created a docker file with the vulnerable version of Joomla in the Joomla directory of the Git repository.
我们在网络安全学院创建了 CTF,以便您可以尝试新技能。为了您的方便,我还在 Git 存储库的 Joomla 目录中使用易受攻击的 Joomla 版本创建了一个 docker 文件。

Timeline 时间线

Reported to Joomla on 30th Jan, 2024, 3:40pm – Fixed on 20th Feb, 2024 CVE-2024-21725
于 2024 年 1 月 30 日下午 3:40 向 Joomla 报告 – 于 2024 年 2 月 20 日修复 CVE-2024-21725

Reported to IDN library on 8th Feb, 2024, 11:49am – Fixed on 14th Feb, 2024
于 2024 年 2 月 8 日上午 11:49 向 IDN 图书馆报告 – 于 2 月 14 日修复 2024

Reported to Gitlab on 5th Feb, 2024, 11:55am – Fixed on April 25, 2024
于 2024 年 2 月 5 日上午 11:55 向 Gitlab 报告 – 于 2024 年 4 月 25 日修复

Reported to Github on 5th Feb, 2024, 11:55am – Fixed on May 9, 2024
于 2024 年 2 月 5 日上午 11:55 向 Github 报告 – 于 2024 年 5 月 9 日修复

Reported to Zendesk on 5th Feb, 2024, 2:54pm – Fixed on May 9, 2024
于 2024 年 2 月 5 日下午 2:54 向 Zendesk 报告 – 于 2024 年 5 月 9 日修复

原文始发于Gareth HeyesSplitting the email atom: exploiting parsers to bypass access controls

版权声明:admin 发表于 2024年8月8日 上午9:32。
转载请注明:Splitting the email atom: exploiting parsers to bypass access controls | CTF导航

相关文章