☆ SamrQueryInformationUser(36) level 21查询的响应报文解码 queryuser.c用Win32 API NetUserGetInfo()查询USER_INFO_3信息,其主要用户信息 来自SamrQueryInformationUser(36) level 21查询,当然还有其它SMB查询报文,这 次不关心它们,忽略之。 Ethereal 0.10.0对SamrQueryInformationUser(36) level 21查询的响应报文解码如 下: -------------------------------------------------------------------------- Microsoft Security Account Manager Operation: SamrQueryInformationUser (36) USER_INFO: USER_INFO pointer Referent ID: 0x000b1420 USER_INFO: Guest Level: 21 USER_INFO_21: Guest Logon Time: Oct 29, 2003 10:07:46.874532699 Logoff Time: No time specified (0) Kickoff Time: Oct 29, 2003 09:58:41.750682830 PWD Last Set: No time specified (0) PWD Can Change: Oct 29, 2003 09:58:41.750682830 PWD Must Change: Infinity (absolute time) Account Name: Guest Full Name Home Home Drive Script Profile Account Desc: Built-in account for guest access to the computer/domain Workstations Comment Parameters Unknown string Unknown string Unknown string BUFFER: Rid: 501 Group: 513 Acct Ctrl: 0x00000215 .... .... .... .... .... .0.. .... .... = : This account has NOT been auto locked .... .... .... .... .... ..1. .... .... = : Passwords does NOT expire .... .... .... .... .... ...0 .... .... = : This is NOT a server trust account .... .... .... .... .... .... 0... .... = : This is NOT a workstation trust account .... .... .... .... .... .... .0.. .... = : This is NOT a domain trust account .... .... .... .... .... .... ..0. .... = : This is NOT a mns account .... .... .... .... .... .... ...1 .... = : This is a NORMAL USER account .... .... .... .... .... .... .... 0... = : This is NOT a temporary duplicate account .... .... .... .... .... .... .... .1.. = : Password is NOT required .... .... .... .... .... .... .... ..0. = : Homedir is NOT required .... .... .... .... .... .... .... ...1 = : Account is DISABLED Unknown long: 0x00ffffff LOGON_HOURS: Bad Pwd Count: 0 Logon Count: 0 Country: Default (0) Codepage: 0 NT Pwd Set: 0x00 LM Pwd Set: 0x00 Expired flag: 0x00 Unknown char: 0x00 Return code: STATUS_SUCCESS (0x00000000) 0090 20 14 0b 00 15 00 dd db 70 36 ...... .......p6 00a0 52 72 c1 9d c3 01 00 00 00 00 00 00 00 00 10 ea Rr.............. 00b0 66 2d c0 9d c3 01 00 00 00 00 00 00 00 00 10 ea f-.............. 00c0 66 2d c0 9d c3 01 ff ff ff ff ff ff ff 7f 0a 00 f-.............. 00d0 0a 00 f8 b2 0a 00 00 00 00 00 f0 92 0a 00 00 00 ................ 00e0 00 00 b8 b6 0b 00 00 00 00 00 70 4e 0b 00 00 00 ..........pN.... 00f0 00 00 48 fc 09 00 00 00 00 00 10 b1 0a 00 70 00 ..H...........p. 0100 70 00 d0 09 0b 00 00 00 00 00 40 b8 0b 00 00 00 p.........@..... 0110 00 00 e0 b7 0b 00 00 00 00 00 c8 b6 0b 00 00 00 ................ 0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f5 01 ................ 0140 00 00 01 02 00 00 15 02 00 00 ff ff ff 00 a8 00 ................ 0150 00 00 d8 a7 0a 00 00 00 00 00 00 00 00 00 00 00 ................ 0160 00 00 05 00 00 00 00 00 00 00 05 00 00 00 47 00 ..............G. 0170 75 00 65 00 73 00 74 00 69 00 00 00 00 00 00 00 u.e.s.t.i....... 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01b0 00 00 00 00 00 00 38 00 00 00 00 00 00 00 38 00 ......8.......8. 01c0 00 00 42 00 75 00 69 00 6c 00 74 00 2d 00 69 00 ..B.u.i.l.t.-.i. 01d0 6e 00 20 00 61 00 63 00 63 00 6f 00 75 00 6e 00 n. .a.c.c.o.u.n. 01e0 74 00 20 00 66 00 6f 00 72 00 20 00 67 00 75 00 t. .f.o.r. .g.u. 01f0 65 00 73 00 74 00 20 00 61 00 63 00 63 00 65 00 e.s.t. .a.c.c.e. 0200 73 00 73 00 20 00 74 00 6f 00 20 00 74 00 68 00 s.s. .t.o. .t.h. 0210 65 00 20 00 63 00 6f 00 6d 00 70 00 75 00 74 00 e. .c.o.m.p.u.t. 0220 65 00 72 00 2f 00 64 00 6f 00 6d 00 61 00 69 00 e.r./.d.o.m.a.i. 0230 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 n............... 0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0250 00 00 00 00 00 00 ec 04 00 00 00 00 00 00 15 00 ................ 0260 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 0270 ff ff ff ff ff ff ff ff ff ff 00 00 00 00 .............. -------------------------------------------------------------------------- 观察上述报文解码,对比USER_INFO_3结构,发现usri3_password_age在SMB报文中没 有直接对应项。为了获取如下信息: Last logon time Password last set time Password can change time Password must change time queryuser.c必须结合不同结构的不同成员进行计算: usri3_last_logon tod_elapsedt usri3_password_age usrmod0_min_passwd_age usrmod0_max_passwd_age 但事实上相关信息已经包含在单个SMB报文中。实现Win32 API NetUserGetInfo()的 人不知出于什么原因,未将上述信息直接反映到USER_INFO_3结构中,绕了一个大弯 后提供usri3_password_age成员,为了计算得到usri3_password_age成员,还得调用 NetRemoteTOD(),这不是吃撑了吗。写net user命令的人跟实现NetUserGetInfo()的 人肯定不是一伙的,前者当时想必也极度郁闷,费了手脚才得到本该直接得到的信息。 rpcclient显然意识到level 21响应报文携带足够多的信息,未走NetUserGetInfo()、 NetRemoteTOD()、NetUserModalsGet()的老路。这与最初的猜测不同。 usri3_priv不在level 21响应报文中,需要用其它SMB查询报文获取相应信息。 Acct Ctrl不直接对应usri3_flags,我们所关心的有对应关系的bit如下: 0x00000001 (account is disabled) UF_ACCOUNTDISABLE 0x00000004 (no password is required) UF_PASSWD_NOTREQD 0x00000200 (password never expire) UF_DONT_EXPIRE_PASSWD 0x00020000 (must change password) UF_PASSWORD_EXPIRED 0x00020000是自己Hacking的结果,Ethereal 0.10.0并未解析该bit。 UF_PASSWD_CANT_CHANGE已经确定不包含在Acct Ctrl中。 UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED是否包含在Acct Ctrl中,我不清楚。 Samba、Ethereal解析level 21响应报文时对各个时间处理如下: Logon Time Logoff Time Kickoff Time PWD Last Set PWD Can Change PWD Must Change 据观察,Logoff Time无意义,usri3_last_logoff也无意义,总为0。Kickoff Time 应为PWD Last Set,而原PWD Last Set应为什么我不清楚,总为0。注意level 21响 应报文中0x0000000000000000、0x7FFFFFFFFFFFFFFF的特殊含义。 这些时间是以100纳秒(ns)为单位的FILETIME,将RtlTime、FILETIME之间的转换公式 做点变换,方便计算: ( RtlTime + 11644473600 ) * 10000000 -> FILETIME ( RtlTime + 0x00000002B6109100 ) * 0x0000000000989680 -> FILETIME FILETIME / 0x0000000000989680 - 0x00000002B6109100 -> RtlTime Logon Count、usri3_num_logons对应成功登录次数,包括本机登录、通过终端服务 登录等等,但不包含net use成功次数。如果发现一些被禁帐号的成功登录次数有变 化,这是危险信号。 直接用SMB报文查询用户信息时,发现一件有意思的事。主机A是一台做了某种程度安 全加固的Windows 2000,queryuser.c调用NetUserGetInfo()查询主机A上的用户信息, 如果是空会话,将得到如下错误信息: NetUserGetInfo() failed: the user does not have access to the requested information 抓包发现SamrOpenDomain(7)试图打开"S-1-5-32"(参winnt.h,Built-in domain)时 权限否定: -------------------------------------------------------------------------- Microsoft Security Account Manager Operation: SamrOpenDomain (7) Policy Handle Context Handle: 00000000000000000000000000000000... Return code: STATUS_ACCESS_DENIED (0xc0000022) -------------------------------------------------------------------------- 同时注意到SamrOpenDomain(7)打开主机SID成功!为了进行level 21查询,这已经是 充分条件了。就是说,直接用SMB报文查询主机A上的用户信息,空会话足够了。尽管 A做了某种程度的安全加固,却只对用Win32 API的客户端有效,服务端的安全性依赖 客户端的实现,可真够讽刺的,不过这不是第一次,也不是最后一次。 写完SMB查询代码后,针对主机A进行查询,居然得到正确返回值,对比queryuser.c 的Win32 API查询效果,发现了这个猫腻。意识到这点,再用rpcclient进一步确认: -------------------------------------------------------------------------- > ./rpcclient -U "" -N rpcclient $> queryuser User Name : scz Logon Time : Password last set Time : Password can change Time : Password must change Time : user_rid : group_rid : rpcclient $> --------------------------------------------------------------------------