Skip to content

Commit 5da5bf1

Browse files
authored
Merge pull request Pennyw0rth#649 from d4ytox/Refactoring-NXC_PATH
Refactoring nxc path and adding support for XDG Base Directory - addressing issue Pennyw0rth#558
2 parents 3591950 + 06c0a7f commit 5da5bf1

23 files changed

Lines changed: 82 additions & 87 deletions

nxc/config.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import os
21
from os.path import join as path_join
32
import configparser
4-
from nxc.paths import NXC_PATH, DATA_PATH
3+
from nxc.paths import DATA_PATH, CONFIG_PATH
54
from nxc.first_run import first_run_setup
65
from nxc.logger import nxc_logger
76
from ast import literal_eval
@@ -10,25 +9,25 @@
109
nxc_default_config.read(path_join(DATA_PATH, "nxc.conf"))
1110

1211
nxc_config = configparser.ConfigParser()
13-
nxc_config.read(os.path.join(NXC_PATH, "nxc.conf"))
12+
nxc_config.read(CONFIG_PATH)
1413

1514
if "nxc" not in nxc_config.sections():
1615
first_run_setup()
17-
nxc_config.read(os.path.join(NXC_PATH, "nxc.conf"))
16+
nxc_config.read(CONFIG_PATH)
1817

1918
# Check if there are any missing options in the config file
2019
for section in nxc_default_config.sections():
2120
if not nxc_config.has_section(section):
2221
nxc_logger.display(f"Adding missing section '{section}' to nxc.conf")
2322
nxc_config.add_section(section)
24-
with open(path_join(NXC_PATH, "nxc.conf"), "w") as config_file:
23+
with open(CONFIG_PATH, "w") as config_file:
2524
nxc_config.write(config_file)
2625
for option in nxc_default_config.options(section):
2726
if not nxc_config.has_option(section, option):
2827
nxc_logger.display(f"Adding missing option '{option}' in config section '{section}' to nxc.conf")
2928
nxc_config.set(section, option, nxc_default_config.get(section, option))
3029

31-
with open(path_join(NXC_PATH, "nxc.conf"), "w") as config_file:
30+
with open(CONFIG_PATH, "w") as config_file:
3231
nxc_config.write(config_file)
3332

3433
# THESE OPTIONS HAVE TO EXIST IN THE DEFAULT CONFIG FILE

nxc/context.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import configparser
22
import os
33

4+
from nxc.paths import NXC_PATH, CONFIG_PATH
5+
46

57
class Context:
68
def __init__(self, db, logger, args):
79
for key, value in vars(args).items():
810
setattr(self, key, value)
911

1012
self.db = db
11-
self.log_folder_path = os.path.join(os.path.expanduser("~/.nxc"), "logs")
13+
self.log_folder_path = os.path.join(NXC_PATH, "logs")
1214
self.localip = None
1315

1416
self.conf = configparser.ConfigParser()
15-
self.conf.read(os.path.expanduser("~/.nxc/nxc.conf"))
17+
self.conf.read(CONFIG_PATH)
1618

1719
self.log = logger

nxc/first_run.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,16 @@
88

99

1010
def first_run_setup(logger=nxc_logger):
11-
if not exists(TMP_PATH):
12-
mkdir(TMP_PATH)
13-
1411
if not exists(NXC_PATH):
1512
logger.display("First time use detected")
1613
logger.display("Creating home directory structure")
1714
mkdir(NXC_PATH)
15+
if not exists(TMP_PATH):
16+
mkdir(TMP_PATH)
1817

1918
folders = (
2019
"logs",
2120
"modules",
22-
"protocols",
2321
"workspaces",
2422
"obfuscated_scripts",
2523
"screenshots",
@@ -46,7 +44,3 @@ def first_run_setup(logger=nxc_logger):
4644
logger.display("Copying default configuration file")
4745
default_path = path_join(DATA_PATH, "nxc.conf")
4846
shutil.copy(default_path, NXC_PATH)
49-
50-
# if not exists(CERT_PATH):
51-
# if os.name != 'nt':
52-
# if e.errno == errno.ENOENT:

nxc/helpers/logger.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import os
22
from termcolor import colored
3+
from nxc.paths import NXC_PATH
34

45

56
def write_log(data, log_name):
6-
logs_dir = os.path.join(os.path.expanduser("~/.nxc"), "logs")
7+
logs_dir = os.path.join(NXC_PATH, "logs")
78
with open(os.path.join(logs_dir, log_name), "w") as log_output:
89
log_output.write(data)
910

nxc/loaders/protocolloader.py

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
from importlib.machinery import SourceFileLoader
33
from os import listdir
44
from os.path import join as path_join
5-
from os.path import dirname, exists, expanduser
5+
from os.path import dirname, exists
6+
67
import nxc
78

89

910
class ProtocolLoader:
10-
def __init__(self):
11-
self.nxc_path = expanduser("~/.nxc")
12-
1311
def load_protocol(self, protocol_path):
1412
loader = SourceFileLoader("protocol", protocol_path)
1513
protocol = ModuleType(loader.name)
@@ -18,27 +16,22 @@ def load_protocol(self, protocol_path):
1816

1917
def get_protocols(self):
2018
protocols = {}
21-
protocol_paths = [
22-
path_join(dirname(nxc.__file__), "protocols"),
23-
path_join(self.nxc_path, "protocols"),
24-
]
25-
26-
for path in protocol_paths:
27-
for protocol in listdir(path):
28-
if protocol[-3:] == ".py" and protocol[:-3] != "__init__":
29-
protocol_path = path_join(path, protocol)
30-
protocol_name = protocol[:-3]
31-
32-
protocols[protocol_name] = {"path": protocol_path}
33-
34-
db_file_path = path_join(path, protocol_name, "database.py")
35-
db_nav_path = path_join(path, protocol_name, "db_navigator.py")
36-
protocol_args_path = path_join(path, protocol_name, "proto_args.py")
37-
if exists(db_file_path):
38-
protocols[protocol_name]["dbpath"] = db_file_path
39-
if exists(db_nav_path):
40-
protocols[protocol_name]["nvpath"] = db_nav_path
41-
if exists(protocol_args_path):
42-
protocols[protocol_name]["argspath"] = protocol_args_path
4319

20+
proto_path = path_join(dirname(nxc.__file__), "protocols")
21+
for protocol in listdir(proto_path):
22+
if protocol[-3:] == ".py" and protocol[:-3] != "__init__":
23+
protocol_path = path_join(proto_path, protocol)
24+
protocol_name = protocol[:-3]
25+
26+
protocols[protocol_name] = {"path": protocol_path}
27+
28+
db_file_path = path_join(proto_path, protocol_name, "database.py")
29+
db_nav_path = path_join(proto_path, protocol_name, "db_navigator.py")
30+
protocol_args_path = path_join(proto_path, protocol_name, "proto_args.py")
31+
if exists(db_file_path):
32+
protocols[protocol_name]["dbpath"] = db_file_path
33+
if exists(db_nav_path):
34+
protocols[protocol_name]["nvpath"] = db_nav_path
35+
if exists(protocol_args_path):
36+
protocols[protocol_name]["argspath"] = protocol_args_path
4437
return protocols

nxc/modules/backup_operator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from impacket.smbconnection import SessionError
77
from impacket.dcerpc.v5 import transport, rrp
88
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE
9-
109
from nxc.paths import NXC_PATH
1110

1211

nxc/modules/enum_dns.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from nxc.helpers.logger import write_log
3+
from nxc.paths import NXC_PATH
34

45

56
class NXCModule:
@@ -34,7 +35,7 @@ def on_admin_login(self, context, connection):
3435
else:
3536
domains = [self.domains]
3637
data = ""
37-
38+
3839
for domain in domains:
3940
output = connection.wmi(
4041
f"Select TextRepresentation FROM MicrosoftDNS_ResourceRecord WHERE DomainName = {domain}",
@@ -64,4 +65,4 @@ def on_admin_login(self, context, connection):
6465

6566
log_name = f"DNS-Enum-{connection.host}-{datetime.now().strftime('%Y-%m-%d_%H%M%S')}.log"
6667
write_log(data, log_name)
67-
context.log.display(f"Saved raw output to ~/.nxc/logs/{log_name}")
68+
context.log.display(f"Saved raw output to {NXC_PATH}/logs/{log_name}")

nxc/modules/get-network.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# Credit to https://github.com/dirkjanm/adidnsdump @_dirkjan
33
# module by @mpgn_x64
44
import re
5-
from os.path import expanduser
65
import codecs
76
import socket
87
from datetime import datetime
@@ -14,6 +13,8 @@
1413
from impacket.structure import Structure
1514
from impacket.ldap import ldapasn1 as ldapasn1_impacket
1615
from ldap3 import LEVEL
16+
from os.path import expanduser
17+
from nxc.paths import NXC_PATH
1718

1819

1920
def get_dns_zones(connection, root, debug=False):
@@ -179,7 +180,7 @@ def on_login(self, context, connection):
179180
)
180181

181182
context.log.highlight(f"Found {len(outdata)} records")
182-
path = expanduser(f"~/.nxc/logs/{connection.domain}_network_{datetime.now().strftime('%Y-%m-%d_%H%M%S')}.log")
183+
path = expanduser(f"{NXC_PATH}/logs/{connection.domain}_network_{datetime.now().strftime('%Y-%m-%d_%H%M%S')}.log")
183184
with codecs.open(path, "w", "utf-8") as outfile:
184185
for row in outdata:
185186
if self.showhosts:

nxc/modules/get_netconnections.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from datetime import datetime
22
from nxc.helpers.logger import write_log
3+
from nxc.paths import NXC_PATH
34
import json
45

56

@@ -31,4 +32,4 @@ def on_admin_login(self, context, connection):
3132

3233
log_name = f"network-connections-{connection.host}-{datetime.now().strftime('%Y-%m-%d_%H%M%S')}.log"
3334
write_log(json.dumps(data), log_name)
34-
context.log.display(f"Saved raw output to ~/.nxc/logs/{log_name}")
35+
context.log.display(f"Saved raw output to {NXC_PATH}/logs/{log_name}")

nxc/modules/keepass_trigger.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from io import BytesIO, StringIO
77
from xml.etree import ElementTree as ET
88
from nxc.helpers.powershell import get_ps_script
9+
from nxc.paths import TMP_PATH
910

1011

1112
class NXCModule:
@@ -39,7 +40,7 @@ def __init__(self):
3940
self.share = "C$"
4041
self.remote_temp_script_path = "C:\\Windows\\Temp\\temp.ps1"
4142
self.keepass_binary_path = "C:\\Program Files\\KeePass Password Safe 2\\KeePass.exe"
42-
self.local_export_path = "/tmp"
43+
self.local_export_path = TMP_PATH
4344
self.trigger_name = "export_database"
4445
self.poll_frequency_seconds = 5
4546
self.dummy_service_name = "OneDrive Sync KeePass"

0 commit comments

Comments
 (0)