应用自定义协议(Custom URI Scheme)相关记录

自定义协议的相关问题其实比较古老了,08 年时就已经在 BH 上被提出来,最近因为 Electron 远程代码执行漏洞(CVE-2018-1000006)又一次被提起,借此机会刚好把之前学习的相关内容整理下,备忘。

1. 应用自定义协议(Custom URI Scheme)

应用程序为了方便交互、调用常会在操作系统中注册自定义协议和 Handler,以 TIM QQ 为例,其注册了如下协议:

此处注册的意义是当外部应用(浏览器、Windows Run…)调用到 Tim 协议时会调用 C:\Program Files (x86)\Tencent\TIM\Bin\Timwp.exe 对输入进行处理,并将参数通过 “%1” 传递给程序。如外部应用调用如下链接:

实际的调用为:

其中的“"”是可以通过注入“"”闭合的,如微软文档所言:

Because Internet Explorer will decode all percent-encoded octets in the URI before passing the resulting string to ShellExecute, URIs such as alert:%3F? will be given to the alert application pluggable protocol handler as alert:??. The handler won’t know that the first question mark was percent-encoded. To avoid this issue, pluggable protocol handlers and their associated URI scheme must not rely on encoding. If encoding is necessary, protocol handlers should use another type of encoding that is compatible with URI syntax, such as Base64 encoding. Double percent-encoding is not a good solution either; if the application protocol URI isn’t processed by Internet Explorer, it will not be decoded.

When ShellExecute executes the pluggable protocol handler with a stringon the command line, any non-encoded spaces, quotes, and backslashes in the URI will be interpreted as part of the command line. This means that if you use C/C++’s argc and argv to determine the arguments passed to your application, the string may be broken across multiple parameters. To mitigate this issue:

  • Avoid spaces, quotes, or backslashes in your URI
  • Quote the %1 in the registration ("%1" as written in the ‘alert’ example registration)

However, avoidance doesn’t completely solve the problem of quotes in the URI or a backslash at the end of the URI.

也就是说可以通过注入“"”而引入任何参数,这便是 Electron 漏洞的原理。

2. 相关漏洞

理解了什么是自定义协议再看相关漏洞就简单很多,其实就是一个能被其他应用调用的输入点,这里的其他应用包括但不限于浏览器(相对直接的利用方式)、快捷方式等。下面看几个比较典型的案例。

上古时期的 ShellExecute

Windows XP 和 Windows 2003 安装 IE 7 后 ShellExecute 这个 API 进行了一些变动,具体表现为:当传递给 ShellExecute 的参数中包含“%”时,该函数会认为认为参数不正确,然后试图“修复”它,而这个“修复”会导致命令注入。更操蛋的是,自定义 URI 协议的调用底层实现也是 ShellExecute,也就是说任何注册了自定义协议的应用都可以被远程命令执行。

以 mailto 协议为例,调用如下链接:

调用 ShellEecute

“修复”后:

Firefox 浏览器命令注入

Firefox 2.0 注册自定义协议如下:

上面提过,通过注入“"”可以引入任何参数,Firefox 提供了如下参数:

通过注入 -new-window/-chrome 参数可以做本地域的 UXSS、命令执行:

解码后的Payload:

是不是和 Electron 这个洞很像?历史总是相似的:)

QQ 游戏命令注入

@redrain 之前 slide 中提到过一个 QQ 游戏的命令注入,输入点也是自定义协议,具体可以看 http://www.hackdog.me/paper/Attack_Surface_Extended_by_URL_Schemes.pdf

某下载软件缓冲区溢出

这得等另一个故事了~

3. 参考