From a223fa1c0f3d58fe43f634d1ba9afb7d7fdd030b Mon Sep 17 00:00:00 2001 From: cytopia Date: Fri, 26 Mar 2021 18:05:36 +0100 Subject: [PATCH 01/13] Ensure to re-accept during local port forwarding if client quits --- CHANGELOG.md | 6 ++++++ README.md | 2 +- bin/pwncat | 8 ++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58dde76e..5c01d774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ## Unreleased +## Release 0.1.1 + +### Fixes +- Fixes: pwncat will re-accept during local portforwarding if the client quits (previously pwncat shutdown) + + ## Release 0.1.0 ### Fixes diff --git a/README.md b/README.md index dacb9455..82019fa0 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ -> [1] mypy type coverage (fully typed: 93.84%)
+> [1] mypy type coverage (fully typed: 93.99%)
> [2] Failing builds do not indicate broken functionality. Integration tests run for multiple hours and break sporadically for various different reasons (network timeouts, unknown cancellations of GitHub Actions, etc): #735, #841
> diff --git a/bin/pwncat b/bin/pwncat index a3e81588..ea92b511 100755 --- a/bin/pwncat +++ b/bin/pwncat @@ -128,7 +128,7 @@ if os.environ.get("MYPY_CHECK", False): APPNAME = "pwncat" APPREPO = "https://github.com/cytopia/pwncat" -VERSION = "0.1.0" +VERSION = "0.1.1" # Default timeout for timeout-based sys.stdin and socket.recv TIMEOUT_READ_STDIN = 0.05 @@ -6160,6 +6160,9 @@ def main(): # Run local port-forward # -> listen locally and forward traffic to remote (connect) if mode == "local": + # Enure to re-connect forever during local port forward + cli_opts.reconn = -1 + cli_opts.reconn_wait = 0.0 srv_opts.keep_open = True lhost = args.local.split(":")[0] lport = int(args.local.split(":")[1]) @@ -6198,8 +6201,9 @@ def main(): # -> connect to client, connect to target and proxy traffic in between. if mode == "remote": # TODO: Make the listen address optional! + # Enure to re-connect forever during remote port forward cli_opts.reconn = -1 - cli_opts.reconn_wait = 0.1 + cli_opts.reconn_wait = 0.0 lhost = args.remote.split(":")[0] lport = int(args.remote.split(":")[1]) # Create local and remote client From 4fc94662b5b4b43c1dcbea376331c0c2559b6836 Mon Sep 17 00:00:00 2001 From: cytopia Date: Fri, 26 Mar 2021 18:06:01 +0100 Subject: [PATCH 02/13] Python Black autoformat --- bin/pwncat | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/bin/pwncat b/bin/pwncat index ea92b511..c926a649 100755 --- a/bin/pwncat +++ b/bin/pwncat @@ -1677,13 +1677,20 @@ class Sock(_Singleton("SingletonMeta", (object,), {})): # type: ignore except (OSError, socket.error) as error: msg = "Connecting to {}:{} (family {}/{}, {}) failed: {}".format( - addr, port, sock.family, sock_family_name, sock_type_name, error, + addr, + port, + sock.family, + sock_family_name, + sock_type_name, + error, ) raise socket.error(msg) local = sock.getsockname() self.__log.debug( - "Connected from %s:%d", local[0], local[1], + "Connected from %s:%d", + local[0], + local[1], ) self.__log.info( "Connected to %s:%d (family %d/%s, %s)", @@ -3255,9 +3262,7 @@ class IONetworkScanner(IO): # [1/7] Check for termination request if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for IONetworkScanner.producer" - ) + self.log.trace("TERMINATE signal ACK for IONetworkScanner.producer") # type: ignore return addr = self.__targets[family] @@ -3316,7 +3321,9 @@ class IONetworkScanner(IO): yield self.__enc.encode(msg) if banner is None and succ_banner: msg = "[+] {:>5}/{} open ({})".format( - port, self.__sock.get_type_name(sock_type), self.__sock.get_family_name(family), + port, + self.__sock.get_type_name(sock_type), + self.__sock.get_family_name(family), ) yield self.__enc.encode(msg) @@ -3513,7 +3520,8 @@ class IOStdinStdout(IO): # Setting sys.stdin to binary mode fixes that. if hasattr(os, "O_BINARY"): msvcrt.setmode( # type: ignore - sys.stdin.fileno(), os.O_BINARY, # pylint: disable=no-member + sys.stdin.fileno(), + os.O_BINARY, # pylint: disable=no-member ) return sys.stdin.read() # type: ignore @@ -4093,9 +4101,7 @@ class Runner(object): # [1/3] Start available action in a thread for key in self.__actions: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [1]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [1]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -4134,9 +4140,7 @@ class Runner(object): # [2/3] Start available timers in a thread for key in self.__timers: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [2]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [2]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -4157,9 +4161,7 @@ class Runner(object): # [3/3] Start available repeaters in a thread for key in self.__repeaters: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [3]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [3]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -5283,7 +5285,8 @@ def _args_check_mutually_exclusive(parser, args): if args.ipv4 and args.ipv6: parser.print_usage() print( - "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), file=sys.stderr, + "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5326,13 +5329,15 @@ def _args_check_mutually_exclusive(parser, args): if args.keep_open and (args.udp): parser.print_usage() print( - "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), + file=sys.stderr, ) sys.exit(1) if args.keep_open and not args.listen: parser.print_usage() print( - "%s: error: --keep-open only works with -l/--listen" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open only works with -l/--listen" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5340,7 +5345,8 @@ def _args_check_mutually_exclusive(parser, args): if args.reconn != 0 and not connect_mode: parser.print_usage() print( - "%s: error: --reconn only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --reconn only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5357,7 +5363,8 @@ def _args_check_mutually_exclusive(parser, args): if args.udp_sconnect and not connect_mode: parser.print_usage() print( - "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -6017,7 +6024,8 @@ The default is to send a null byte sting: '\\0'. if not args.zero and len(args.port) > 1: parser.print_usage() print( - "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), file=sys.stderr, + "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), + file=sys.stderr, ) sys.exit(1) From ef5a03e8fa5b5dac9e71746d215af5b751e78d43 Mon Sep 17 00:00:00 2001 From: cytopia Date: Fri, 26 Mar 2021 18:09:41 +0100 Subject: [PATCH 03/13] Update project files --- README.md | 4 +- docs/pwncat.api.html | 183 ++++++++++++++++++++++++++---------------- docs/pwncat.man.html | 4 +- docs/pwncat.type.html | 114 ++++++++++++++------------ man/pwncat.1 | 6 +- setup.py | 2 +- 6 files changed, 184 insertions(+), 129 deletions(-) diff --git a/README.md b/README.md index 82019fa0..ab54ab71 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ -> [1] mypy type coverage (fully typed: 93.99%)
+> [1] mypy type coverage (fully typed: 94.00%)
> [2] Failing builds do not indicate broken functionality. Integration tests run for multiple hours and break sporadically for various different reasons (network timeouts, unknown cancellations of GitHub Actions, etc): #735, #841
> @@ -155,7 +155,7 @@ tool that works on older and newer machines (hence Python 2+3 compat). Most impo ## :tada: Install -Current version is: **0.1.0** +Current version is: **0.1.1** | [Pip](https://pypi.org/project/pwncat/) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [MacOS](https://formulae.brew.sh/formula/pwncat#default) | |:-:|:-:|:-:|:-:| diff --git a/docs/pwncat.api.html b/docs/pwncat.api.html index 7ce8a8f2..9a61fc6a 100644 --- a/docs/pwncat.api.html +++ b/docs/pwncat.api.html @@ -3,15 +3,17 @@ - + pwncat API documentation - - - - + + + + + +
@@ -155,7 +157,7 @@

Module pwncat

APPNAME = "pwncat" APPREPO = "https://github.com/cytopia/pwncat" -VERSION = "0.1.0" +VERSION = "0.1.1" # Default timeout for timeout-based sys.stdin and socket.recv TIMEOUT_READ_STDIN = 0.05 @@ -1704,13 +1706,20 @@

Module pwncat

except (OSError, socket.error) as error: msg = "Connecting to {}:{} (family {}/{}, {}) failed: {}".format( - addr, port, sock.family, sock_family_name, sock_type_name, error, + addr, + port, + sock.family, + sock_family_name, + sock_type_name, + error, ) raise socket.error(msg) local = sock.getsockname() self.__log.debug( - "Connected from %s:%d", local[0], local[1], + "Connected from %s:%d", + local[0], + local[1], ) self.__log.info( "Connected to %s:%d (family %d/%s, %s)", @@ -3282,9 +3291,7 @@

Module pwncat

# [1/7] Check for termination request if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for IONetworkScanner.producer" - ) + self.log.trace("TERMINATE signal ACK for IONetworkScanner.producer") # type: ignore return addr = self.__targets[family] @@ -3343,7 +3350,9 @@

Module pwncat

yield self.__enc.encode(msg) if banner is None and succ_banner: msg = "[+] {:>5}/{} open ({})".format( - port, self.__sock.get_type_name(sock_type), self.__sock.get_family_name(family), + port, + self.__sock.get_type_name(sock_type), + self.__sock.get_family_name(family), ) yield self.__enc.encode(msg) @@ -3540,7 +3549,8 @@

Module pwncat

# Setting sys.stdin to binary mode fixes that. if hasattr(os, "O_BINARY"): msvcrt.setmode( # type: ignore - sys.stdin.fileno(), os.O_BINARY, # pylint: disable=no-member + sys.stdin.fileno(), + os.O_BINARY, # pylint: disable=no-member ) return sys.stdin.read() # type: ignore @@ -4120,9 +4130,7 @@

Module pwncat

# [1/3] Start available action in a thread for key in self.__actions: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [1]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [1]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -4161,9 +4169,7 @@

Module pwncat

# [2/3] Start available timers in a thread for key in self.__timers: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [2]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [2]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -4184,9 +4190,7 @@

Module pwncat

# [3/3] Start available repeaters in a thread for key in self.__repeaters: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [3]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [3]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -5310,7 +5314,8 @@

Module pwncat

if args.ipv4 and args.ipv6: parser.print_usage() print( - "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), file=sys.stderr, + "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5353,13 +5358,15 @@

Module pwncat

if args.keep_open and (args.udp): parser.print_usage() print( - "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), + file=sys.stderr, ) sys.exit(1) if args.keep_open and not args.listen: parser.print_usage() print( - "%s: error: --keep-open only works with -l/--listen" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open only works with -l/--listen" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5367,7 +5374,8 @@

Module pwncat

if args.reconn != 0 and not connect_mode: parser.print_usage() print( - "%s: error: --reconn only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --reconn only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -5384,7 +5392,8 @@

Module pwncat

if args.udp_sconnect and not connect_mode: parser.print_usage() print( - "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -6044,7 +6053,8 @@

Module pwncat

if not args.zero and len(args.port) > 1: parser.print_usage() print( - "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), file=sys.stderr, + "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -6187,6 +6197,9 @@

Module pwncat

# Run local port-forward # -> listen locally and forward traffic to remote (connect) if mode == "local": + # Enure to re-connect forever during local port forward + cli_opts.reconn = -1 + cli_opts.reconn_wait = 0.0 srv_opts.keep_open = True lhost = args.local.split(":")[0] lport = int(args.local.split(":")[1]) @@ -6225,8 +6238,9 @@

Module pwncat

# -> connect to client, connect to target and proxy traffic in between. if mode == "remote": # TODO: Make the listen address optional! + # Enure to re-connect forever during remote port forward cli_opts.reconn = -1 - cli_opts.reconn_wait = 0.1 + cli_opts.reconn_wait = 0.0 lhost = args.remote.split(":")[0] lport = int(args.remote.split(":")[1]) # Create local and remote client @@ -7047,7 +7061,8 @@

Functions

if not args.zero and len(args.port) > 1: parser.print_usage() print( - "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), file=sys.stderr, + "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -7205,6 +7220,9 @@

Functions

# Run local port-forward # -> listen locally and forward traffic to remote (connect) if mode == "local": + # Enure to re-connect forever during local port forward + cli_opts.reconn = -1 + cli_opts.reconn_wait = 0.0 srv_opts.keep_open = True lhost = args.local.split(":")[0] lport = int(args.local.split(":")[1]) @@ -7243,8 +7261,9 @@

Functions

# -> connect to client, connect to target and proxy traffic in between. if mode == "remote": # TODO: Make the listen address optional! + # Enure to re-connect forever during remote port forward cli_opts.reconn = -1 - cli_opts.reconn_wait = 0.1 + cli_opts.reconn_wait = 0.0 lhost = args.remote.split(":")[0] lport = int(args.remote.split(":")[1]) # Create local and remote client @@ -9283,7 +9302,7 @@

Inherited members

class CNCPythonNotFound -(...) +(*args, **kwargs)

CNC Exception handler.

@@ -12184,9 +12203,7 @@

Args

# [1/7] Check for termination request if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for IONetworkScanner.producer" - ) + self.log.trace("TERMINATE signal ACK for IONetworkScanner.producer") # type: ignore return addr = self.__targets[family] @@ -12245,7 +12262,9 @@

Args

yield self.__enc.encode(msg) if banner is None and succ_banner: msg = "[+] {:>5}/{} open ({})".format( - port, self.__sock.get_type_name(sock_type), self.__sock.get_family_name(family), + port, + self.__sock.get_type_name(sock_type), + self.__sock.get_family_name(family), ) yield self.__enc.encode(msg) @@ -12275,7 +12294,17 @@

Args

# type: () -> None """Stop function that can be called externally to close this instance.""" self.log.trace("SOCK-QUIT signal RAISED in IONetworkScanner.interrupt") # type: ignore - self.ssig.raise_sock_quit() + self.ssig.raise_sock_quit() + + # NOTE: Closing up to 65535 sockets (single thread) takes very very long + # Se we leave this up to Python itself, once the program exits. + # self.log.trace("SOCK-QUIT-CLEANUP: Closing sockets") # type: ignore + # # Double loop to prevent: Dictionary size changed during iteration + # remove = {} + # for key in self.__local_binds: + # remove[key] = self.__local_binds[key] + # for key in remove: + # self.__sock.close(remove[key], key)

Ancestors

    @@ -12340,7 +12369,17 @@

    Methods

    # type: () -> None """Stop function that can be called externally to close this instance.""" self.log.trace("SOCK-QUIT signal RAISED in IONetworkScanner.interrupt") # type: ignore - self.ssig.raise_sock_quit() + self.ssig.raise_sock_quit() + + # NOTE: Closing up to 65535 sockets (single thread) takes very very long + # Se we leave this up to Python itself, once the program exits. + # self.log.trace("SOCK-QUIT-CLEANUP: Closing sockets") # type: ignore + # # Double loop to prevent: Dictionary size changed during iteration + # remove = {} + # for key in self.__local_binds: + # remove[key] = self.__local_binds[key] + # for key in remove: + # self.__sock.close(remove[key], key)
@@ -12382,9 +12421,7 @@

Yields

# [1/7] Check for termination request if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for IONetworkScanner.producer" - ) + self.log.trace("TERMINATE signal ACK for IONetworkScanner.producer") # type: ignore return addr = self.__targets[family] @@ -12443,7 +12480,9 @@

Yields

yield self.__enc.encode(msg) if banner is None and succ_banner: msg = "[+] {:>5}/{} open ({})".format( - port, self.__sock.get_type_name(sock_type), self.__sock.get_family_name(family), + port, + self.__sock.get_type_name(sock_type), + self.__sock.get_family_name(family), ) yield self.__enc.encode(msg) @@ -12635,7 +12674,8 @@

Args

# Setting sys.stdin to binary mode fixes that. if hasattr(os, "O_BINARY"): msvcrt.setmode( # type: ignore - sys.stdin.fileno(), os.O_BINARY, # pylint: disable=no-member + sys.stdin.fileno(), + os.O_BINARY, # pylint: disable=no-member ) return sys.stdin.read() # type: ignore @@ -14768,9 +14808,7 @@

Args

# [1/3] Start available action in a thread for key in self.__actions: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [1]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [1]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -14809,9 +14847,7 @@

Args

# [2/3] Start available timers in a thread for key in self.__timers: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [2]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [2]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -14832,9 +14868,7 @@

Args

# [3/3] Start available repeaters in a thread for key in self.__repeaters: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [3]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [3]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -15116,9 +15150,7 @@

Args

# [1/3] Start available action in a thread for key in self.__actions: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [1]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [1]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -15157,9 +15189,7 @@

Args

# [2/3] Start available timers in a thread for key in self.__timers: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [2]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [2]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -15180,9 +15210,7 @@

Args

# [3/3] Start available repeaters in a thread for key in self.__repeaters: if self.__ssig.has_terminate(): - self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [3]: [%s]", key - ) + self.log.trace("TERMINATE signal ACK for Runner.run [3]: [%s]", key) # type: ignore break # Create Thread object thread = threading.Thread( @@ -15265,7 +15293,6 @@

Args

class Sock -(*args, **kwargs)

Thread-safe singleton Socket wrapper to emulate a module within the same file.

@@ -15864,13 +15891,20 @@

Args

except (OSError, socket.error) as error: msg = "Connecting to {}:{} (family {}/{}, {}) failed: {}".format( - addr, port, sock.family, sock_family_name, sock_type_name, error, + addr, + port, + sock.family, + sock_family_name, + sock_type_name, + error, ) raise socket.error(msg) local = sock.getsockname() self.__log.debug( - "Connected from %s:%d", local[0], local[1], + "Connected from %s:%d", + local[0], + local[1], ) self.__log.info( "Connected to %s:%d (family %d/%s, %s)", @@ -15949,7 +15983,8 @@

Args

# self.__log.trace("Closing %s socket", name) # type: ignore sock.close() except (OSError, socket.error): - pass
+ pass + # self.__log.trace("Could not close %s socket: %s", name, error) # type: ignore

Ancestors

    @@ -16233,7 +16268,8 @@

    Args

    # self.__log.trace("Closing %s socket", name) # type: ignore sock.close() except (OSError, socket.error): - pass + pass + # self.__log.trace("Could not close %s socket: %s", name, error) # type: ignore
@@ -16344,13 +16380,20 @@

Raises

except (OSError, socket.error) as error: msg = "Connecting to {}:{} (family {}/{}, {}) failed: {}".format( - addr, port, sock.family, sock_family_name, sock_type_name, error, + addr, + port, + sock.family, + sock_family_name, + sock_type_name, + error, ) raise socket.error(msg) local = sock.getsockname() self.__log.debug( - "Connected from %s:%d", local[0], local[1], + "Connected from %s:%d", + local[0], + local[1], ) self.__log.info( "Connected to %s:%d (family %d/%s, %s)", @@ -18074,9 +18117,7 @@

T

- - \ No newline at end of file diff --git a/docs/pwncat.man.html b/docs/pwncat.man.html index 99b0dbc2..bae47f21 100644 --- a/docs/pwncat.man.html +++ b/docs/pwncat.man.html @@ -283,8 +283,8 @@

DESCRIPTION UDP): Hide traffic in https packets to fool Firewalls/IDS/IPS.

-

−H [str [str -...]], −−header [str [str ...]]

+

−H [str ...], +−−header [str ...]

Add HTTP headers to your request when using −−http(s).

diff --git a/docs/pwncat.type.html b/docs/pwncat.type.html index 6a43fa7f..83271d3a 100644 --- a/docs/pwncat.type.html +++ b/docs/pwncat.type.html @@ -14,13 +14,13 @@

Mypy Type Check Coverage Summary

Total -6.16% imprecise -6352 LOC +6.00% imprecise +6364 LOC bin/pwncat -6.16% imprecise -6352 LOC +6.00% imprecise +6364 LOC @@ -6387,6 +6387,18 @@

pwncat

6350 6351 6352 +6353 +6354 +6355 +6356 +6357 +6358 +6359 +6360 +6361 +6362 +6363 +6364
#!/usr/bin/env python3
 """pwncat."""
@@ -6518,7 +6530,7 @@ 

pwncat

APPNAME = "pwncat" APPREPO = "https://github.com/cytopia/pwncat" -VERSION = "0.1.0" +VERSION = "0.1.1" # Default timeout for timeout-based sys.stdin and socket.recv TIMEOUT_READ_STDIN = 0.05 @@ -7897,10 +7909,8 @@

pwncat

# [4/4] Resolve try: - infos = socket.getaddrinfo(host, port, family, socktype, proto, flags) - addr = str(infos[0][4][0]) + infos = socket.getaddrinfo(host, port, family, socktype, proto, flags) + addr = str(infos[0][4][0]) self.__log.debug("Resolved %s host: %s", self.get_family_name(family), addr) return addr @@ -8141,11 +8151,9 @@

pwncat

) # Ensure to use connect() protocol independent + info = socket.getaddrinfo(addr, port, sock.family, sock.type, sock.proto) info = socket.getaddrinfo(addr, port, sock.family, sock.type, sock.proto) - sock.connect(info[0][4]) +Omitted Generics (x1)"> sock.connect(info[0][4]) # UDP stateful connect # A UDP client doesn't know if the connect() was successful, so the trick @@ -8176,14 +8184,21 @@

pwncat

except (OSError, socket.error) as error: msg = "Connecting to {}:{} (family {}/{}, {}) failed: {}".format( - addr, port, sock.family, sock_family_name, sock_type_name, error, + addr, + port, + sock.family, + sock_family_name, + sock_type_name, + error, ) raise socket.error(msg) local = sock.getsockname() self.__log.debug( - "Connected from %s:%d", local[0], local[1], + "Connected from %s:%d", + local[0], + local[1], ) self.__log.info( @@ -9828,9 +9843,7 @@

pwncat

# [1/7] Check for termination request if self.__ssig.has_terminate(): self.log.trace( # type: ignore - "TERMINATE signal ACK for IONetworkScanner.producer" - ) +Error (x2)"> self.log.trace("TERMINATE signal ACK for IONetworkScanner.producer") # type: ignore return addr = self.__targets[family] @@ -9896,7 +9909,9 @@

pwncat

if banner is None and succ_banner: msg = "[+] {:>5}/{} open ({})".format( port, self.__sock.get_type_name(sock_type), self.__sock.get_family_name(family), +Explicit (x1)"> port, + self.__sock.get_type_name(sock_type), + self.__sock.get_family_name(family), ) yield self.__enc.encode(msg) @@ -9917,8 +9932,7 @@

pwncat

except IOError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another broken pipe at shutdown - devnull = os.open(os.devnull, os.O_WRONLY) + devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) finally: self.__screen_lock.release() @@ -10049,8 +10063,7 @@

pwncat

except IOError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another broken pipe at shutdown - devnull = os.open(os.devnull, os.O_WRONLY) + devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) def interrupt(self): @@ -10109,7 +10122,8 @@

pwncat

Explicit (x1)"> if hasattr(os, "O_BINARY"): msvcrt.setmode( # type: ignore - sys.stdin.fileno(), os.O_BINARY, # pylint: disable=no-member + sys.stdin.fileno(), + os.O_BINARY, # pylint: disable=no-member ) return sys.stdin.read() # type: ignore @@ -10166,7 +10180,6 @@

pwncat

env = os.environ.copy() try: self.proc = Popen( self.__opts.executable, stdin=PIPE, @@ -10227,7 +10240,6 @@

pwncat

self.log.error("COMMAND-EOF restarting: %s", self.__opts.executable) self.proc = Popen( self.__opts.executable, stdin=PIPE, @@ -10733,9 +10745,7 @@

pwncat

for key in self.__actions: if self.__ssig.has_terminate(): self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [1]: [%s]", key - ) +Error (x2)"> self.log.trace("TERMINATE signal ACK for Runner.run [1]: [%s]", key) # type: ignore break # Create Thread object for key in self.__timers: if self.__ssig.has_terminate(): self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [2]: [%s]", key - ) +Error (x2)"> self.log.trace("TERMINATE signal ACK for Runner.run [2]: [%s]", key) # type: ignore break # Create Thread object for key in self.__repeaters: if self.__ssig.has_terminate(): self.log.trace( # type: ignore - "TERMINATE signal ACK for Runner.run [3]: [%s]", key - ) +Error (x2)"> self.log.trace("TERMINATE signal ACK for Runner.run [3]: [%s]", key) # type: ignore break # Create Thread object except IOError: # Python flushes standard streams on exit; redirect remaining output # to devnull to avoid another broken pipe at shutdown - devnull = os.open(os.devnull, os.O_WRONLY) + devnull = os.open(os.devnull, os.O_WRONLY) os.dup2(devnull, sys.stdout.fileno()) # -------------------------------------------------------------------------- @@ -11563,8 +11568,8 @@

pwncat

first = True data = [] # type: List[str] - with open(lpath, "r") as fhandle: + with open(lpath, "r") as fhandle: lines = fhandle.readlines() count = len(lines) curr = 1 @@ -11824,11 +11829,10 @@

pwncat

def type_file_content(value): # type: (str) -> str """Check argument for valid file content (file must exist and be readable).""" - if not os.path.isfile(value): + if not os.path.isfile(value): raise argparse.ArgumentTypeError("File not found: %s" % value) - fhandle = open(value, mode="r") + fhandle = open(value, mode="r") script = fhandle.read() fhandle.close() return script @@ -11969,7 +11973,8 @@

pwncat

Explicit (x3)"> if args.ipv4 and args.ipv6: parser.print_usage() print( - "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), file=sys.stderr, + "%s: error: -4 and -6 are mutually exclusive" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -12017,14 +12022,16 @@

pwncat

Explicit (x3)"> if args.keep_open and (args.udp): parser.print_usage() print( - "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open mutually excl. with -u/--udp" % (APPNAME), + file=sys.stderr, ) sys.exit(1) if args.keep_open and not args.listen: parser.print_usage() print( - "%s: error: --keep-open only works with -l/--listen" % (APPNAME), file=sys.stderr, + "%s: error: --keep-open only works with -l/--listen" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -12033,7 +12040,8 @@

pwncat

Explicit (x3)"> if args.reconn != 0 and not connect_mode: parser.print_usage() print( - "%s: error: --reconn only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --reconn only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -12052,7 +12060,8 @@

pwncat

Explicit (x2)"> if args.udp_sconnect and not connect_mode: parser.print_usage() print( - "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), file=sys.stderr, + "%s: error: --udp-sconnect only works in connect mode" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -12766,7 +12775,8 @@

pwncat

Explicit (x2)"> if not args.zero and len(args.port) > 1: parser.print_usage() print( - "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), file=sys.stderr, + "%s: error: Only Zero-I/O mode supports multiple ports" % (APPNAME), + file=sys.stderr, ) sys.exit(1) @@ -12953,6 +12963,9 @@

pwncat

# Run local port-forward # -> listen locally and forward traffic to remote (connect) if mode == "local": + # Enure to re-connect forever during local port forward + cli_opts.reconn = -1 + cli_opts.reconn_wait = 0.0 srv_opts.keep_open = True lhost = args.local.split(":")[0] @@ -12999,8 +13012,9 @@

pwncat

# -> connect to client, connect to target and proxy traffic in between. if mode == "remote": # TODO: Make the listen address optional! + # Enure to re-connect forever during remote port forward cli_opts.reconn = -1 - cli_opts.reconn_wait = 0.1 + cli_opts.reconn_wait = 0.0 lhost = args.remote.split(":")[0] Date: Fri, 26 Mar 2021 18:44:21 +0100 Subject: [PATCH 04/13] CI: Use latest checkout action --- .github/workflows/building.yml | 2 +- .github/workflows/code-black.yml | 2 +- .github/workflows/code-mypy.yml | 2 +- .github/workflows/code-pycodestyle.yml | 2 +- .github/workflows/code-pydocstyle.yml | 2 +- .github/workflows/code-pylint.yml | 2 +- .github/workflows/linting.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/building.yml b/.github/workflows/building.yml index baaa38a5..81bfe52a 100644 --- a/.github/workflows/building.yml +++ b/.github/workflows/building.yml @@ -28,7 +28,7 @@ jobs: name: "[${{ matrix.version }}]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: Build source distribution run: | diff --git a/.github/workflows/code-black.yml b/.github/workflows/code-black.yml index a019ca30..89b09db5 100644 --- a/.github/workflows/code-black.yml +++ b/.github/workflows/code-black.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: "${{ matrix.target }}" run: | diff --git a/.github/workflows/code-mypy.yml b/.github/workflows/code-mypy.yml index 93b7c9f2..c288d1aa 100644 --- a/.github/workflows/code-mypy.yml +++ b/.github/workflows/code-mypy.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: "${{ matrix.target }}" run: | diff --git a/.github/workflows/code-pycodestyle.yml b/.github/workflows/code-pycodestyle.yml index 91a0e14e..1101a3d3 100644 --- a/.github/workflows/code-pycodestyle.yml +++ b/.github/workflows/code-pycodestyle.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: "${{ matrix.target }}" run: | diff --git a/.github/workflows/code-pydocstyle.yml b/.github/workflows/code-pydocstyle.yml index a16f7ccd..090b7139 100644 --- a/.github/workflows/code-pydocstyle.yml +++ b/.github/workflows/code-pydocstyle.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: "${{ matrix.target }}" run: | diff --git a/.github/workflows/code-pylint.yml b/.github/workflows/code-pylint.yml index 7ee85cd3..ac63a0eb 100644 --- a/.github/workflows/code-pylint.yml +++ b/.github/workflows/code-pylint.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: "${{ matrix.target }}" run: | diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 3ceb4ac2..250508e5 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -23,7 +23,7 @@ jobs: name: "[ ${{ matrix.target }} ]" steps: - name: Checkout repository - uses: actions/checkout@master + uses: actions/checkout@v2 - name: Lint files run: | From 7ab387172190b03b8b11b63a03930c89a26c89fa Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 12:05:59 +0100 Subject: [PATCH 05/13] Ensure pylint compat with version prior 2.6.0 --- setup.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 74d55a85..06bfc235 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,9 +25,9 @@ max-line-length = 100 # useless-object-inheritance: don't lint useless-object-inheritance to stary Python2/3 compatible # bad-continuation: let Python Black take care of this # unidiomatic-typecheck: Need to check if int or bool and this doesnt work with isinstance() -disable = useless-object-inheritance, bad-continuation, unidiomatic-typecheck +disable = useless-object-inheritance, bad-continuation, unidiomatic-typecheck, super-with-arguments, raise-missing-from, use-a-generator max-branches = 30 -max-statements = 121 +max-statements = 125 max-args = 15 max-attributes = 13 max-locals = 37 From 164f59fc426d90a9b2c59190c81884352482d708 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 12:06:20 +0100 Subject: [PATCH 06/13] Always show linter versions --- Makefile | 55 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index f4182c0c..4598c002 100644 --- a/Makefile +++ b/Makefile @@ -146,9 +146,11 @@ code: _code-mypy .PHONY: _code-pycodestyle _code-pycodestyle: - @echo "# -------------------------------------------------------------------- #" - @echo "# Check pycodestyle" - @echo "# -------------------------------------------------------------------- #" + @V="$$( docker run --rm cytopia/pycodestyle --version | head -1 )"; \ + echo "# -------------------------------------------------------------------- #"; \ + echo "# Check pycodestyle: $${V}"; \ + echo "# -------------------------------------------------------------------- #" + @# docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data --entrypoint= cytopia/pycodestyle sh -c ' \ mkdir -p /tmp \ && cp $(BINPATH)$(BINNAME) /tmp/$(BINNAME).py \ @@ -156,9 +158,11 @@ _code-pycodestyle: .PHONY: _code-pydocstyle _code-pydocstyle: - @echo "# -------------------------------------------------------------------- #" - @echo "# Check pycodestyle" - @echo "# -------------------------------------------------------------------- #" + @V="$$( docker run --rm cytopia/pydocstyle --version | head -1 )"; \ + echo "# -------------------------------------------------------------------- #"; \ + echo "# Check pydocstyle: $${V}"; \ + echo "# -------------------------------------------------------------------- #" + @# docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data --entrypoint= cytopia/pydocstyle sh -c ' \ mkdir -p /tmp \ && cp $(BINPATH)$(BINNAME) /tmp/$(BINNAME).py \ @@ -166,24 +170,39 @@ _code-pydocstyle: .PHONY: _code-pylint _code-pylint: - @echo "# -------------------------------------------------------------------- #" - @echo "# Check pylint" - @echo "# -------------------------------------------------------------------- #" - docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data cytopia/pylint --rcfile=setup.cfg $(BINPATH)$(BINNAME) + @V="$$( docker run --rm cytopia/pylint --version | head -1 )"; \ + echo "# -------------------------------------------------------------------- #"; \ + echo "# Check pylint: $${V}"; \ + echo "# -------------------------------------------------------------------- #" + @# + docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data --entrypoint= cytopia/pylint sh -c ' \ + mkdir -p /tmp \ + && cp $(BINPATH)$(BINNAME) /tmp/$(BINNAME).py \ + && pylint --rcfile=setup.cfg /tmp/$(BINNAME).py' .PHONY: _code-black _code-black: - @echo "# -------------------------------------------------------------------- #" - @echo "# Check Python Black" - @echo "# -------------------------------------------------------------------- #" - docker run --rm $$(tty -s && echo "-it" || echo) -v ${PWD}:/data cytopia/black -l 100 --check --diff $(BINPATH)$(BINNAME) + @V="$$( docker run --rm cytopia/black --version | head -1 )"; \ + echo "# -------------------------------------------------------------------- #"; \ + echo "# Check Python Black: $${V}"; \ + echo "# -------------------------------------------------------------------- #" + @# + docker run --rm $$(tty -s && echo "-it" || echo) -v ${PWD}:/data --entrypoint= cytopia/black sh -c ' \ + mkdir -p /tmp \ + && cp $(BINPATH)$(BINNAME) /tmp/$(BINNAME).py \ + && black -l 100 --check --diff /tmp/$(BINNAME).py' .PHONY: _code-mypy _code-mypy: - @echo "# -------------------------------------------------------------------- #" - @echo "# Check mypy" - @echo "# -------------------------------------------------------------------- #" - docker run --rm $$(tty -s && echo "-it" || echo) -v ${PWD}:/data cytopia/mypy --config-file setup.cfg $(BINPATH)$(BINNAME) + @V="$$( docker run --rm cytopia/mypy --version | head -1 )"; \ + echo "# -------------------------------------------------------------------- #"; \ + echo "# Check Mypy: $${V}"; \ + echo "# -------------------------------------------------------------------- #" + @# + docker run --rm $$(tty -s && echo "-it" || echo) -v ${PWD}:/data --entrypoint= cytopia/mypy sh -c ' \ + mkdir -p /tmp \ + && cp $(BINPATH)$(BINNAME) /tmp/$(BINNAME).py \ + && mypy --config-file setup.cfg /tmp/$(BINNAME).py' # ------------------------------------------------------------------------------------------------- From 34ca02fd5e2e72db0358fab615dc12c19a31316f Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 12:10:05 +0100 Subject: [PATCH 07/13] Adjust dev status --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3b073685..d87741ee 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ # https://pypi.org/classifiers/ # # How mature is this project - "Development Status :: 3 - Alpha", + "Development Status :: 5 - Production/Stable", # Indicate who your project is intended for "Intended Audience :: Developers", "Intended Audience :: Information Technology", From 8ce2ad75169d874441e5bdbd4694307a408fb03b Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 12:17:43 +0100 Subject: [PATCH 08/13] Update tools --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ab54ab71..c3adfc72 100644 --- a/README.md +++ b/README.md @@ -1400,6 +1400,7 @@ Below is a list of sec tools and docs I am maintaining. | **[pwncat]** | Pivoting | Python 2+3 | Cross-platform netcat on steroids | | **[badchars]** | Reverse Engineering | Python 2+3 | Badchar generator | | **[fuzza]** | Reverse Engineering | Python 2+3 | TCP fuzzing tool | +| **[docker-dvwa]** | Playground | PHP | DVWA with local priv esc challenges | [offsec]: https://github.com/cytopia/offsec [header-fuzz]: https://github.com/cytopia/header-fuzz @@ -1408,6 +1409,7 @@ Below is a list of sec tools and docs I am maintaining. [pwncat]: https://github.com/cytopia/pwncat [badchars]: https://github.com/cytopia/badchars [fuzza]: https://github.com/cytopia/fuzza +[docker-dvwa]: https://github.com/cytopia/docker-dvwa ## :octocat: Contributing From b726d1980634dc496077f38501e401e85c27a2b8 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 13:41:18 +0100 Subject: [PATCH 09/13] Update methods of installation --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c3adfc72..833c3912 100644 --- a/README.md +++ b/README.md @@ -157,10 +157,20 @@ tool that works on older and newer machines (hence Python 2+3 compat). Most impo Current version is: **0.1.1** -| [Pip](https://pypi.org/project/pwncat/) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [MacOS](https://formulae.brew.sh/formula/pwncat#default) | -|:-:|:-:|:-:|:-:| -| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/python.png)](https://pypi.org/project/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png)](https://aur.archlinux.org/packages/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png)](https://www.blackarch.org/tools.html) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png)](https://formulae.brew.sh/formula/pwncat#default) | -| `pip install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `brew install pwncat` | +#### Generic + +| [Pip](https://pypi.org/project/pwncat/) | +|:-:| +| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/python.png)](https://pypi.org/project/pwncat/) | +| `pip install pwncat` | + + +#### OS specific + +| [MacOS](https://formulae.brew.sh/formula/pwncat#default) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [Fedora](https://src.fedoraproject.org/rpms/pwncat) | [Kali Linux](https://gitlab.com/kalilinux/packages/pwncat) | +|:-:|:-:|:-:|:-:|:-:| +| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png)](https://formulae.brew.sh/formula/pwncat#default) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png)](https://aur.archlinux.org/packages/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png)](https://www.blackarch.org/tools.html) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/fedora.png)](https://src.fedoraproject.org/rpms/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/kali.png)](https://gitlab.com/kalilinux/packages/pwncat) | +| `brew install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `yum install pwncat` | `apt install pwncat` | ## :coffee: TL;DR From 501ef8ee616cceb9b5067afae3d07579bddba032 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 13:52:06 +0100 Subject: [PATCH 10/13] Update project maturity --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d87741ee..2a4f8f05 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ # https://pypi.org/classifiers/ # # How mature is this project - "Development Status :: 5 - Production/Stable", + "Development Status :: 4 - Beta", # Indicate who your project is intended for "Intended Audience :: Developers", "Intended Audience :: Information Technology", From d490a4814a704b3462d48da3a79b473f9c15cc2a Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 14:42:51 +0100 Subject: [PATCH 11/13] Update install methods --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 833c3912..c0067904 100644 --- a/README.md +++ b/README.md @@ -167,10 +167,10 @@ Current version is: **0.1.1** #### OS specific -| [MacOS](https://formulae.brew.sh/formula/pwncat#default) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [Fedora](https://src.fedoraproject.org/rpms/pwncat) | [Kali Linux](https://gitlab.com/kalilinux/packages/pwncat) | -|:-:|:-:|:-:|:-:|:-:| -| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png)](https://formulae.brew.sh/formula/pwncat#default) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png)](https://aur.archlinux.org/packages/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png)](https://www.blackarch.org/tools.html) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/fedora.png)](https://src.fedoraproject.org/rpms/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/kali.png)](https://gitlab.com/kalilinux/packages/pwncat) | -| `brew install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `yum install pwncat` | `apt install pwncat` | +| [MacOS](https://formulae.brew.sh/formula/pwncat#default) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [CentOS](https://pkgs.org/download/pwncat) | [Fedora](https://src.fedoraproject.org/rpms/pwncat) | [Kali Linux](https://gitlab.com/kalilinux/packages/pwncat) | +|:-:|:-:|:-:|:-:|:-:|:-:| +| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png)](https://formulae.brew.sh/formula/pwncat#default) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png)](https://aur.archlinux.org/packages/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png)](https://www.blackarch.org/tools.html) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/centos.png)](https://pkgs.org/download/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/fedora.png)](https://src.fedoraproject.org/rpms/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/kali.png)](https://gitlab.com/kalilinux/packages/pwncat) | +| `brew install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `yum install pwncat` | `yum install pwncat` | `apt install pwncat` | ## :coffee: TL;DR From a3bc944d7f8bfb4c8752633e05076d52a7f4993b Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 15:05:05 +0100 Subject: [PATCH 12/13] Update website --- docs/index.html | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/index.html b/docs/index.html index c74fbd1c..22a19173 100644 --- a/docs/index.html +++ b/docs/index.html @@ -158,6 +158,15 @@

Pip

pip install pwncat

+
+
+

MacOS

+

+

brew install pwncat

+
+
+ +

ArchLinux

@@ -174,9 +183,23 @@

BlackArch

-

MacOS

-

-

brew install pwncat

+

CentOS

+

+

yum install pwncat

+
+
+
+
+

Fedora

+

+

yum install pwncat

+
+
+
+
+

Kali Linux

+

+

apt install pwncat

From 8c14906e8f42cc32cc4bdddd4b4a9129bd6bf7bf Mon Sep 17 00:00:00 2001 From: cytopia Date: Sat, 27 Mar 2021 17:33:13 +0100 Subject: [PATCH 13/13] Update install methods --- README.md | 36 ++++++++++++++++++++++++++++++++---- docs/index.html | 38 +++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c0067904..51cf2ab5 100644 --- a/README.md +++ b/README.md @@ -167,10 +167,38 @@ Current version is: **0.1.1** #### OS specific -| [MacOS](https://formulae.brew.sh/formula/pwncat#default) | [ArchLinux](https://aur.archlinux.org/packages/pwncat/) | [BlackArch](https://www.blackarch.org/tools.html) | [CentOS](https://pkgs.org/download/pwncat) | [Fedora](https://src.fedoraproject.org/rpms/pwncat) | [Kali Linux](https://gitlab.com/kalilinux/packages/pwncat) | -|:-:|:-:|:-:|:-:|:-:|:-:| -| [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png)](https://formulae.brew.sh/formula/pwncat#default) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png)](https://aur.archlinux.org/packages/pwncat/) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png)](https://www.blackarch.org/tools.html) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/centos.png)](https://pkgs.org/download/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/fedora.png)](https://src.fedoraproject.org/rpms/pwncat) | [![](https://raw.githubusercontent.com/cytopia/icons/master/64x64/kali.png)](https://gitlab.com/kalilinux/packages/pwncat) | -| `brew install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `yum install pwncat` | `yum install pwncat` | `apt install pwncat` | +| **[MacOS][mac_lnk]** | **[Arch Linux][arch_lnk]** | **[BlackArch][barch_lnk]** | **[CentOS][centos_lnk]** | +|:---------------------------:|:--------------------------:|:----------------------------:|:---------------------------:| +| [![mac_img]][mac_lnk] | [![arch_img]][arch_lnk] | [![barch_img]][barch_lnk] | [![centos_img]][centos_lnk] | +| `brew install pwncat` | `yay -S pwncat` | `pacman -S pwncat` | `yum install pwncat` | +| **[Fedora][fedora_lnk]** | **[Kali Linux][kali_lnk]** | **[Parrot OS][parrot_lnk]** | **[Pentoo][pentoo_lnk]** | +| [![fedora_img]][fedora_lnk] | [![kali_img]][kali_lnk] | [![parrot_img]][parrot_lnk] | [![pentoo_img]][pentoo_lnk] | +| `dnf install pwncat` | `apt install pwncat` | `apt install pwncat` | `net-analyzer/pwncat` | + +[mac_lnk]: https://formulae.brew.sh/formula/pwncat#default +[mac_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/osx.png + +[arch_lnk]: https://aur.archlinux.org/packages/pwncat/ +[arch_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/archlinux.png + +[barch_lnk]: https://www.blackarch.org/tools.html +[barch_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/blackarch.png + +[centos_lnk]: https://pkgs.org/download/pwncat +[centos_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/centos.png + +[fedora_lnk]: https://src.fedoraproject.org/rpms/pwncat +[fedora_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/fedora.png + +[kali_lnk]: https://gitlab.com/kalilinux/packages/pwncat +[kali_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/kali.png + +[parrot_lnk]: https://repology.org/project/pwncat/versions +[parrot_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/parrot.png + +[pentoo_lnk]: https://repology.org/project/pwncat/versions +[pentoo_img]: https://raw.githubusercontent.com/cytopia/icons/master/64x64/pentoo.png + ## :coffee: TL;DR diff --git a/docs/index.html b/docs/index.html index 22a19173..ae0596f9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -158,6 +158,8 @@

Pip

pip install pwncat

+ +

MacOS

@@ -165,22 +167,13 @@

MacOS

brew install pwncat

-
-
-

ArchLinux

+

Arch Linux

yay -S pwncat

-
-
-

BlackArch

-

-

pacman -S pwncat

-
-

CentOS

@@ -192,7 +185,16 @@

CentOS

Fedora

-

yum install pwncat

+

dnf install pwncat

+
+
+
+
+
+
+

BlackArch

+

+

pacman -S pwncat

@@ -202,6 +204,20 @@

Kali Linux

apt install pwncat

+
+
+

Parrot OS

+

+

apt install pwncat

+
+
+
+
+

Pentoo

+

+

net-analyzer/pwncat

+
+