简介
ExclIT项目是基于 HWSyscalls 的 DLL Shellcode 自注入器/运行器,理想情况下被认为是使用 rundll32 执行的。如果受害者端点有权访问攻击者控制的 SMB 共享,则可能授予无文件执行。
根据作者介绍,这个项目是一个DLL的shellcode注入的loader。
项目下载地址如下:
https://github.com/florylsk/ExecIT
使用方法如下:
这个项目生成是一个DLL文件,这里的HelpFunc是一个导出函数。
rundll32.exe ExecIT.dll, HelperFunc, <path_to_file>
我们紧接着来看一下源码。
代码解析
我们首先定位到DllMain函数这里,这几个判断就不说了,当这个Dll被加载的时候会去调用OutPutDebugStringA
这个函数来输出调试相关的信息。所以这里并没有我们想要的东西。
我们再来看一下它这条命令,这里通过rundll32去执行ExecIT.dll中的HelperFunc函数的,并将最后一个参数传递进去,也就是shellcode的路径。
所以我们定位到HelperFunc函数这里。这个函数遵守了rundll32的调用约定。rundll32的调用约定都是stdcall,这个函数传递了四个参数,这四个参数都是必需的,hwnd是窗口的句柄,hinst是DLL的实例句柄,lpszCmdLine是字符串的参数,nCmdShow是控制窗口显示的方式
接下来这里调用了InitHWSyscalls
函数,这个函数是用于获取到ntdll.dll的基址的,我们可以跟进去查看。
首先通过GetCurrentThread
函数来获取到当前线程的句柄,然后这里调用了一个自定义的GetModuleAddress
函数,将ntd
字符串传递进去。我们跟进GetModuleAddress
函数。
这个函数就是典型的使用PEB来获取ntdll.dll
模块的基址的。
获取到ntdll模块基址之后,调用FindRetGadget函数查找合适的垫片来实现特定的控制流,一般在实现ROP的时候会用到,这里我们不用管,紧接着注册了一个异常处理程序,1表示处理程序的优先级,数值越小,优先级越高。这里的异常处理函数是HWSyscallExceptionHandler
。
最后返回,如上的代码其实都是HWSyscalls中的。这里我们简单介绍一下就好。
紧接着定义了两个字符串,这两个字符串是翻转过的,我们会发现,这两个字符串其实就是NtReadFile
和NtProtectVirtualMemory
。
紧接着通过CreateFileA函数打开传递进来的文件,返回文件的句柄。
通过GetFileSize函数获取到该文件的大小。
这里定义了两个变量,分别是hThread和无效句柄。
因为上面对其字符串进行反转了,所以需要将其翻转回来。这里调用了一个reverStr函数对其字符串进行翻转。
reverseStr
函数如下:
翻转之后从yromeMlautriVetacollAtN
字符串转变为了NtAllocateVirtualMemory
。紧接着调用PrepareSyscall
函数,将其我们翻转之后的字符串传递进去。
这里其实就是Syscall的系统调用了,这里会通过PrepareSyscall获取到函数的地址之后来进行调用。
这里本质上调用了NtAllocateVirtualMemory
函数来申请内存。
这里申请了一块可读可写的内存,使用payload变量来接收。
紧接着翻转cNtReadFile
变量中的字符串,也就是eliFdaeRtN
,翻转过来其实就是NtReadFile
。
接着对其syscall系统调用该函数,将读进来的shellcode文件,读入到payload这块内存中。
然后再对其yromeMlautriVtcetorPtN
进行翻转,也就是NtProtectVirtualMemory
,修改其内存保护权限为可读可写可执行的权限。
这里执行shellcode使用的是回调函数执行的。EnumCalendarInfoEx
函数是一个枚举指定区域设置下的日历信息的,第一个参数其实就是回调函数的指针,这里指向的是payload。
最后注销异常处理程序。
如上其实就是整个项目的解析了,这里最需要我们学习的一点其实就是字符串翻转这里,可以有效的规避静态扫描。
那么我们其实是可以尝试对其进行更改的,我们可以将其我们的shellcode对其进行加密处理。
加密之后需在loader中,也就是导出函数中进行解密即可。
原文始发于微信公众号(Relay学安全):绕过某60及Defender项目解析
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论