The below code is expecting a binary file.
#include <stdio.h>
#include <string.h>
#define bufsz 100
const char msg[] = "Usage: %s <shellcode file>\n";
static char buffer1[bufsz];
static char buffer2[bufsz];
void usage(char *self) {
printf(msg, self);
exit(1);
}
int main(int argc, char *argv[]) {
FILE *fp;
void (*funcptr)();
if (argc != 2)
usage(argv[0]);
if ((fp = fopen(argv[1], "rb")) == NULL ) {
printf("fail to open file: %s\n", argv[1]);
exit(1);
};
fgets(buffer1, bufsz, fp);
fclose(fp);
strcpy(buffer2, buffer1);
if (strlen(buffer2) >= 40)
printf("your shellcode is too long! \n");
if (strlen(buffer2) < 30)
printf("your shellcode is less than 30 bytes!\n");
if (strstr(buffer2, "/bin/sh"))
printf("Malicious code detected!\n");
funcptr = (void *) buffer2;
(*funcptr)(); /* execute your shell code */
return 0;
}
Therefore, I created the below shellfile.c
that contains 19 bytes to test the above app
int main(){
/* push trick */
__asm__("push $0;\n\
push $2;\n\
movl %esp, %ebx;\n\
xorl %ecx, %ecx;\n\
mov $162, %al;\n\
int $0x80;\n\
xorl %ebx, %ebx;\n\
leal 0x1(%ebx), %eax;\n\
int $0x80;\n\
");
return 0;
}
Compiled it, but the code is retrieving the below error:
gcc -o codetest -g -ggdb codetest.c
./runshell testcode
your shellcode is less than 30 bytes!
Illegal Instruction
Where is the issue exactly?
The requirements for your shellcode are :
\x00
) or strlen
will fail\x0A
) or fgets
will failYour first instruction is push $0
so the two first bytes of your shellcode is \x6A\x00
.
The size of the buffer is 1
(strlen
stops after a null byte).
That's why you have the error your shellcode is less than 30 bytes!
.
Consider this shellcode, which is equivalent to yours, except push $1
to avoid null byte :
6A01 push $1 ;to avoid null byte
6A02 push $2
89E3 movl %esp, %ebx ;ebx now points on top of stack
31C9 xorl %ecx, %ecx ;ecx=0
B0A2 mov $162, %al ;eax=162
CD80 int $0x80 ;call sys_nanosleep because eax=162 with arguments ebx and ecx (ebx={1,2} and ecx=NULL)
31DB xorl %ebx, %ebx ;ebx=0
678D4301 leal 0x1(%ebx), %eax ;eax=1
CD80 int $0x80 ;call sys_exit because eax=1, with code 0 (ebx value)
Basically, this shellcode waits 2 seconds (and 1 nanosecond) and exits.
int 0x80
is a system call depending of eax
value, more information here
You still have a problem, the length of this shellcode is 20 bytes.
You just have to add eleven NOP
's (0x90
) at the beginning (or at the end) to fill the requirement.
Try this :
echo -e '\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x6A\x01\x6A\x02\x89\xE3\x31\xC9\xB0\xA2\xCD\x80\x31\xDB\x67\x8D\x43\x01\xCD\x80' > shellcode.bin
./runshell shellcode.bin
If the program waits 2 seconds and successfully exits (with code 0), then the shellcode was executed.
If necessary, I can explain you how to code a shellcode which permits to get the rights of runshell
program which is often the goal of this kind of exercice (and obviously the case here with the test on "/bin/sh"
).