破解pcap文件的NTLMv2 hash以得到密码明文

首先你要有一个pcap文件且含有NTLM v2哈希

1.ntlmssp过滤

2.为了破解ntlmv2,我们需要找到如下信息

username::domain:ServerChallenge:NTproofstring:modifiedntlmv2response 

3.找到NTLMSSP_AUTH包,并过滤到下图内容

可获得

username和domain

4.追踪NTLM response

 可获得NTproofstring和modifiedntlmv2response 

此处注意ntlmv2response的开头是NTproofstring,需要删除ntlmv2response里的重复部分

5.过滤搜索ntlmssp.ntlmserverchallenge,找到符合条件的包

获得NTLM Server Challenge

自此,获得了username::domain:ServerChallenge:NTproofstring:modifiedntlmv2response 的所有信息

6.将该字符串保存后使用hashcat破解

hashcat -m 5600 保存的字符串.txt 密码字典.txt -o 结果.txt --force

hashcat具体操作可参考https://blog.csdn.net/SHIGUANGTUJING/article/details/90074614

7.利用python自动提取pcap包中的ntlmv2 hash

可参考https://github.com/gh-balthazarbratt/nocashvalue

#!/usr/bin/python3

import os, sys, subprocess, json, logging, argparse
from uuid import uuid4

parser = argparse.ArgumentParser(description='Extracts NTLMv2 tokens from pcaps 
and creates files ready to be consumed by hashcat')
parser.add_argument('--tshark_path', 
                    type=str, 
                    help='full path to tshark executable', 
                    required=True)
parser.add_argument('--pcap_file', 
                    type=str, 
                    help='full path to pcap file', 
                    required=True)

args = parser.parse_args()
tshark_path = args.tshark_path
pcap_file = args.pcap_file

# Change the value below based on your system paths, it is set for *nix type systems
tmp = '/tmp'
# Set temporary directory and log file names
scr_dir = 'nocashvalue_ntlmv2-' + uuid4().__str__()[:8]
tmp_scr_dir = tmp + '/' + scr_dir
log_file = 'nocashvalue.log'

# Create script tmp directory
os.mkdir(tmp_scr_dir)

# Setup logger
logger = logging.getLogger('nocashvalue')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler(tmp_scr_dir+'/'+log_file)
fh.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(fh)

logger.info('Logger initialized')

challenge_filter_str = "'ntlmssp.identifier == NTLMSSP and ntlmssp.messagetype == 0x00000002'"
blob_filter_str = "'ntlmssp.identifier == NTLMSSP and ntlmssp.messagetype == 0x00000003'"

challenge_str_cmd = "{} -r {} -Y{} -Tjson -e ntlmssp.auth.username 
-e ntlmssp.auth.domain -e ntlmssp.ntlmserverchallenge -e ntlmssp.ntlmv2_response.ntproofstr 
-e ntlmssp.ntlmv2_response".format(tshark_path, pcap_file, challenge_filter_str)

blob_str_cmd = "{} -r {} -Y{} -Tjson -e ntlmssp.auth.username -e ntlmssp.auth.domain 
-e ntlmssp.ntlmserverchallenge -e ntlmssp.ntlmv2_response.ntproofstr 
-e ntlmssp.ntlmv2_response".format(tshark_path, pcap_file, blob_filter_str)

logger.info('Executing "{}" in a subprocess shell'.format(challenge_str_cmd))
pipe1 = subprocess.Popen(challenge_str_cmd, stdout=subprocess.PIPE, shell=True)
logger.info('Child process pid is {} and it exited with {}'.format(pipe1.pid, pipe1.returncode))

logger.info('Executing "{}" in a subprocess shell'.format(blob_str_cmd))
pipe2 = subprocess.Popen(blob_str_cmd, stdout=subprocess.PIPE, shell=True)
logger.info('Child process pid is {} and it exited with {}'.format(pipe2.pid, pipe2.returncode))

challenge_str_output = pipe1.stdout.read()
blob_str_output = pipe2.stdout.read()

# This is a list of dictionaries
challenge_str_json = json.loads(challenge_str_output.decode('UTF-8'))
logger.info(json.dumps(challenge_str_json, indent=2))

blob_str_json = json.loads(blob_str_output.decode('UTF-8'))
logger.info(json.dumps(blob_str_json, indent=2))

# Log the fact that the number of server challenge packets 
# are different than the number of ntlmv2_response packets and exit
if (len(challenge_str_json) != len(blob_str_json)): 
    sys.stdout.write('Number of SMB2 packets containing NTLM Server Challenge tokens 
are different than the number of packets containing NTLMv2 responses. See {} 
for details.'.format(tmp_scr_dir+'/'+log_file))
    exit()

packets = []

# Merge server challenge tokens with the rest of the ntlmv2_response details
# Caveat: We assume that the packets are received in chronological order such that
# the packet which contains server_challenge token appears right before the packet 
# that contains NTLMv2_response it is associated with
for i, blob_pkt in enumerate(blob_str_json):
    username, domain, server_challenge, ntproofstr, ntlmv2_response = ['', '', '', '', '']
    if (len(blob_pkt['_source']['layers']) > 0 and 
        'ntlmssp.auth.username' in blob_pkt['_source']['layers']):
        username = blob_pkt['_source']['layers']['ntlmssp.auth.username'][0]
    if (len(blob_pkt['_source']['layers']) > 0 
        and 'ntlmssp.auth.domain' in blob_pkt['_source']['layers']):
        domain = blob_pkt['_source']['layers']['ntlmssp.auth.domain'][0]
    if (len(challenge_str_json[i]['_source']['layers']) > 0 
        and 'ntlmssp.ntlmserverchallenge' in challenge_str_json[i]['_source']['layers']):
        server_challenge = challenge_str_json[i]['_source']['layers']['ntlmssp.ntlmserverchallenge'][0]
    if (len(blob_pkt['_source']['layers']) > 0 
        and 'ntlmssp.ntlmv2_response.ntproofstr' in blob_pkt['_source']['layers']):
        ntproofstr = blob_pkt['_source']['layers']['ntlmssp.ntlmv2_response.ntproofstr'][0]
    if (len(blob_pkt['_source']['layers']) > 0 
        and 'ntlmssp.ntlmv2_response' in blob_pkt['_source']['layers']):
        ntlmv2_response = blob_pkt['_source']['layers']['ntlmssp.ntlmv2_response'][0]
        if len(ntlmv2_response) > 0:
            ntlmv2_response = ntlmv2_response[31:]
    packets.insert(i, {'username': username, 
                       'domain': domain, 
                       'server_challenge': server_challenge, 
                       'ntproofstr': ntproofstr, 
                       'ntlmv2_response': ntlmv2_response})

# Hashcat NTLMv2 file format
# username::domain:ServerChallenge:NTproofstring:modifiedntlmv2response
for packet in packets:
    file_name = (tmp_scr_dir 
                    + '/' + packet['username'] + '_' + packet['domain'] 
                    + '-' + uuid4().__str__()[:8] + '.txt')
    with open(file_name, 'w', encoding="UTF-8") as file:
        blob = packet['username'] + '::' + packet['domain'] + ':' + packet['server_challenge'] 
        blob += ':' + packet['ntproofstr'] + ':' + packet['ntlmv2_response']
        file.write(blob)

sys.stdout.write('{} files created. See {} for details.'.format(len(packets),tmp_scr_dir))
./main.py --tshark_path /usr/bin/tshark --pcap_file /home/桌面/1.pcap

 

原文地址:https://www.cnblogs.com/FrozenW/p/15449379.html