I wrote the code below to test shellcode (for unlinking /tmp/passwd
) for an assignment in a security class.
When I compile with gcc -o test -g test.c
, I get a segfault on the jump into the shellcode.
When I postprocess the binary with execstack -s test
, I no longer get a segfault and the shellcode executes correctly, removing /tmp/passwd
.
I am running gcc 4.7.2
. It seems like it is bad idea to require the stack to be executable in order to make the heap executable, since there are many more legitimate use cases of the latter than the former.
Is this expected behavior? If so, what is the rationale?
#include <stdio.h>
#include <stdlib.h>
char* shellcode;
int main(){
shellcode = malloc(67);
FILE* code = fopen("shellcode.bin", "rb");
fread(shellcode, 1, 67, code);
int (*fp)(void) = (int (*) (void)) shellcode;
fp();
}
Here is the output of xxd shellcode.bin
:
0000000: eb28 5e89 760c 31c0 8846 0bfe c0fe c0fe .(^.v.1..F......
0000010: c0fe c0fe c0fe c0fe c0fe c0fe c0fe c089 ................
0000020: f3cd 8031 db89 d840 cd80 e8d3 ffff ff2f ...1...@......./
0000030: 746d 702f 7061 7373 7764 tmp/passwd
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…