😼

Windowsにpipでimpacketをインストールしようとしたらエラーが出た

に公開

やり方

impacket\dpapi.pyDumpNTLMInfo.pyにAV/EDR除外設定をしてからpip install impacket

経緯

pip installしたらエラーが出た。Windows Defenderが脅威をブロック/削除したようです。

Building wheels for collected packages: impacket, dsinternals
  Building wheel for impacket (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for impacket (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [15 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build\lib
      creating build\lib\impacket
      copying impacket\cdp.py -> build\lib\impacket
      copying impacket\crypto.py -> build\lib\impacket
      copying impacket\dhcp.py -> build\lib\impacket
      copying impacket\dns.py -> build\lib\impacket
      copying impacket\dot11.py -> build\lib\impacket
      copying impacket\Dot11Crypto.py -> build\lib\impacket
      copying impacket\Dot11KeyManager.py -> build\lib\impacket
      copying impacket\dpapi.py -> build\lib\impacket
      error: could not open 'impacket\dpapi.py': Invalid argument
      [end of output]
Successfully built impacket
Installing collected packages: pycryptodomex, ldap3, dsinternals, dnspython, charset-normalizer, ldapdomaindump, cryptography, pyOpenSSL, impacket
  Attempting uninstall: cryptography
    Found existing installation: cryptography 3.3.2
    Uninstalling cryptography-3.3.2:
      Successfully uninstalled cryptography-3.3.2
ERROR: Could not install packages due to an OSError: [Errno 22] Invalid argument: 'c:\\users\\pachirisu\\appdata\\local\\programs\\python\\python39\\Scripts\\DumpNTLMInfo.py'

除外設定 1

impacket\dpapi.pyはフォルダ名が毎回変わるのでTempごと除外
C:\Users\Pachirisu\AppData\Local\Temp
インストール作業が終わったらこの除外設定は不要なので必ず設定削除しましょう。
Windows Defenderの除外設定はこちら
会社環境の場合はセキュリティ担当者にお願いしましょう。

除外設定 2

DumpNTLMInfo.pyはC:\\Users\\Pachirisu\\AppData\\Local\\programs\\python\\python39\\Scripts\\DumpNTLMInfo.pyを除外
細かいパスはご自身の環境に合わせてください

再度pip install

pip install impacket

Ref

https://github.com/fortra/impacket/issues/1725

免責事項

この記事を見て除外設定をしたことによりトラブルが発生しても責任は負いかねます。
必ずご自身の責任で実施をお願いします。

#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# Copyright Fortra, LLC and its affiliated companies 
#
# All rights reserved.
#
# This software is provided under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Description:
#   Simple SMB Server example.
#
# Author:
#   Alberto Solino (@agsolino)
#

import sys
import argparse
import logging

from impacket.examples import logger
from impacket import smbserver, version
from impacket.ntlm import compute_lmhash, compute_nthash

if __name__ == '__main__':

    # Init the example's logger theme
    print(version.BANNER)

    parser = argparse.ArgumentParser(add_help = True, description = "This script will launch a SMB Server and add a "
                                     "share specified as an argument. You need to be root in order to bind to port 445. "
                                     "For optional authentication, it is possible to specify username and password or the NTLM hash. "
                                     "Example: smbserver.py -comment 'My share' TMP /tmp")

    parser.add_argument('shareName', action='store', help='name of the share to add')
    parser.add_argument('sharePath', action='store', help='path of the share to add')
    parser.add_argument('-comment', action='store', help='share\'s comment to display when asked for shares')
    parser.add_argument('-username', action="store", help='Username to authenticate clients')
    parser.add_argument('-password', action="store", help='Password for the Username')
    parser.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes for the Username, format is LMHASH:NTHASH')
    parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output')
    parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')
    parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface')
    parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)')
    parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)')
    parser.add_argument('-outputfile', action='store', default=None, help='Output file to log smbserver output messages')

    if len(sys.argv)==1:
        parser.print_help()
        sys.exit(1)

    try:
       options = parser.parse_args()
    except Exception as e:
       logging.critical(str(e))
       sys.exit(1)

    logger.init(options.ts)

    if options.debug is True:
        logging.getLogger().setLevel(logging.DEBUG)
        # Print the Library's installation path
        logging.debug(version.getInstallationPath())
    else:
        logging.getLogger().setLevel(logging.INFO)

    if options.comment is None:
        comment = ''
    else:
        comment = options.comment

    server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port))

    if options.outputfile:
        logging.info('Switching output to file %s' % options.outputfile)
        server.setLogFile(options.outputfile)

    server.addShare(options.shareName.upper(), options.sharePath, comment)
    server.setSMB2Support(options.smb2support)

    # If a user was specified, let's add it to the credentials for the SMBServer. If no user is specified, anonymous
    # connections will be allowed
    if options.username is not None:
        # we either need a password or hashes, if not, ask
        if options.password is None and options.hashes is None:
            from getpass import getpass
            password = getpass("Password:")
            # Let's convert to hashes
            lmhash = compute_lmhash(password)
            nthash = compute_nthash(password)
        elif options.password is not None:
            lmhash = compute_lmhash(options.password)
            nthash = compute_nthash(options.password)
        else:
            lmhash, nthash = options.hashes.split(':')

        server.addCredential(options.username, 0, lmhash, nthash)

    # Here you can set a custom SMB challenge in hex format
    # If empty defaults to '4141414141414141'
    # (remember: must be 16 hex bytes long)
    # e.g. server.setSMBChallenge('12345678abcdef00')
    server.setSMBChallenge('')

    # Rock and roll
    server.start()

Discussion