Skip to content

Commit 6de6247

Browse files
Merge pull request Pennyw0rth#590 from Pennyw0rth/marshall-db-ip-fix
fix: check if an IP is being searched for when calling get_hosts
2 parents aa832c5 + f4fa975 commit 6de6247

6 files changed

Lines changed: 47 additions & 18 deletions

File tree

nxc/database.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import configparser
2+
import ipaddress
23
import shutil
34
import sys
45
from os import mkdir
@@ -8,7 +9,7 @@
89
from sqlite3 import connect
910
from threading import Lock
1011

11-
from sqlalchemy import create_engine, MetaData
12+
from sqlalchemy import create_engine, MetaData, func
1213
from sqlalchemy.exc import IllegalStateChangeError
1314
from sqlalchemy.orm import sessionmaker, scoped_session
1415

@@ -109,7 +110,36 @@ def initialize_db():
109110

110111
# Even if the default workspace exists, we still need to check if every protocol has a database (in case of a new protocol)
111112
init_protocol_dbs("default")
112-
113+
114+
def format_host_query(q, filter_term, HostsTable):
115+
"""One annoying thing is that if you search for an ip such as '10.10.10.5',
116+
it will return 10.10.10.5 and 10.10.10.52, so we have to check if its an ip address first
117+
"""
118+
# the FTP and SSH protocols call the column host instead of IP
119+
# TODO: normalize these column names
120+
if hasattr(HostsTable.c, "ip"):
121+
ip_column = HostsTable.c.ip
122+
nxc_logger.debug("Using 'ip' column for filtering")
123+
elif hasattr(HostsTable.c, "host"):
124+
ip_column = HostsTable.c.host
125+
nxc_logger.debug("Using 'host' column for filtering")
126+
else:
127+
nxc_logger.debug("Neither 'ip' nor 'host' columns found in the table")
128+
return q
129+
130+
# first we check if its an ip address
131+
try:
132+
ipaddress.ip_address(filter_term)
133+
nxc_logger.debug(f"filter_term is an IP address: {filter_term}")
134+
q = q.filter(ip_column == filter_term)
135+
except ValueError:
136+
nxc_logger.debug(f"filter_term is not an IP address: {filter_term}")
137+
like_term = func.lower(f"%{filter_term}%")
138+
139+
# check if the hostname column exists for hostname searching
140+
q = q.filter(ip_column.like(like_term) | func.lower(HostsTable.c.hostname).like(like_term)) if hasattr(HostsTable.c, "hostname") else q.filter(ip_column.like(like_term))
141+
142+
return q
113143

114144
class BaseDB:
115145
def __init__(self, db_engine):

nxc/protocols/ftp/database.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
NoSuchTableError,
88
)
99

10-
from nxc.database import BaseDB
10+
from nxc.database import BaseDB, format_host_query
1111
from nxc.logger import nxc_logger
1212

1313

@@ -221,8 +221,8 @@ def get_hosts(self, filter_term=None):
221221
return [results]
222222
# if we're filtering by host
223223
elif filter_term and filter_term != "":
224-
like_term = func.lower(f"%{filter_term}%")
225-
q = q.filter(self.HostsTable.c.host.like(like_term))
224+
q = format_host_query(q, filter_term, self.HostsTable)
225+
226226
results = self.db_execute(q).all()
227227
nxc_logger.debug(f"FTP get_hosts() - results: {results}")
228228
return results

nxc/protocols/mssql/database.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from sqlalchemy.dialects.sqlite import Insert # used for upsert
66
from sqlalchemy.exc import SAWarning, NoInspectionAvailable, NoSuchTableError
77

8-
from nxc.database import BaseDB
8+
from nxc.database import BaseDB, format_host_query
99
from nxc.logger import nxc_logger
1010

1111
# if there is an issue with SQLAlchemy and a connection cannot be cleaned up properly it spews out annoying warnings
@@ -272,7 +272,6 @@ def get_hosts(self, filter_term=None, domain=None):
272272
q = q.filter(func.lower(self.HostsTable.c.domain) == func.lower(domain))
273273
# if we're filtering by ip/hostname
274274
elif filter_term and filter_term != "":
275-
like_term = func.lower(f"%{filter_term}%")
276-
q = select(self.HostsTable).filter(self.HostsTable.c.ip.like(like_term) | func.lower(self.HostsTable.c.hostname).like(like_term))
275+
q = format_host_query(q, filter_term, self.HostsTable)
277276

278277
return self.db_execute(q).all()

nxc/protocols/smb/database.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
from sqlalchemy.exc import SAWarning
1313

14-
from nxc.database import BaseDB
14+
from nxc.database import BaseDB, format_host_query
1515
from nxc.logger import nxc_logger
1616

1717
# if there is an issue with SQLAlchemy and a connection cannot be cleaned up properly it spews out annoying warnings
@@ -349,6 +349,7 @@ def add_admin_user(self, credtype, domain, username, password, host, user_id=Non
349349
hosts = self.get_hosts(host)
350350

351351
if users and hosts:
352+
nxc_logger.debug(f"users: {users}, hosts: {hosts}")
352353
for user, host in zip(users, hosts, strict=True):
353354
user_id = user[0]
354355
host_id = host[0]
@@ -468,8 +469,8 @@ def get_hosts(self, filter_term=None, domain=None):
468469
q = q.filter(self.HostsTable.c.domain.like(like_term))
469470
# if we're filtering by ip/hostname
470471
elif filter_term and filter_term != "":
471-
like_term = func.lower(f"%{filter_term}%")
472-
q = q.filter(self.HostsTable.c.ip.like(like_term) | func.lower(self.HostsTable.c.hostname).like(like_term))
472+
q = format_host_query(q, filter_term, self.HostsTable)
473+
473474
results = self.db_execute(q).all()
474475
nxc_logger.debug(f"smb hosts() - results: {results}")
475476
return results

nxc/protocols/ssh/database.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
NoSuchTableError,
1010
)
1111

12-
from nxc.database import BaseDB
12+
from nxc.database import BaseDB, format_host_query
1313
from nxc.logger import nxc_logger
1414
from nxc.paths import NXC_PATH
1515

@@ -348,8 +348,8 @@ def get_hosts(self, filter_term=None):
348348
return [results]
349349
# if we're filtering by host
350350
elif filter_term and filter_term != "":
351-
like_term = func.lower(f"%{filter_term}%")
352-
q = q.filter(self.HostsTable.c.host.like(like_term))
351+
q = format_host_query(q, filter_term, self.HostsTable)
352+
353353
results = self.db_execute(q).all()
354354
nxc_logger.debug(f"SSH get_hosts() - results: {results}")
355355
return results

nxc/protocols/winrm/database.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import sys
2-
32
from sqlalchemy import Table, select, func, delete
43
from sqlalchemy.dialects.sqlite import Insert
54
from sqlalchemy.exc import (
65
NoInspectionAvailable,
76
NoSuchTableError,
87
)
98

10-
from nxc.database import BaseDB
9+
from nxc.database import BaseDB, format_host_query
1110
from nxc.logger import nxc_logger
1211

1312

@@ -309,8 +308,8 @@ def get_hosts(self, filter_term=None):
309308
q = q.filter(self.HostsTable.c.domain.like(like_term))
310309
# if we're filtering by ip/hostname
311310
elif filter_term and filter_term != "":
312-
like_term = func.lower(f"%{filter_term}%")
313-
q = q.filter(self.HostsTable.c.ip.like(like_term) | func.lower(self.HostsTable.c.hostname).like(like_term))
311+
q = format_host_query(q, filter_term, self.HostsTable)
312+
314313
results = self.db_execute(q).all()
315314
nxc_logger.debug(f"winrm get_hosts() - results: {results}")
316315
return results

0 commit comments

Comments
 (0)