通過逆向分析 SQL Server 登錄協議(TDS 封包),揭示其網絡傳輸加密與資料庫存儲雜湊算法的設計缺陷,證明兩者均屬極弱保護,極易被嗅探還原或離線破解。
核心解密彙編片段(0065C880):
mov cl, [edi]
mov dl, cl
xor cl, 5
xor dl, 0AFh
shr dl, 4
shl cl, 4
or dl, cl
mov [edi], dl
inc edi
dec eax
jnz short loc_65C880
對應 C 實現:
void sqlpasswd(char *enp, char *dnp) {
for (int i=0; i<128; i++) {
if (enp[i]==0) break;
unsigned char a1 = (enp[i] ^ 5) << 4;
unsigned char a2 = (enp[i] ^ 0xaf) >> 4;
dnp[i] = a1 | a2;
}
dnp[i]=dnp[i+1]=0;
}
算法無鹽、無迭代、線性可逆,與明文無異。0xA5 非分隔符,僅為 0x00 加密後產物。嵌入 Sniffer 即可實時解密登錄封包。
存儲格式(共 46 字節):
0x0100 (固定雙字節頭)
4 字節 HASH 加密 KEY (Salt)
20 字節 HASH1 (小寫密碼 + Salt 的 SHA-1)
20 字節 HASH2 (大寫密碼 + Salt 的 SHA-1)
生成流程(調用 CryptoAPI):
CryptAcquireContextW(&hProv, NULL, L"Microsoft Base Cryptographic Provider v1.0", 1, 0xf0000000);
CryptCreateHash(hProv, 0x8004, NULL, NULL, &hHash); // CALG_SHA1
CryptHashData(hHash, lower_passwd_buf + salt, 0x12, 0);
CryptGetHashParam(hHash, 2, &hash1, &len, 0); // HASH1
CryptHashData(hHash, upper_passwd_buf + salt, 0x12, 0);
CryptGetHashParam(hHash, 2, &hash2, &len, 0); // HASH2
最終存儲 = HASH1 || HASH2 (40 字節)
舊版 SQL Server 密碼機制在現代威脅模型下已完全失效,必須通過傳輸加密與版本升級從根本上消除風險。