Dll注入的一些手段

Dll注入的一些手段

Created
Nov 1, 2021 02:19 AM
Tags

0x01 普通Dll注入

DLL注入就是将dll文件放到某个正在运行的进程中,并且让这个进程调用LoadLibrary进行加载dll
注入流程:
  1. attach到某个进程
  1. 在进程中开辟一段空间
  1. 写入Dll文件路径
  1. 获取LoadLibrary函数地址
  1. 调用CreateRemoteThread来远程调用LoadLibrary去加载Dll
 

0x02 反射Dll注入

反射注入不需要Dll文件落地,可以避免一些静态查杀工具。主要技术是ReflectiveLoader
来实现Dll自己将自己装载到内存中,可以避免调用LoadLibrary函数。
 
注入流程:
  1. attach到某个进程
  1. 为Dll分配存储空间,并将Dll的内容拷贝到此空间
  1. 通过执行CreateRemoteThread或其他shellcode开控制进行执行到Dll的ReflectiveLoader函数
  1. ReflectiveLoader执行结束后会跳转到Dllmain
 
 

0x03 Shellcode反射Dll注入

它和反射Dll注入的区别在于反射加载函数并没有在Dll内部实现,而是利用在Dll头部前面添加了一段代码,实现了反射加载函数
注入流程:
  1. attach到某个进程
  1. 为Dll分配存储空间,并将Dll的内容拷贝到此空间
  1. Dll入口点函数名称和参数的散列赋值到原Dll的空间中
  1. 生成Shellcode放置原Dll之前,且该Shellcode中带有步骤三的值以及修改版的ReflectiveLoader
  1. 从Shellcode起始端开始执行即可
 
 
sRDI工具:
 

sRDI分析

该工具是生成用来sRDI操作的dll文件。
功能由两部分组成,一个是实现反射加载的shellcode,另一个是结合Dll来生成SRDI bin文件的代码,包括了引导shellcode、sRDI、用户数据、DLL。
 
项目结构:
├── DotNet
│   ├── App.config
│   ├── DotNet.csproj
│   ├── Program.cs
│   └── Properties
│       └── AssemblyInfo.cs
├── LICENSE
├── Native
│   ├── Loader.cpp
│   ├── Native.vcxproj
│   ├── Native.vcxproj.filters
│   ├── stdafx.cpp
│   ├── stdafx.h
│   └── targetver.h
├── PowerShell
│   ├── ConvertTo-Shellcode.ps1
│   └── Invoke-Shellcode.ps1
├── Python
│   ├── ConvertToShellcode.py
│   ├── Python.pyproj
│   ├── ShellcodeRDI.py
│   ├── ShellcodeRDI.pyc
│   └── __pycache__
│       └── ShellcodeRDI.cpython-39.pyc
├── README.md
├── ShellcodeRDI
│   ├── GetProcAddressWithHash.h
│   ├── ShellcodeRDI.c
│   ├── ShellcodeRDI.vcxproj
│   ├── ShellcodeRDI.vcxproj.filters
│   └── function_link_order.txt
├── ShellcodeRDI.sln
├── TestDLL
│   ├── Resource.rc
│   ├── TestDLL.vcxproj
│   ├── TestDLL.vcxproj.filters
│   ├── dllmain.cpp
│   └── resource.h
├── bin
├── lib
│   ├── PowerShell
│   │   ├── Get-FunctionHash.ps1
│   │   ├── Get-LibSymbols.ps1
│   │   ├── Get-ObjDump.format.ps1xml
│   │   ├── Get-PEHeader.ps1
│   │   └── Out-Shellcode.ps1
│   └── Python
│       ├── EncodeBlobs.py
│       └── FunctionToHash.py
 

Native

由C语言编写,关键文件是Loader.c
 
Main函数流程:
  1. 获取命令行参数指定的bin文件或者Dll文件
  1. 若参数指定的是Dll文件,则调用ConvertToShellcode函数将其转变成sRDIshellcode代码
  1. 若参数指定的Bin文件,不做处理,当做shellcode的代码进行后续的操作
  1. 调用VirtualProtect函数申请shellcode的存储空间
  1. shellcode的起始端开始执行
notion image
 
关键函数ConvertToShellcode中实现的是将Dll文件转成Shellcode,先识别Dll的位数,根据不同的位数来拼接不同的shellcode,其中rdiShellcode是已经编译好的汇编字节码,直接拼接即可。
 

Python

ConvertToShellcode.py 是处理命令参数,可以通过命令行参数指定Dllmain函数执行之后执行哪个函数、添加其他的数据、是否擦除PE文件头的信息、导入表的处理、指定导入时间等。
notion image
 
其中ConvertToShellcode函数和C语言实现的功能都是一样的。
 

DotNet

C#实现Native,关键文件是Program.cs
用法:
DotNetLoader.exe TestDLL_x64.dll
 

Powershell

利用Powershell来实现将Dll转换成shellcode和在内存中加载shellcode
实现方式和上面的都一样
Import-Module .\Invoke-Shellcode.ps1
Import-Module .\ConvertTo-Shellcode.ps1
Invoke-Shellcode -Shellcode (ConvertTo-Shellcode -File TestDLL_x64.dll)
 

Python\EncodeBlobs.py

用于批量修改上面各个项目中的RDIshellcode部分的代码

Python\FunctionToHash.py

指定Dll名和函数名,计算出一个哈希值
 

ShellcodeRDI

关键代码在ShellcodeRDI.c中的LoadDLL函数
实现步骤:
  1. 准备特殊变量声明和赋初值,比如函数名字符串、PE data、函数指针
  1. 获取LoadlibraryGetProcAddress的函数地址
  1. 调用了VirtualAlloc分配内存,并且把Dll的PE header拷贝到该内存中
  1. 拷贝各个sections到内存中
  1. 处理重定位
  1. 处理导入表
  1. 设置各个section的页面属性
  1. 执行TLS回调函数
  1. 执行参数指定的函数
  1. 执行导出函数
  1. 返回该Dll装载的基地址
 
 

参考