Skip to content

Commit

Permalink
[connection.py] add 'self.port' & improve gethost_addrinfo
Browse files Browse the repository at this point in the history
Signed-off-by: XiaoliChan <[email protected]>
  • Loading branch information
XiaoliChan committed Oct 13, 2023
1 parent 66e6c95 commit fbe9c9f
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 49 deletions.
28 changes: 14 additions & 14 deletions nxc/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

import random
import socket
from socket import AF_INET, AF_INET6, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME
from socket import getaddrinfo
from os.path import isfile
from threading import BoundedSemaphore
from functools import wraps
from time import sleep
from ipaddress import ip_address
from socket import AF_UNSPEC, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME, getaddrinfo

from nxc.config import pwned_label
from nxc.helpers.logger import highlight
Expand All @@ -22,17 +21,17 @@
global_failed_logins = 0
user_failed_logins = {}


def gethost_addrinfo(hostname):
try:
for res in getaddrinfo( hostname, None, AF_INET6, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME):
af, socktype, proto, canonname, sa = res
host = canonname if ip_address(sa[0]).is_link_local else sa[0]
except socket.gaierror:
for res in getaddrinfo( hostname, None, AF_INET, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME):
af, socktype, proto, canonname, sa = res
host = sa[0] if sa[0] else canonname
return host
is_ipv6 = False
is_link_local_ipv6 = False
for res in getaddrinfo( hostname, None, AF_UNSPEC, SOCK_DGRAM, IPPROTO_IP, AI_CANONNAME):
af, socktype, proto, canonname, sa = res
if ip_address(sa[0]).version == 6:
is_ipv6 = True
host, is_link_local_ipv6 = (canonname, True) if ip_address(sa[0]).is_link_local else (sa[0], False)
else:
host = sa[0]
return host, is_ipv6, is_link_local_ipv6

def requires_admin(func):
def _decorator(self, *args, **kwargs):
Expand Down Expand Up @@ -76,6 +75,7 @@ def __init__(self, args, db, host):
self.args = args
self.db = db
self.hostname = host
self.port = None
self.conn = None
self.admin_privs = False
self.password = ""
Expand All @@ -89,10 +89,10 @@ def __init__(self, args, db, host):
self.logger = nxc_logger

try:
self.host = gethost_addrinfo(self.hostname)
self.host, self.is_ipv6, self.is_link_local_ipv6 = gethost_addrinfo(self.hostname)
if self.args.kerberos:
self.host = self.hostname
self.logger.info(f"Socket info: host={self.host}, hostname={self.hostname}, kerberos={ 'True' if self.args.kerberos else 'False' }")
self.logger.info(f"Socket info: host={self.host}, hostname={self.hostname}, kerberos={ 'True' if self.args.kerberos else 'False' }, ipv6={self.is_ipv6}, link-local ipv6={self.is_link_local_ipv6}")
except Exception as e:
self.logger.info(f"Error resolving hostname {self.hostname}: {e}")
return
Expand Down
9 changes: 5 additions & 4 deletions nxc/protocols/ftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ def __init__(self, args, db, host):
super().__init__(args, db, host)

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "FTP",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)
Expand All @@ -45,7 +46,7 @@ def print_host_info(self):
def create_conn_obj(self):
self.conn = FTP()
try:
self.conn.connect(host=self.host, port=self.args.port)
self.conn.connect(host=self.host, port=self.port)
except error_reply:
return False
except error_temp:
Expand All @@ -72,8 +73,8 @@ def plaintext_login(self, username, password):

# 230 is "User logged in, proceed" response, ftplib raises an exception on failed login
if "230" in resp:
self.logger.debug(f"Host: {self.host} Port: {self.args.port}")
self.db.add_host(self.host, self.args.port, self.remote_version)
self.logger.debug(f"Host: {self.host} Port: {self.port}")
self.db.add_host(self.host, self.port, self.remote_version)

cred_id = self.db.add_credential(username, password)

Expand Down
19 changes: 10 additions & 9 deletions nxc/protocols/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,19 @@ def __init__(self, args, db, host):

def proto_logger(self):
# self.logger = nxc_logger
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "LDAP",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)

def get_ldap_info(self, host):
try:
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap"
ldap_url = f"{proto}://{host}"
self.logger.info(f"Connecting to {ldap_url} with no baseDN")
try:
Expand Down Expand Up @@ -360,7 +361,7 @@ def kerberos_login(

try:
# Connect to LDAP
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap"
ldap_url = f"{proto}://{self.target}"
self.logger.info(f"Connecting to {ldap_url} - {self.baseDN} [1]")
self.ldapConnection = ldap_impacket.LDAPConnection(ldap_url, self.baseDN)
Expand All @@ -386,7 +387,7 @@ def kerberos_login(
# out = f"{domain}\\{self.username}{' from ccache' if useCache else ':%s' % (kerb_pass if not self.config.get('nxc', 'audit_mode') else self.config.get('nxc', 'audit_mode') * 8)} {highlight('({})'.format(self.config.get('nxc', 'pwn3d_label')) if self.admin_privs else '')}"

self.logger.extra["protocol"] = "LDAP"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389"
self.logger.success(out)

if not self.args.local_auth:
Expand Down Expand Up @@ -484,7 +485,7 @@ def plaintext_login(self, domain, username, password):

try:
# Connect to LDAP
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap"
ldap_url = f"{proto}://{self.target}"
self.logger.debug(f"Connecting to {ldap_url} - {self.baseDN} [3]")
self.ldapConnection = ldap_impacket.LDAPConnection(ldap_url, self.baseDN)
Expand All @@ -495,7 +496,7 @@ def plaintext_login(self, domain, username, password):
out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}"

self.logger.extra["protocol"] = "LDAP"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389"
self.logger.success(out)

if not self.args.local_auth:
Expand Down Expand Up @@ -575,7 +576,7 @@ def hash_login(self, domain, username, ntlm_hash):

try:
# Connect to LDAP
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap"
ldaps_url = f"{proto}://{self.target}"
self.logger.info(f"Connecting to {ldaps_url} - {self.baseDN}")
self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN)
Expand All @@ -585,7 +586,7 @@ def hash_login(self, domain, username, ntlm_hash):
# Prepare success credential text
out = f"{domain}\\{self.username}:{process_secret(self.nthash)} {self.mark_pwned()}"
self.logger.extra["protocol"] = "LDAP"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389"
self.logger.success(out)

if not self.args.local_auth:
Expand Down Expand Up @@ -1409,7 +1410,7 @@ def bloodhound(self):
self.logger.highlight("Using kerberos auth from ccache")

timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S") + "_"
bloodhound = BloodHound(ad, self.hostname, self.host, self.args.port)
bloodhound = BloodHound(ad, self.hostname, self.host, self.port)
bloodhound.connect()

bloodhound.run(
Expand Down
5 changes: 3 additions & 2 deletions nxc/protocols/mssql.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ def proto_flow(self):
self.call_cmd_args()

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "MSSQL",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": "None",
}
)
Expand Down Expand Up @@ -121,7 +122,7 @@ def print_host_info(self):

def create_conn_obj(self):
try:
self.conn = tds.MSSQL(self.host, self.args.port)
self.conn = tds.MSSQL(self.host, self.port)
self.conn.connect()
except socket.error as e:
self.logger.debug(f"Error connecting to MSSQL: {e}")
Expand Down
7 changes: 4 additions & 3 deletions nxc/protocols/rdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ def __init__(self, args, db, host):
# self.call_cmd_args()

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "RDP",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)
Expand All @@ -112,7 +113,7 @@ def print_host_info(self):
return True

def create_conn_obj(self):
self.target = RDPTarget(ip=self.host, domain="FAKE", port=self.args.port, timeout=self.args.rdp_timeout)
self.target = RDPTarget(ip=self.host, domain="FAKE", port=self.port, timeout=self.args.rdp_timeout)
self.auth = NTLMCredential(secret="pass", username="user", domain="FAKE", stype=asyauthSecret.PASS)

self.check_nla()
Expand Down Expand Up @@ -154,7 +155,7 @@ def create_conn_obj(self):
self.target = RDPTarget(
ip=self.host,
hostname=self.hostname,
port=self.args.port,
port=self.port,
domain=self.domain,
dc_ip=self.domain,
timeout=self.args.rdp_timeout,
Expand Down
17 changes: 9 additions & 8 deletions nxc/protocols/smb.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,12 @@ def __init__(self, args, db, host):
connection.__init__(self, args, db, host)

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "SMB",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)
Expand Down Expand Up @@ -592,7 +593,7 @@ def create_smbv1_conn(self, kdc=""):
self.host if not kdc else kdc,
self.host if not kdc else kdc,
None,
self.args.port,
self.port,
preferredDialect=SMB_DIALECT,
timeout=self.args.smb_timeout,
)
Expand All @@ -613,7 +614,7 @@ def create_smbv3_conn(self, kdc=""):
self.host if not kdc else kdc,
self.host if not kdc else kdc,
None,
self.args.port,
self.port,
timeout=self.args.smb_timeout,
)
self.smbv1 = False
Expand Down Expand Up @@ -755,7 +756,7 @@ def execute(self, payload=None, get_output=False, methods=None):
self.host if not self.kerberos else self.hostname + "." + self.domain,
self.smb_share_name,
self.conn,
self.args.port,
self.port,
self.username,
self.password,
self.domain,
Expand All @@ -764,7 +765,7 @@ def execute(self, payload=None, get_output=False, methods=None):
self.kdcHost,
self.hash,
self.args.share,
self.args.port,
self.port,
self.logger,
self.args.get_output_tries
)
Expand Down Expand Up @@ -1320,12 +1321,12 @@ def rid_brute(self, max_rid=None):

try:
full_hostname = self.host if not self.kerberos else self.hostname + "." + self.domain
string_binding = KNOWN_PROTOCOLS[self.args.port]["bindstr"]
string_binding = KNOWN_PROTOCOLS[self.port]["bindstr"]
logging.debug(f"StringBinding {string_binding}")
rpc_transport = transport.DCERPCTransportFactory(string_binding)
rpc_transport.set_dport(self.args.port)
rpc_transport.set_dport(self.port)

if KNOWN_PROTOCOLS[self.args.port]["set_host"]:
if KNOWN_PROTOCOLS[self.port]["set_host"]:
rpc_transport.setRemoteHost(full_hostname)

if hasattr(rpc_transport, "set_credentials"):
Expand Down
11 changes: 6 additions & 5 deletions nxc/protocols/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ def __init__(self, args, db, host):
super().__init__(args, db, host)

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "SSH",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)
Expand All @@ -46,14 +47,14 @@ def enum_host_info(self):
stdin, stdout, stderr = self.conn.exec_command("uname -r")
self.server_os = stdout.read().decode("utf-8")
self.logger.debug(f"OS retrieved: {self.server_os}")
self.db.add_host(self.host, self.args.port, self.remote_version, os=self.server_os)
self.db.add_host(self.host, self.port, self.remote_version, os=self.server_os)

def create_conn_obj(self):
self.conn = paramiko.SSHClient()
self.conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())

try:
self.conn.connect(self.host, port=self.args.port)
self.conn.connect(self.host, port=self.port)
except AuthenticationException:
return True
except SSHException:
Expand Down Expand Up @@ -91,7 +92,7 @@ def plaintext_login(self, username, password, private_key=None):
self.logger.debug(f"Logging in with key")
self.conn.connect(
self.host,
port=self.args.port,
port=self.port,
username=username,
passphrase=password if password != "" else None,
pkey=pkey,
Expand All @@ -118,7 +119,7 @@ def plaintext_login(self, username, password, private_key=None):
self.logger.debug(f"Logging in with password")
self.conn.connect(
self.host,
port=self.args.port,
port=self.port,
username=username,
password=password,
look_for_keys=False,
Expand Down
5 changes: 3 additions & 2 deletions nxc/protocols/vnc.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ def proto_flow(self):
self.call_cmd_args()

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(
extra={
"protocol": "VNC",
"host": self.host,
"port": self.args.port,
"port": self.port,
"hostname": self.hostname,
}
)
Expand All @@ -53,7 +54,7 @@ def print_host_info(self):

def create_conn_obj(self):
try:
self.target = RDPTarget(ip=self.host, port=self.args.port)
self.target = RDPTarget(ip=self.host, port=self.port)
credential = UniCredential(protocol=asyauthProtocol.PLAIN, stype=asyauthSecret.NONE)
self.conn = VNCConnection(target=self.target, credentials=credential, iosettings=self.iosettings)
asyncio.run(self.connect_vnc(True))
Expand Down
5 changes: 3 additions & 2 deletions nxc/protocols/wmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,17 @@ def __init__(self, args, db, host):
connection.__init__(self, args, db, host)

def proto_logger(self):
self.port = self.args.port
self.logger = NXCAdapter(extra={'protocol': 'WMI',
'host': self.host,
'port': self.args.port,
'port': self.port,
'hostname': self.hostname})

def create_conn_obj(self):
if self.remoteName == '':
self.remoteName = self.host
try:
rpctansport = transport.DCERPCTransportFactory(r'ncacn_ip_tcp:{0}[{1}]'.format(self.remoteName, str(self.args.port)))
rpctansport = transport.DCERPCTransportFactory(r'ncacn_ip_tcp:{0}[{1}]'.format(self.remoteName, str(self.port)))
rpctansport.set_credentials(username="", password="", domain="", lmhash="", nthash="", aesKey="")
rpctansport.setRemoteHost(self.host)
rpctansport.set_connect_timeout(self.args.rpc_timeout)
Expand Down

0 comments on commit fbe9c9f

Please sign in to comment.