25 May 2021

house of your mother's mourning hall——一种全新的堆利用方法

Abstract

GNU Libc is the standard C runtime library of most Linux distributions for PC and servers. There used to be many memory corruption exploit techniques against ptmalloc. But the widely deployment of mitigations on modern operating systems and continuous patching to ptmalloc effectively fuck most of these techniques. In this paper, 👴 present some new exploit methods against ptmalloc along with proof of concept code.

house of your mother’s mourning hall

该攻击方式适用于所有 libc

当程序中存在 system("/bin/sh") 时,我们可以直接 getshell

本质上是通过 liibc 下的 get_shell_attack 以及 input_666 利用,来配合 libc 下的 system_attack 进行组合利用的方法。主要适用于程序中仅有 gift 函数能用,其他选项都不管用的情况。(因为选择其他选项只会打印 NO_IMPLEMENT,无法完成常规的 tcache attack 等利用)

该方法最为核心的地方在于,利用了 glibc 中 system() 函数可以 getshell,并且执行 system() 函数可以通过输入 666 进 gift() 实现。

关于 libc 下的 input_666 的手法可以参考:c-switch 语句,该攻击的最终效果是可以执行 gift() 函数。

关于 libc 下的 system_attack 的细节详见:libc 源码,该攻击的最终效果有一堆,我们这里使用的是该攻击可以 get shell 效果特性。

example

这里以 mourning hall ctf final 的 house of your mother’s mourning hall 题目为例

======================
    mourning hall
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:

菜单只有五个选项,但是如果我们输入 666,就可以进入 gift,调用 system("/bin/sh")

======================
    mourning hall
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:666
# cat flag
flag{nmsl}

目前已经有很多 gift 666 利用的题目,但是我第一次把这称作 house of your mother’s mourning hall,所以这是一种全新的堆利用方法

build the mourning hall

如何出一道考察 hom 的题目

  1. 找一道题
  2. 有源码就直接用,没源码重复 1,或者自己照着写一遍
  3. 把菜单换成 house of your mother’s mourning hall
  4. 添加 house of your mother’s mourning hall 知识点
  5. 题目名称:house of your mother’s mourning hall
  6. 难度标为困难,打包交给主办方,等着收钱
  7. 主办方办比赛用到这道题时,直接参赛

example

找到第六届贵校信息安全竞赛中的 White_Give_Flag

void menu(){
   puts("======================");
   puts("      White Give      ");
   puts("======================");
   puts("1.Add");
   puts("2.Show");
   puts("3.Delete");
   puts("4.Edit");
   puts("5.Exit");
   puts("======================");
   printf("choice:");
}

修改菜单

void menu(){
   puts("======================");
   puts("    mourning hall     ");
   puts("======================");
   puts("1.NM$L");
   puts("2.Show the corpse");
   puts("3.Cremate your mother");
   puts("4.Edit the corpse");
   puts("5.Exit");
   puts("======================");
   printf("choice:");
}

出好了!此时,我提出一种全新的堆利用方法:house of your mother’s mourning hall plus

house of your mother’s mourning hall plus

该攻击方式适用于所有 libc

当程序可以打印 flag 时,我们可以直接得到 flag

本质上是通过 liibc 下的 open_read_flag 以及 puts_flag 利用,来配合 libc 下的 read_ret_0 进行组合利用的方法。主要适用于程序中仅有 gift 函数能用,其他选项都不管用的情况。(因为选择其他选项只会打印 NO_IMPLEMENT,无法完成常规的 tcache attack 等利用)

该方法最为核心的地方在于,利用了 glibc 中 read() 函数可以返回 0,并且执行 puts(array[0]) 函数可以通过 read() 返回 0 实现。

关于 libc 下的 puts_flag 的手法可以参考:c-数组,该攻击的最终效果是可以打印 flag。

关于 libc 下的 read_ret_0 的细节详见:libc 源码,该攻击的最终效果是返回 0 ,我们这里使用的是该攻击可以返回 0 效果特性。

example

这里以 mourning hall ctf final 的 house of your mother’s mourning hall plus 题目为例

======================
    mourning hall
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:

读取选项时返回值是 read() 返回值

int read_choice(){
    char buf[8];
    int ret = read(0,buf,8);
    int choice = atoi(buf);
    if(ret > 5){
        exit(0);
    }
    if(ret < 0){
        exit(0);
    }
    return ret;
}

每个选项都会打印对应字符串

choice = read_choice();
puts(msg_ptr[choice]);

真正的核心漏洞是在 init() 中,这里把 flag 读了,放到 msg_ptr[0]

这里注意一个细节,我在出题的时候把变量名改了,比只改菜单不知道高到哪里去了。

void init(){
    open("./flag",0);
    read(3,flag,38);
    close(3);
    msg_ptr[0] = flag;
    msg_ptr[1] = nmsl_msg;
    msg_ptr[2] = show_the_corpse_msg;
    msg_ptr[3] = cremate_your_mother_msg;
    msg_ptr[4] = edit_the_corpse_msg;
    msg_ptr[5] = bye_msg;
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
}

由于每个功能都没有实现

void add(){
	puts("NO_IMPLEMENT");
}

void show(){
	puts("NO_IMPLEMENT");
}

void delete(){
	puts("NO_IMPLEMENT");
}

void edit(){
	puts("NO_IMPLEMENT");
}

所以无法使用 tcache attack,所以也不能用 fastbin attack。

这里就需要利用我们的 house of your mother’s mourning hall。详见 exp

from pwn import *
r = process('./pwn')
r.recvuntil('choice:')
r.shutdown_raw('send')
r.interactive()

read() 读到 EOF 返回 0,puts() 越界打印 flag

======================
    mourning hall
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:flag{nmsl}

Invalid!

house of your mother’s ashes

该攻击方式适用于所有 libc

当程序中存在 system("/bin/sh") 时,我们可以直接 getshell

本质上是通过 liibc 下的 get_shell_attack 以及 input_nmsl 利用,来配合 libc 下的 system_attack 进行组合利用的方法。主要适用于程序中仅有 gift 函数能用,其他选项都不管用的情况。(因为选择其他选项只会打印 NO_IMPLEMENT,无法完成常规的 tcache attack 等利用)

该方法最为核心的地方在于,利用了 glibc 中 system() 函数可以 getshell,并且执行 system() 函数可以通过输入 nmsl 进 gift() 实现。

关于 libc 下的 input_nmsl 的手法可以参考:c 库函数 strncmp(),该攻击的最终效果是可以执行 gift() 函数。

关于 libc 下的 system_attack 的细节详见:libc 源码,该攻击的最终效果有一堆,我们这里使用的是该攻击可以 get shell 效果特性。

该利用方法对 house of your mother’s mourning hall 进行了优化,因为已经提出 house of your mother’s mourning hall plus 并且我更想提出一个新的 house of,我决定把这种利用方法称为 house of your mother’s ashes。

在 house of your mother’s mourning hall 中,需要输入 666 才能进入 gift() 函数,但是输入 666 并不契合 house of your mother’s mourning hall 这一名称,所以我对该利用方法进行优化,将输入 666 改为输入 nmsl,使其与名称更加符合,提出 house of your mother’s ashes 这一全新的利用方法。

example

这里以 mourning hall ctf final 的 house of your mother’s ashes 题目为例

======================
        ashes
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:

菜单只有五个选项,但是如果我们输入 nmsl,就可以进入 gift,调用 system("/bin/sh")

======================
    mourning hall
======================
1.NM$L
2.Show the corpse
3.Cremate your mother
4.Edit the corpse
5.Exit
======================
choice:nmsl
# cat flag
flag{nmsl}

Tags:
0 comments



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

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0).