NetExec
NetExec copied to clipboard
"ON": syntax error on SSH
Describe the bug SSH module doesn't work, as some sqlite errors cause stack traces to be displayed. I tried clearing the ~/.nxc/ folder and the same error is generated.
Also is there a way to disable the local database usage?
To Reproduce
Steps to reproduce the behavior i.e.:
Command: NetExec ssh 127.0.0.1
Resulted in:
[15:47:20] ERROR Exception while calling proto_flow() on target 127.0.0.1: (sqlite3.OperationalError) near "ON": syntax error connection.py:176
[SQL: INSERT INTO hosts (host, port, banner, os) VALUES (?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET host = excluded.host, port = excluded.port, banner = excluded.banner, os = excluded.os]
[parameters: ('127.0.0.1', 22, 'SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7', '')]
(Background on this error at: https://sqlalche.me/e/20/e3q8)
╭───────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────────────────────────────────────────╮
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1964 in _exec_single_context │
│ │
│ 1961 │ │ │ │ │ │ │ evt_handled = True │
│ 1962 │ │ │ │ │ │ │ break │
│ 1963 │ │ │ │ if not evt_handled: │
│ ❱ 1964 │ │ │ │ │ self.dialect.do_execute( │
│ 1965 │ │ │ │ │ │ cursor, str_statement, effective_parameters, context │
│ 1966 │ │ │ │ │ ) │
│ 1967 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/default.py:942 in do_execute │
│ │
│ 939 │ │ cursor.executemany(statement, parameters) │
│ 940 │ │
│ 941 │ def do_execute(self, cursor, statement, parameters, context=None): │
│ ❱ 942 │ │ cursor.execute(statement, parameters) │
│ 943 │ │
│ 944 │ def do_execute_no_params(self, cursor, statement, context=None): │
│ 945 │ │ cursor.execute(statement) │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
OperationalError: near "ON": syntax error
The above exception was the direct cause of the following exception:
╭───────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────────────────────────────────────────╮
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/nxc/connection.py:168 in __init__ │
│ │
│ 165 │ │ self.logger.info(f"Socket info: host={self.host}, hostname={self.hostname}, │
│ kerberos={self.kerberos}, ipv6={self.is_ipv6}, link-local │
│ ipv6={self.is_link_local_ipv6}") │
│ 166 │ │ │
│ 167 │ │ try: │
│ ❱ 168 │ │ │ self.proto_flow() │
│ 169 │ │ except Exception as e: │
│ 170 │ │ │ if "ERROR_DEPENDENT_SERVICES_RUNNING" in str(e): │
│ 171 │ │ │ │ self.logger.error(f"Exception while calling proto_flow() on target │
│ {target}: {e}") │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/nxc/protocols/ssh.py:32 in proto_flow │
│ │
│ 29 │ │ self.logger.debug("Kicking off proto_flow") │
│ 30 │ │ self.proto_logger() │
│ 31 │ │ if self.create_conn_obj(): │
│ ❱ 32 │ │ │ self.enum_host_info() │
│ 33 │ │ │ self.print_host_info() │
│ 34 │ │ │ if self.remote_version == "Unknown SSH Version": │
│ 35 │ │ │ │ self.conn.close() │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/nxc/protocols/ssh.py:66 in enum_host_info │
│ │
│ 63 │ │ if self.conn._transport.remote_version: │
│ 64 │ │ │ self.remote_version = self.conn._transport.remote_version │
│ 65 │ │ self.logger.debug(f"Remote version: {self.remote_version}") │
│ ❱ 66 │ │ self.db.add_host(self.host, self.port, self.remote_version) │
│ 67 │ │
│ 68 │ def create_conn_obj(self): │
│ 69 │ │ self.conn = paramiko.SSHClient() │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/nxc/protocols/ssh/database.py:142 in add_host │
│ │
│ 139 │ │ update_columns = {col.name: col for col in q.excluded if col.name not in "id"} │
│ 140 │ │ q = q.on_conflict_do_update(index_elements=self.HostsTable.primary_key, │
│ set_=update_columns) │
│ 141 │ │ │
│ ❱ 142 │ │ self.db_execute(q, hosts) # .scalar() │
│ 143 │ │ # we only return updated IDs for now - when RETURNING clause is allowed we can │
│ return inserted │
│ 144 │ │ if updated_ids: │
│ 145 │ │ │ nxc_logger.debug(f"add_host() - Host IDs Updated: {updated_ids}") │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/nxc/database.py:145 in db_execute │
│ │
│ 142 │ │
│ 143 │ def db_execute(self, *args): │
│ 144 │ │ self.lock.acquire() │
│ ❱ 145 │ │ res = self.sess.execute(*args) │
│ 146 │ │ self.lock.release() │
│ 147 │ │ return res │
│ 148 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/orm/session.py:2365 in execute │
│ │
│ 2362 │ │ │
│ 2363 │ │ │
│ 2364 │ │ """ │
│ ❱ 2365 │ │ return self._execute_internal( │
│ 2366 │ │ │ statement, │
│ 2367 │ │ │ params, │
│ 2368 │ │ │ execution_options=execution_options, │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/orm/session.py:2260 in _execute_internal │
│ │
│ 2257 │ │ │ │ conn, │
│ 2258 │ │ │ ) │
│ 2259 │ │ else: │
│ ❱ 2260 │ │ │ result = conn.execute( │
│ 2261 │ │ │ │ statement, params or {}, execution_options=execution_options │
│ 2262 │ │ │ ) │
│ 2263 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1416 in execute │
│ │
│ 1413 │ │ except AttributeError as err: │
│ 1414 │ │ │ raise exc.ObjectNotExecutableError(statement) from err │
│ 1415 │ │ else: │
│ ❱ 1416 │ │ │ return meth( │
│ 1417 │ │ │ │ self, │
│ 1418 │ │ │ │ distilled_parameters, │
│ 1419 │ │ │ │ execution_options or NO_OPTIONS, │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/sql/elements.py:515 in _execute_on_connection │
│ │
│ 512 │ │ if self.supports_execution: │
│ 513 │ │ │ if TYPE_CHECKING: │
│ 514 │ │ │ │ assert isinstance(self, Executable) │
│ ❱ 515 │ │ │ return connection._execute_clauseelement( │
│ 516 │ │ │ │ self, distilled_params, execution_options │
│ 517 │ │ │ ) │
│ 518 │ │ else: │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1638 in _execute_clauseelement │
│ │
│ 1635 │ │ │ schema_translate_map=schema_translate_map, │
│ 1636 │ │ │ linting=self.dialect.compiler_linting | compiler.WARN_LINTING, │
│ 1637 │ │ ) │
│ ❱ 1638 │ │ ret = self._execute_context( │
│ 1639 │ │ │ dialect, │
│ 1640 │ │ │ dialect.execution_ctx_cls._init_compiled, │
│ 1641 │ │ │ compiled_sql, │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1843 in _execute_context │
│ │
│ 1840 │ │ if context.execute_style is ExecuteStyle.INSERTMANYVALUES: │
│ 1841 │ │ │ return self._exec_insertmany_context(dialect, context) │
│ 1842 │ │ else: │
│ ❱ 1843 │ │ │ return self._exec_single_context( │
│ 1844 │ │ │ │ dialect, context, statement, parameters │
│ 1845 │ │ │ ) │
│ 1846 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1983 in _exec_single_context │
│ │
│ 1980 │ │ │ result = context._setup_result_proxy() │
│ 1981 │ │ │
│ 1982 │ │ except BaseException as e: │
│ ❱ 1983 │ │ │ self._handle_dbapi_exception( │
│ 1984 │ │ │ │ e, str_statement, effective_parameters, cursor, context │
│ 1985 │ │ │ ) │
│ 1986 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:2352 in _handle_dbapi_exception │
│ │
│ 2349 │ │ │ │ raise newraise.with_traceback(exc_info[2]) from e │
│ 2350 │ │ │ elif should_wrap: │
│ 2351 │ │ │ │ assert sqlalchemy_exception is not None │
│ ❱ 2352 │ │ │ │ raise sqlalchemy_exception.with_traceback(exc_info[2]) from e │
│ 2353 │ │ │ else: │
│ 2354 │ │ │ │ assert exc_info[1] is not None │
│ 2355 │ │ │ │ raise exc_info[1].with_traceback(exc_info[2]) │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/base.py:1964 in _exec_single_context │
│ │
│ 1961 │ │ │ │ │ │ │ evt_handled = True │
│ 1962 │ │ │ │ │ │ │ break │
│ 1963 │ │ │ │ if not evt_handled: │
│ ❱ 1964 │ │ │ │ │ self.dialect.do_execute( │
│ 1965 │ │ │ │ │ │ cursor, str_statement, effective_parameters, context │
│ 1966 │ │ │ │ │ ) │
│ 1967 │
│ │
│ /home/dan/brute/NetExec/lib/python3.10/site-packages/sqlalchemy/engine/default.py:942 in do_execute │
│ │
│ 939 │ │ cursor.executemany(statement, parameters) │
│ 940 │ │
│ 941 │ def do_execute(self, cursor, statement, parameters, context=None): │
│ ❱ 942 │ │ cursor.execute(statement, parameters) │
│ 943 │ │
│ 944 │ def do_execute_no_params(self, cursor, statement, context=None): │
│ 945 │ │ cursor.execute(statement) │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
OperationalError: (sqlite3.OperationalError) near "ON": syntax error
[SQL: INSERT INTO hosts (host, port, banner, os) VALUES (?, ?, ?, ?) ON CONFLICT (id) DO UPDATE SET host = excluded.host, port = excluded.port, banner = excluded.banner, os = excluded.os]
[parameters: ('127.0.0.1', 22, 'SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7', '')]
Expected behavior SQL errors should not block the script processing.
NetExec info
- OS: Ubuntu 18.04.6 LTS
- Version of nxc: 1.3.0 - NeedForSpeed - 9511ca2b
- Installed from: GitHub
Thanks for the bug report! I remember there might be an issue with some ubuntu version strings and sqlalchemy, but i have to take a closer look at it. Unfortunately there is no way to disable the db, other than comment out the part where nxc adds the host to the database