• 破解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

     

  • 相关阅读:
    C#前端画表
    JavaScript中遍历获取Json中属性值
    【数据库】Redis(5)--Redis发布订阅
    【java框架】SpringBoot(9) -- Springboot中如何优雅的进行字段校验
    【开发工具】-- IDEA集成Git在实际项目中的运用
    【Java代码之美】 -- Java必会的工具库,减少代码量的利器
    【java框架】SpringMVC(4) -- JSON相关的数据返回
    聊聊基于jdk实现的spi如何与spring整合实现依赖注入
    聊聊springcloud项目同时存在多个注册中心客户端采坑记
    feign请求返回值反序列LocalDateTime异常记录
  • 原文地址:https://www.cnblogs.com/FrozenW/p/15449379.html
Copyright © 2020-2023  润新知