☆ SamrQueryInformationDomain level 1查询的响应报文解码 Ethereal 0.10.0无法正确解析Max Pwd Age、Min Pwd Age,因为他们不清楚其中的 运算法则。 -------------------------------------------------------------------------- Microsoft Security Account Manager Operation: SamrQueryInformationDomain (8) DOMAIN_INFO pointer Referent ID: 0x00138ed0 DOMAIN_INFO: Level: 1 DOMAIN_INFO_1: Min Pwd Len: 7 Pwd History Len: 1 Unknown long: 0x00000001 Max Pwd Age: Time can't be converted Min Pwd Age: Time can't be converted Return code: STATUS_SUCCESS (0x00000000) 0080 d0 8e 13 00 01 00 ..$............. 0090 00 00 07 00 01 00 01 00 00 00 00 00 a5 2d 8e 72 .............-.r 00a0 ff ff 00 80 9b 07 6d e8 ff ff 00 00 00 00 ......m....... Max Pwd Age : 0xFFFF728E2DA50000 Min Pwd Age : 0xFFFFE86D079B8000 -------------------------------------------------------------------------- 为了搞清楚上述64-bit的值如何对应到组策略中的天数,有很多条路可走,可以逆向 Windows的代码,可以查看rpcclient的源代码,rpcclient的queryuser命令显然正确 理解了上述64-bit值。不过,还是想自己判断一下这个运算法则。 这个64-bit值可能对应RtlTime、FILETIME或者其它什么稀奇古怪值。从queryuser.c 得到的调试信息是: -------------------------------------------------------------------------- usrmod0_min_passwd_age : 0x00278D00 usrmod0_max_passwd_age : 0x00ED4E00 -------------------------------------------------------------------------- 我套了如下计算公式: ( RtlTime + 11644473600 ) * 10000000 -> FILETIME 怎么也无法将usrmod0_max_passwd_age与Max Pwd Age联系起来。后来想了想,管它 是什么值,为了表示1天、2天、3天,这个值应该呈等差数列变化。于是从1天开始, 不断在组策略中递增"密码最长存留期",再抓包求差,果然如此: -------------------------------------------------------------------------- 0x0000000000000000 0天 0xFFFFFF36D5964000 1天 0xC92A69C000 0xFFFFFE6DAB2C8000 2天 0xC92A69C000 0xFFFFFDA480C2C000 3天 0xC92A69C000 0xFFFFDFC835104000 41天 0xFFFFDEFF0AA68000 42天 0xC92A69C000 0xFFFFDE35E03CC000 43天 0xC92A69C000 0xFFFFDD6CB5D30000 44天 0xC92A69C000 0xFFFFBA10413C4000 89天 0xFFFFB94716D28000 90天 0xC92A69C000 10000000 * 24 * 3600 == 0xC92A69C000 -------------------------------------------------------------------------- 公差是0xC92A69C000,除以24、除以3600,立刻就明白其中的运算法则了。64-bit值 以100纳秒(ns)为单位,以0xC92A69C000为公差递减(按无符号数理解的话)。 那个0天是我后来加上去的。乍看0xFFFFFF36D5964000没什么特殊的,不理解MS为何 选这个初值,从等差数列的角度一考虑,加上公差,上溢成0,哈,原来如此。 将64-bit值转换成天数的计算公式是: ( 0xFFFFFF36D5964000 - <64-bit value> ) / 0xC92A69C000 + 1 == 天数 现在回头看示例报文中的两个值: Max Pwd Age : 0xFFFF728E2DA50000 180天 Min Pwd Age : 0xFFFFE86D079B8000 30天 我给Gerald Combs 报告了这个修正,不知下一版会否修正进 去。其实还有N多更重要的SMB、DCE/RPC协议解码修正,不过实在写不好英文,加上 懒惰,故未报告过去。要是没有工作压力,像老外那样为了兴趣而折腾,我倒是很想 掺和到Ethereal解码开发中去,很佩服这帮人,还有Samba Team的人,都是大公无私 的典范。人生追求各不相同,我该好好学学他们的。sigh