C 外壳代码和二进制文件
下面的代码需要一个二进制文件C 外壳代码和二进制文件,c,shellcode,C,Shellcode,下面的代码需要一个二进制文件 #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);
#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;
}
已编译,但代码正在检索以下错误:
gcc -o codetest -g -ggdb codetest.c
./runshell testcode
your shellcode is less than 30 bytes!
Illegal Instruction
问题到底在哪里?fgets(buffer1、bufsz、fp);
fgets(buffer1, bufsz, fp);
...
if (strlen(buffer2)<30)
printf("your shellcode is less than 30 bytes!\n");
...
如果(strlen(buffer2)对外壳代码的要求是:
- 长度在31到40之间
- 任何零字节(
\x00
)或strlen
都不会失败
- 任何'\n'字节(
\x0A
)或fgets
都不会失败
- 否“/bin/sh”子字符串
您的第一条指令是push$0
,因此外壳代码的前两个字节是\x6A\x00
缓冲区的大小为1
(strlen
在空字节后停止)。
这就是为什么出现错误您的外壳代码小于30字节!
考虑此外壳代码,它与您的外壳代码相同,只是推送$1
以避免空字节:
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)
基本上,此外壳代码等待2秒(1纳秒)后退出。
int 0x80
是一个系统调用,取决于eax
值
您仍然有问题,此外壳代码的长度为20字节。
您只需在开头(或结尾)添加十一个NOP
(0x90
)即可满足需求
试试这个:
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
如果程序等待2秒并成功退出(代码为0),则执行外壳代码
如果有必要,我可以向您解释如何编写外壳代码,以获得runshell
程序的权限,这通常是此类练习的目标(显然,在这里测试“/bin/sh”
).我很好奇——您使用了什么命令来编译shellfile.c
?gcc-o shellfile-g-ggdb shellfile.c这将是您的下一个问题。shellfile
将是一个ELF文件,而不仅仅是一个x86指令流。您的意思是我必须从shellfile.c中提取操作码吗?在您修复fgets()之后
,请阅读:我认为他无法修改此代码,我想创建满足代码条件的外壳代码是一种练习。@Michael即使他设法将正确的字节码放入缓冲区,当他尝试执行时,此尝试也会出错。@moooeeep,是的,因为该文件不只包含字节码流。@moooeeepif(strlen(buffer2)>=40)
和if(strlen(buffer2)<30)
@moooeeep,警告,而不是通知。这些条件验证外壳代码。
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