Shellcode-exit-normally

前言

最近在和binpang一起设计南京大学软件安全的课程试验,发现buffer overflow漏洞程序和一个正确的shellcode,不能实现攻击并打开shell。然后和binpang做出一些验证,尝试去解释这个问题。

简单介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// buf2.c
// gcc −z execstack −o buf buf2
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void vul(char *str){
char buffer[36];
// buffer overflow
strcpy(buffer, str);
}
buf2 . c −fno−stack−protector
int main(int argc, char **argv){
char str[128];
int n = read(0, str, 128);
if(n < 0){
printf("Read Error\n");
exit(-1);
}
vul(str);
printf(”Returned Properly\n”);
return 0;
}

存在一个正确的exp文件,包含正确的返回地址、buffer首地址和启动shell的代码。输入方式如果使用:

1
./buf < poc

不能打开一个可以交互式的shell。但是如果使用下面的触发方式,则可以打开一个可以交互式的shell:

1
cat poc - | ./buf

原因

经过查阅资料发现,我们在使用输入重定位的时候,就相当于将进程的输入重定位到文件中,而当程序将文件中的内容读完之后,会关闭该文件,此时相当于将程序的输入(stdin)关闭了。
当该进程启动一个shell进程时,shell进程是该进程的子进程,继承了父进程的文件描述符(包括已经关闭了的标准输入),此时shell发现标准输入已经关闭了,就会退出。

具体细节可以到 binpang 查阅。

Ref

https://blog.binpang.me/2019/03/22/shellcode-exit/