diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8a3b77cb..446ebf0e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,17 +3,18 @@ # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +--- version: 2 updates: - - package-ecosystem: "pip" # See documentation for possible values - directory: "/" # Location of package manifests + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests schedule: interval: "weekly" - - package-ecosystem: "pip" # See documentation for possible values - directory: "/docs" # Location of package manifests + - package-ecosystem: "pip" # See documentation for possible values + directory: "/docs" # Location of package manifests schedule: interval: "weekly" - - package-ecosystem: "github-actions" # See documentation for possible values - directory: "/" # Location of package manifests + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests schedule: interval: "weekly" diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 1740b80c..07f78c71 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12.0-rc.1", "pypy-3.8", "pypy-3.9", "pypy-3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12.0-rc.1", "pypy-3.9", "pypy-3.10"] continue-on-error: ${{ matrix.python-version == '3.12.0-rc.1' }} steps: - uses: actions/checkout@v3 diff --git a/.readthedocs.yml b/.readthedocs.yml index 25f6d44b..5d21f764 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -19,7 +19,7 @@ build: os: ubuntu-22.04 tools: python: "3.11" - + # Optionally Python version and requirements required to build your docs python: install: diff --git a/requirements.txt b/requirements.txt index db8d73f8..43655197 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,4 +10,4 @@ python-dateutil==2.8.2 service_identity==23.1.0 tftpy==0.8.2 treq==22.2.0 -twisted==22.10.0 +twisted==23.8.0 diff --git a/src/backend_pool/pool_server.py b/src/backend_pool/pool_server.py index 02d7201d..7ee2a450 100644 --- a/src/backend_pool/pool_server.py +++ b/src/backend_pool/pool_server.py @@ -92,9 +92,7 @@ class PoolServer(Protocol): guest_id, guest_ip, ssh_port, telnet_port ) - fmt = "!cIIH{}sHHH{}s".format( - len(self.nat_public_ip), len(guest_snapshot) - ) + fmt = f"!cIIH{len(self.nat_public_ip)}sHHH{len(guest_snapshot)}s" response = struct.pack( fmt, b"r", diff --git a/src/cowrie/commands/fs.py b/src/cowrie/commands/fs.py index 26d29898..e523d324 100644 --- a/src/cowrie/commands/fs.py +++ b/src/cowrie/commands/fs.py @@ -371,9 +371,7 @@ or available locally via: info '(coreutils) rm invocation'\n""" if i[fs.A_NAME] == basename: if i[fs.A_TYPE] == fs.T_DIR and not recursive: self.errorWrite( - "rm: cannot remove `{}': Is a directory\n".format( - i[fs.A_NAME] - ) + f"rm: cannot remove `{i[fs.A_NAME]}': Is a directory\n" ) else: dir.remove(i) @@ -456,7 +454,7 @@ class Command_cp(HoneyPotCommand): dir = self.fs.get_path(os.path.dirname(resolv(dest))) outfile = os.path.basename(dest.rstrip("/")) if outfile in [x[fs.A_NAME] for x in dir]: - dir.remove([x for x in dir if x[fs.A_NAME] == outfile][0]) + dir.remove(next(x for x in dir if x[fs.A_NAME] == outfile)) s[fs.A_NAME] = outfile dir.append(s) diff --git a/src/cowrie/commands/ftpget.py b/src/cowrie/commands/ftpget.py index 3a947467..61e27682 100644 --- a/src/cowrie/commands/ftpget.py +++ b/src/cowrie/commands/ftpget.py @@ -166,9 +166,7 @@ Download a file via FTP path = os.path.dirname(fakeoutfile) if not path or not self.fs.exists(path) or not self.fs.isdir(path): self.write( - "ftpget: can't open '{}': No such file or directory".format( - self.local_file - ) + f"ftpget: can't open '{self.local_file}': No such file or directory" ) self.exit() return @@ -250,9 +248,7 @@ Download a file via FTP ftp.connect(host=self.host, port=self.port, timeout=30) except Exception as e: log.msg( - "FTP connect failed: host={}, port={}, err={}".format( - self.host, self.port, str(e) - ) + f"FTP connect failed: host={self.host}, port={self.port}, err={e!s}" ) self.write("ftpget: can't connect to remote host: Connection refused\n") return False diff --git a/src/cowrie/commands/gcc.py b/src/cowrie/commands/gcc.py index bf99cbef..cc361145 100644 --- a/src/cowrie/commands/gcc.py +++ b/src/cowrie/commands/gcc.py @@ -166,12 +166,10 @@ compilation terminated.\n""" version_short = ".".join([str(v) for v in Command_gcc.APP_VERSION[:2]]) if short: - data = """{} (Debian {}-8) {} + data = f"""{Command_gcc.APP_NAME} (Debian {version}-8) {version} Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.""".format( - Command_gcc.APP_NAME, version, version - ) +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.""" else: data = """Using built-in specs. COLLECT_GCC=gcc diff --git a/src/cowrie/commands/iptables.py b/src/cowrie/commands/iptables.py index 3008fddd..eadd36ab 100644 --- a/src/cowrie/commands/iptables.py +++ b/src/cowrie/commands/iptables.py @@ -283,7 +283,7 @@ Perhaps iptables or your kernel needs to be upgraded.\n""".format( """ self.write( - """{} {}' + f"""{Command_iptables.APP_NAME} {Command_iptables.APP_VERSION}' Usage: iptables -[AD] chain rule-specification [options] iptables -I chain [rulenum] rule-specification [options] @@ -345,9 +345,7 @@ Options: [!] --fragment -f match second or further fragments only --modprobe= try to insert modules using this command --set-counters PKTS BYTES set the counter during insert/append -[!] --version -V print package version.\n""".format( - Command_iptables.APP_NAME, Command_iptables.APP_VERSION - ) +[!] --version -V print package version.\n""" ) self.exit() diff --git a/src/cowrie/commands/perl.py b/src/cowrie/commands/perl.py index 981ed113..97fe5cee 100644 --- a/src/cowrie/commands/perl.py +++ b/src/cowrie/commands/perl.py @@ -101,9 +101,7 @@ class Command_perl(HoneyPotCommand): self.exit() else: self.write( - 'Can\'t open perl script "{}": No such file or directory\n'.format( - value - ) + f'Can\'t open perl script "{value}": No such file or directory\n' ) self.exit() diff --git a/src/cowrie/commands/ssh.py b/src/cowrie/commands/ssh.py index 799039b9..94a0bd1e 100644 --- a/src/cowrie/commands/ssh.py +++ b/src/cowrie/commands/ssh.py @@ -82,10 +82,8 @@ class Command_ssh(HoneyPotCommand): self.ip = host else: self.write( - "ssh: Could not resolve hostname {}: \ - Name or service not known\n".format( - host - ) + f"ssh: Could not resolve hostname {host}: \ + Name or service not known\n" ) self.exit() else: @@ -98,10 +96,8 @@ class Command_ssh(HoneyPotCommand): self.user = user self.write( - "The authenticity of host '{} ({})' \ - can't be established.\n".format( - self.host, self.ip - ) + f"The authenticity of host '{self.host} ({self.ip})' \ + can't be established.\n" ) self.write( "RSA key fingerprint is \ @@ -112,10 +108,8 @@ class Command_ssh(HoneyPotCommand): def yesno(self, line: str) -> None: self.write( - "Warning: Permanently added '{}' (RSA) to the \ - list of known hosts.\n".format( - self.host - ) + f"Warning: Permanently added '{self.host}' (RSA) to the \ + list of known hosts.\n" ) self.write(f"{self.user}@{self.host}'s password: ") self.protocol.password_input = True @@ -136,10 +130,8 @@ class Command_ssh(HoneyPotCommand): self.protocol.cwd = "/" self.protocol.password_input = False self.write( - "Linux {} 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 \ - UTC 2009 i686\n".format( - self.protocol.hostname - ) + f"Linux {self.protocol.hostname} 2.6.26-2-686 #1 SMP Wed Nov 4 20:45:37 \ + UTC 2009 i686\n" ) self.write(f"Last login: {time.ctime(time.time() - 123123)} from 192.168.9.4\n") self.exit() diff --git a/src/cowrie/commands/wget.py b/src/cowrie/commands/wget.py index 6a4ebc40..d5362432 100644 --- a/src/cowrie/commands/wget.py +++ b/src/cowrie/commands/wget.py @@ -139,9 +139,7 @@ class Command_wget(HoneyPotCommand): path = os.path.dirname(self.outfile) # type: ignore if not path or not self.fs.exists(path) or not self.fs.isdir(path): self.errorWrite( - "wget: {}: Cannot open: No such file or directory\n".format( - self.outfile - ) + f"wget: {self.outfile}: Cannot open: No such file or directory\n" ) self.exit() return diff --git a/src/cowrie/core/credentials.py b/src/cowrie/core/credentials.py index 88d75d5d..50821eb4 100644 --- a/src/cowrie/core/credentials.py +++ b/src/cowrie/core/credentials.py @@ -39,7 +39,7 @@ class IUsername(ICredentials): """ Encapsulate username only - @type username: C{str} + @type username: C{bytes} @ivar username: The username associated with these credentials. """ @@ -48,10 +48,10 @@ class IUsernamePasswordIP(IUsernamePassword): """ I encapsulate a username, a plaintext password and a source IP - @type username: C{str} + @type username: C{bytes} @ivar username: The username associated with these credentials. - @type password: C{str} + @type password: C{bytes} @ivar password: The password associated with these credentials. @type ip: C{str} @@ -71,16 +71,16 @@ class PluggableAuthenticationModulesIP: Twisted removed IPAM in 15, adding in Cowrie now """ - def __init__(self, username: str, pamConversion: Callable, ip: str) -> None: - self.username: str = username + def __init__(self, username: bytes, pamConversion: Callable, ip: str) -> None: + self.username: bytes = username self.pamConversion: Callable = pamConversion self.ip: str = ip @implementer(IUsername) class Username: - def __init__(self, username: str): - self.username: str = username + def __init__(self, username: bytes): + self.username: bytes = username @implementer(IUsernamePasswordIP) @@ -89,10 +89,10 @@ class UsernamePasswordIP: This credential interface also provides an IP address """ - def __init__(self, username: str, password: str, ip: str) -> None: - self.username: str = username - self.password: str = password + def __init__(self, username: bytes, password: bytes, ip: str) -> None: + self.username: bytes = username + self.password: bytes = password self.ip: str = ip - def checkPassword(self, password: str) -> bool: + def checkPassword(self, password: bytes) -> bool: return self.password == password diff --git a/src/cowrie/output/abuseipdb.py b/src/cowrie/output/abuseipdb.py index f651b29a..787107ba 100644 --- a/src/cowrie/output/abuseipdb.py +++ b/src/cowrie/output/abuseipdb.py @@ -358,7 +358,7 @@ class Reporter: "ip": ip, "categories": "18,22", "comment": "Cowrie Honeypot: Unauthorised SSH/Telnet login attempt " - 'with user "{}" at {}'.format(uname, t), + f'with user "{uname}" at {t}', } self.http_request(params) diff --git a/src/cowrie/output/influx.py b/src/cowrie/output/influx.py index d11f837e..3763b035 100644 --- a/src/cowrie/output/influx.py +++ b/src/cowrie/output/influx.py @@ -54,10 +54,8 @@ class Output(cowrie.core.output.Output): match = re.search(r"^\d+[dhmw]{1}$", retention_policy_duration) if not match: log.msg( - ( "output_influx: invalid retention policy." - "Using default '{}'.." - ).format(retention_policy_duration) + f"Using default '{retention_policy_duration}'.." ) retention_policy_duration = retention_policy_duration_default else: @@ -215,6 +213,6 @@ class Output(cowrie.core.output.Output): if not result: log.msg( - "output_influx: error when writing '{}' measurement" - "in the db.".format(eventid) + f"output_influx: error when writing '{eventid}' measurement" + "in the db." ) diff --git a/src/cowrie/python/logfile.py b/src/cowrie/python/logfile.py index 49112c2b..718fe213 100644 --- a/src/cowrie/python/logfile.py +++ b/src/cowrie/python/logfile.py @@ -23,9 +23,7 @@ class CowrieDailyLogFile(logfile.DailyLogFile): Return the suffix given a (year, month, day) tuple or unixtime """ try: - return "{:02d}-{:02d}-{:02d}".format( - tupledate[0], tupledate[1], tupledate[2] - ) + return f"{tupledate[0]:02d}-{tupledate[1]:02d}-{tupledate[2]:02d}" except Exception: # try taking a float unixtime return "_".join(map(str, self.toDate(tupledate))) diff --git a/src/cowrie/shell/fs.py b/src/cowrie/shell/fs.py index 15c179d7..b47136d6 100644 --- a/src/cowrie/shell/fs.py +++ b/src/cowrie/shell/fs.py @@ -355,7 +355,7 @@ class HoneyPotFilesystem: _dir = self.get_path(_path) outfile: str = os.path.basename(path) if outfile in [x[A_NAME] for x in _dir]: - _dir.remove([x for x in _dir if x[A_NAME] == outfile][0]) + _dir.remove(next(x for x in _dir if x[A_NAME] == outfile)) _dir.append([outfile, T_FILE, uid, gid, size, mode, ctime, [], None, None]) self.newcount += 1 return True diff --git a/src/cowrie/ssh/userauth.py b/src/cowrie/ssh/userauth.py index 47033f4d..74188c59 100644 --- a/src/cowrie/ssh/userauth.py +++ b/src/cowrie/ssh/userauth.py @@ -29,7 +29,7 @@ class HoneyPotSSHUserAuthServer(userauth.SSHUserAuthServer): """ bannerSent: bool = False - user: str + user: bytes _pamDeferred: defer.Deferred | None def serviceStarted(self) -> None: diff --git a/src/cowrie/ssh_proxy/server_transport.py b/src/cowrie/ssh_proxy/server_transport.py index d4955df8..a980076a 100644 --- a/src/cowrie/ssh_proxy/server_transport.py +++ b/src/cowrie/ssh_proxy/server_transport.py @@ -306,9 +306,7 @@ class FrontendSSHTransport(transport.SSHServerTransport, TimeoutMixin): cencCS = ",".join([alg.decode("utf-8") for alg in encCS]) cmacCS = ",".join([alg.decode("utf-8") for alg in macCS]) ccompCS = ",".join([alg.decode("utf-8") for alg in compCS]) - hasshAlgorithms = "{kex};{enc};{mac};{cmp}".format( - kex=ckexAlgs, enc=cencCS, mac=cmacCS, cmp=ccompCS - ) + hasshAlgorithms = f"{ckexAlgs};{cencCS};{cmacCS};{ccompCS}" hassh = md5(hasshAlgorithms.encode("utf-8")).hexdigest() log.msg( diff --git a/tox.ini b/tox.ini index e5a61be7..3268f0d1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] skipsdist = True -envlist = lint,docs,typing,py38,py39,py310,py311,pypy38,pypy39 +envlist = lint,docs,typing,py38,py39,py310,py311,pypy39 deps = -r{toxinidir}/requirements.txt skip_missing_interpreters = True @@ -10,7 +10,6 @@ python = 3.9: py39 3.10: py310, lint, docs, typing 3.11: py311 - pypy-3.8: pypy38 pypy-3.9: pypy39 [testenv]