Section outline

  • Ubuntu 操作系统中的 dash shell 在检测到有效 UID 不等于真实 UID 时(这在 setuid 程序中是这种情况),会通过将有效 UID 变为真实 UID 来放弃权限。我们之前让 /bin/sh 指向另一个名为 zsh 的 shell,它没有这样的防御措施。在本任务中我们将将其变回,并看看如何击败该防御措施。请执行以下操作以使 /bin/sh 指向 /bin/dash。

    $ sudo ln -sf /bin/dash /bin/sh

    为了击败缓冲区溢出攻击中的 dash 防御措施,我们需要做的就是更改真实 UID,使其等于有效 UID。当 root 所拥有的 setuid 程序运行时,有效 UID 为零,在执行 shell 程序之前,我们只需将真实 UID 更改为零即可。 这可以通过在 shellcode 中调用 setuid(0) 来实现。

    以下汇编代码演示了如何调用 setuid(0)。二进制代码已置于 call_shellcode.c 内,你只需将其添加到 shellcode 的开头即可。

    ; 调用 setuid(0): 32位
    xor ebx, ebx      ; ebx = 0: setuid() 的参数
    xor eax, eax
    mov  al, 0xd5     ; setuid() 的系统调用号
    int 0x80
    
    ; 调用 setuid(0): 64位
    xor rdi, rdi      ; rdi = 0: setuid() 的参数
    xor rax, rax       
    mov  al, 0x69     ; setuid() 的系统调用号
    syscall

    编译 call_shellcode.c 成一个 root 所拥有的二进制文件(键入 "make setuid")。运行 shellcode a32.out 和 a64.out,并带有或不带 setuid(0) 系统调用。请描述和解释你的观察结果。

    现在,使用更新的 shellcode 你可以再次针对易受攻击的程序发起攻击,并且这一次,shell 的防御机制已开启。 重复任务 3 的攻击,看看你是否能够获得 root shell。获取 root shell 后,请运行以下命令来验证此防御措施已启用。虽然不需要在任务 2 和任务 3 上重复进行相同的攻击,但你可以自由尝试并查看它们是否会起作用。