☆ 对"V"的Hacking
http://scz.617.cn/windows/200401091624.txt
HKEY_LOCAL_MACHINE\SECURITY\SAM\Domains\Account\Users\000001F4 F REG_BINARY V REG_BINARY
这次我不犯傻了,在Petter Nordahl-Hagen的基础上([20])Hacking "V"结构,从头 造轮子不划算。用同样的程序以16进制方式转储数据如下:
0x000003EB
byteArray [ 548 bytes ] -> 00000000 00 00 00 00 D4 00 00 00-02 00 01 00 D4 00 00 00 ................ 00000010 08 00 00 00 00 00 00 00-DC 00 00 00 12 00 00 00 ................ 00000020 00 00 00 00 F0 00 00 00-16 00 00 00 00 00 00 00 ................ 00000030 08 01 00 00 00 00 00 00-00 00 00 00 08 01 00 00 ................ 00000040 00 00 00 00 00 00 00 00-08 01 00 00 00 00 00 00 ................ 00000050 00 00 00 00 08 01 00 00-00 00 00 00 00 00 00 00 ................ 00000060 08 01 00 00 00 00 00 00-00 00 00 00 08 01 00 00 ................ 00000070 00 00 00 00 00 00 00 00-08 01 00 00 00 00 00 00 ................ 00000080 00 00 00 00 08 01 00 00-15 00 00 00 A8 00 00 00 ................ 00000090 20 01 00 00 08 00 00 00-01 00 00 00 28 01 00 00 ...........(... 000000A0 14 00 00 00 00 00 00 00-3C 01 00 00 14 00 00 00 ........<....... 000000B0 00 00 00 00 50 01 00 00-04 00 00 00 00 00 00 00 ....P........... 000000C0 54 01 00 00 04 00 00 00-00 00 00 00 01 00 14 80 T............... 000000D0 B4 00 00 00 C4 00 00 00-14 00 00 00 44 00 00 00 ............D... 000000E0 02 00 30 00 02 00 00 00-02 C0 14 00 44 00 05 01 ..0.........D... 000000F0 01 01 00 00 00 00 00 01-00 00 00 00 02 C0 14 00 ................ 00000100 FF 07 0F 00 01 01 00 00-00 00 00 05 07 00 00 00 ................ 00000110 02 00 70 00 04 00 00 00-00 00 14 00 5B 03 02 00 ..p.........[... 00000120 01 01 00 00 00 00 00 01-00 00 00 00 00 00 18 00 ................ 00000130 FF 07 0F 00 01 02 00 00-00 00 00 05 20 00 00 00 ............ ... 00000140 20 02 00 00 00 00 18 00-FF 07 0F 00 01 02 00 00 ............... 00000150 00 00 00 05 20 00 00 00-24 02 00 00 00 00 24 00 .... ...$.....$. 00000160 44 00 02 00 01 05 00 00-00 00 00 05 15 00 00 00 D............... 00000170 92 E0 3C 77 35 8A 02 1A-43 17 0A 32 EB 03 00 00 ..<w5...C..2.... 00000180 01 02 00 00 00 00 00 05-20 00 00 00 20 02 00 00 ........ ... ... 00000190 01 02 00 00 00 00 00 05-20 00 00 00 20 02 00 00 ........ ... ... 000001A0 74 00 65 00 73 00 74 00-74 00 65 00 73 00 74 00 t.e.s.t.t.e.s.t. 000001B0 20 00 75 00 73 00 65 00-72 00 01 00 6F 00 6E 00 .u.s.e.r...o.n. 000001C0 6C 00 79 00 20 00 61 00-20 00 74 00 65 00 73 00 l.y. .a. .t.e.s. 000001D0 74 00 38 F0 FF FF FF FF-FF FF FF FF FF FF FF FF t.8............. 000001E0 FF FF FF FF FF FF FF FF-FF 93 38 F0 01 02 00 00 ..........8..... 000001F0 07 00 00 00 01 00 01 00-XX XX XX XX XX XX XX XX ................ 00000200 XX XX XX XX XX XX XX XX-01 00 01 00 XX XX XX XX ................ 00000210 XX XX XX XX XX XX XX XX-XX XX XX XX 01 00 01 00 ................ 00000220 01 00 01 00 ....
对"V"的Hacking首先参考1997年Jeremy Allison编写的pwdump.c([5]),结合[20]。 试着手工解码"V",以0x000003EB为例:
00 00 00 00 未知Offset,0x00000000/0,相对0x000000CC的偏移, 最终位置是0x000000CC D4 00 00 00 未知Length,0x000000D4/212 02 00 01 00 未知,不像是简单的对齐填充字段 D4 00 00 00 Username Offset,0x000000D4/212,相对0x000000CC 的偏移,最终位置是0x000001A0。换个角度来理解, 前面0xCC字节是固定的头结构,后面是数据区。 08 00 00 00 Username Length,Unicode串的字节数,靠长度标识 结尾,不依赖NUL字符,0x00000008/8,"test" 00 00 00 00 未知 DC 00 00 00 User full name Offset,0x000000DC/220,最终位 置是0x000001A8 12 00 00 00 User full name Length,Unicode串的字节数,靠长 度标识结尾,0x00000012/18,"test user" 00 00 00 00 未知 F0 00 00 00 User comment Offset,0x000000F0/240,最终位置 是0x000001BC 16 00 00 00 User comment Length,Unicode串的字节数,靠长度 标识结尾,0x00000016/22,"only a test" 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 00 00 00 00 未知Length,0字节 00 00 00 00 未知 08 01 00 00 未知Offset,0x00000108,最终位置是0x000001D4 15 00 00 00 未知Length,0x00000015/21,本例中是21个0xFF A8 00 00 00 未知,为何此次不为0了 20 01 00 00 0x00000120/288,最终位置是0x000001EC 08 00 00 00 0x00000008/8 01 00 00 00 未知 28 01 00 00 加密存放的LM Hash,0x00000128/296,最终位置是 0x000001F4 14 00 00 00 0x00000014/20 00 00 00 00 未知 3C 01 00 00 加密存放的NTLM Hash,0x0000013C/316,最终位置 是0x00000208 14 00 00 00 0x00000014/20 00 00 00 00 未知 50 01 00 00 0x00000150/336,最终位置是0x0000021C 04 00 00 00 0x00000004/4 00 00 00 00 未知 54 01 00 00 0x00000154/340,最终位置是0x00000220 04 00 00 00 0x00000004/4 00 00 00 00 未知
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 前面总共0xCC字节的固定头结构,后面是变长数据区,靠头结构定位各字段。头结构 简单点讲,就是17组Offset/Length,每组占12字节。 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01 00 14 80 B4 00 00 00 212字节未知数据,其实我对这块数据很好奇,可惜 C4 00 00 00 14 00 00 00 完全看不出明堂来。不同帐号,该块数据长度不同。 44 00 00 00 02 00 30 00 02 00 00 00 02 C0 14 00 44 00 05 01 01 01 00 00 00 00 00 01 00 00 00 00 02 C0 14 00 FF 07 0F 00 01 01 00 00 00 00 00 05 07 00 00 00 02 00 70 00 04 00 00 00 00 00 14 00 5B 03 02 00 01 01 00 00 00 00 00 01 00 00 00 00 00 00 18 00 FF 07 0F 00 01 02 00 00 00 00 00 05 20 00 00 00 20 02 00 00 00 00 18 00 FF 07 0F 00 01 02 00 00 00 00 00 05 20 00 00 00 24 02 00 00 00 00 24 00 44 00 02 00 01 05 00 00 00 00 00 05 15 00 00 00 92 E0 3C 77 35 8A 02 1A 43 17 0A 32 EB 03 00 00 01 02 00 00 00 00 00 05 20 00 00 00 20 02 00 00 01 02 00 00 00 00 00 05 20 00 00 00 20 02 00 00 74 00 65 00 73 00 74 00 Unicode串"test",靠长度标识结尾,不依赖NUL字符 Username 74 00 65 00 73 00 74 00 Unicode串"test user" User full name 20 00 75 00 73 00 65 00 72 00 01 00 这两个字节是填充字节,为了确保后面的数据对齐在 四字节边界上 6F 00 6E 00 6C 00 79 00 Unicode串"only a test" User comment 20 00 61 00 20 00 74 00 65 00 73 00 74 00 38 F0 这两个字节是填充字节,为了确保后面的数据对齐在 四字节边界上 FF FF FF FF FF FF FF FF 21字节 FF FF FF FF FF FF FF FF FF FF FF FF FF 93 38 F0 这三个字节是填充字节,为了确保后面的数据对齐在 四字节边界上 01 02 00 00 07 00 00 00 8字节,不知是何数据 01 00 01 00 20字节,前面这4字节不清楚是何含义 XX XX XX XX XX XX XX XX 加密存放的LM Hash XX XX XX XX XX XX XX XX 01 00 01 00 20字节,前面这4字节不清楚是何含义 XX XX XX XX XX XX XX XX 加密存放的NTLM Hash XX XX XX XX XX XX XX XX 01 00 01 00 4字节 01 00 01 00 4字节
注意到Ethereal、Jeremy Allison、Petter Nordahl-Hagen多解析出几个字段,比如 Home、Script、Profile,但在我的测试环境中始终没有看到这几个字段出现过实际 数据,因此宁可将之视为Unknown_XXX。若是某天看到实际数据了,再回头修正也不 迟。反正我是不相信Kickoff Time这种以讹传讹还被引了无数次的字段,难说"V"中 情形不类似。
为了写程序方便,Hacking一个C风格的结构出来:
#pragma pack( push, 1 )
typedef struct _OFFSET_LENGTH { DWORD Offset; // +0x000 // 偏移是相对于头结构尾部、变长数据区首部的 DWORD Length; // +0x004 // 以字节为单位 DWORD Unknown_008; // +0x008 // 不像是简单的对齐填充字段 // +0x00c } OFFSET_LENGTH, *POFFSET_LENGTH, **PPOFFSET_LENGTH;
/*
- 自己Hacking得到的结构,不可靠。注意,起名SAM_RID_V_VALUE,对应
- HKEY_LOCAL_MACHINE\SECURITY\SAM\Domains\Account\Users\000001F4
- 以区别如下位置的"F"、"V"
- HKEY_LOCAL_MACHINE\SECURITY\SAM\Domains\Account
- 头结构简单点讲,就是17组Offset/Length,每组占12字节。 */ typedef struct _SAM_RID_V_VALUE { OFFSET_LENGTH Unknown_000; // +0x000 OFFSET_LENGTH Username; // +0x00c OFFSET_LENGTH Userfullname; // +0x018 OFFSET_LENGTH Usercomment; // +0x024 OFFSET_LENGTH Unknown_030; // +0x030 OFFSET_LENGTH Unknown_03C; // +0x03c OFFSET_LENGTH Unknown_048; // +0x048 OFFSET_LENGTH Unknown_054; // +0x054 OFFSET_LENGTH Unknown_060; // +0x060 OFFSET_LENGTH Unknown_06C; // +0x06c OFFSET_LENGTH Unknown_078; // +0x078 OFFSET_LENGTH Unknown_084; // +0x084 OFFSET_LENGTH Unknown_090; // +0x090 OFFSET_LENGTH EncryptedLMHash; // +0x09c OFFSET_LENGTH EncryptedNTLMHash; // +0x0a8 OFFSET_LENGTH Unknown_0B4; // +0x0b4 OFFSET_LENGTH Unknown_0C0; // +0x0c0 // +0x0cc } SAM_RID_V_VALUE, *PSAM_RID_V_VALUE, **PPSAM_RID_V_VALUE;
看样子NetUserGetInfo()获取的信息分别源自"F"、"V"。折腾了一趟,原来不明白的 还是不明白,别人没搞出来的,我照样没搞出来,不爽。暂且不管这里了,好歹跟着 Jeremy Allison的脚步完整捋了一遍"F"、"V",下次有谁搓我,就没那么容易了。
SampRetrieveUserPasswords()中调用SampGetUnicodeStringAttribute()获取加密后 的LM Hash、NTLM Hash,SampGetUnicodeStringAttribute()的第二形参是个索引, 分别取值0x0D、0x0E,对照上述SAM_RID_V_VALUE结构,就会发现这两个索引的意义。
☆ 参考资源
嘿嘿,那些个写"原创"的伙计们,千万别被我看到你的原创,最主要的是你得保证你 参考的东西不会被我用Google搜到,要不你就老实交待了参考资源。我没别的长处, 除了能把别人十八代祖宗的历史信息从Google中翻出来,//Grin
[ 5] http://us1.samba.org/samba/ftp/pwdump/pwdump.c - Jeremy Allison[1997]
[20] Offline NT Password & Registry Editor - Petter Nordahl-Hagen http://home.eunet.no/~pnordahl/ntpasswd/