pwncat.channel package¶
Channels represent the basic communication object within pwncat. Each channel abstracts a communication method with a target. By default, pwncat implements a few standard channels: socket bind/connect and ssh.
A channel largely mimics a standard socket, however exact compatibility with sockets was not the goal. Instead, it provides a low-level communication channel between the target and the attacker. Channels make no assumption about protocol of the C2 connection. This is the platform’s job.
As a user, you will never directly create a channel. Instead, you will call
pwncat.manager.Manager.create_session()
. This method will in turn
locate an appropriate channel based on your arguments, and pass all arguments
to the constructor for the appropriate channel type.
- class pwncat.channel.Channel(host: str, port: Optional[int] = None, user: Optional[str] = None, password: Optional[str] = None, **kwargs)¶
Bases:
abc.ABC
Abstract interation with a remote victim. This class acts similarly to a socket object. In the common cases, it simply wraps a socket object. Some methods have default implementations, but many are required to be implemented. At a minimum, the following methods/properties must be implemented:
connected
send
recv
recvinto
drain
close
The
peek
andunrecv
methods have default implementations which buffer some data in memory. If using the default implementations of these methods, you should be prepared to read first from self.peek_buffer prior to making downstream recv requests.In general, direct connections are made during
__init__
. If you are implementing a listener, theconnect
method can be used to wait for/accept the final connection. It is called just before instantiating the resulting pwncat session. At all times,connected
should reflect the state of the underlying data channel. In the case of listeners,connected
should only be true afterconnect
is called. Theclose
method should setconnected
to false.During initialization, you can take any keyword arguments you require to connect. However, you should also always accept a
**kwargs
argument. Parameters are passed dynamically frompwncat.channel.create
and may be attempted with extra arguments you don’t need.- abstract close()¶
Close this channel. This method should do nothing if the
connected
property returns False.
- connect()¶
Utilize the parameters provided at initialization to connect to the remote host. This is mainly used for channels which listen for a connection. In that case, __init__ creates the listener while connect actually establishes a connection. For direct connection-type channels, all logic can be implemented in the constructor.
This method is called when creating a platform around this channel to instantiate the session.
- abstract property connected¶
Check if this channel is connected. This should return false prior to an established connection, and may return true prior to the
connect
method being called for some channel types.
- drain()¶
Drain any buffered data until there is nothing left
- makefile(mode: str, bufsize: int = - 1, sof: Optional[bytes] = None, eof: Optional[bytes] = None)¶
Create a file-like object which acts on this channel. If the mode is “r”, and
sof
andeof
are specified, the file will return data following a line containing onlysof
and up to a line containing onlyeof
. In “w” mode, the file has no bounds and will never hiteof
.- Parameters
mode (str) – a mode string similar to open
sof (bytes) – a string of bytes which indicate the start of file
eof (bytes) – a string of bytes which indicate the end of file
- Returns
A file-like object suitable for the specified mode
- Return type
Union[BinaryIO, TextIO]
- Raises
ValueError: both “r” and “w” were specified or invalid characters were found in mode
- peek(count: Optional[int] = None, timeout: Optional[float] = None)¶
Receive data from the victim and leave the data in the recv buffer. This is a default implementation which uses an internal
bytes
buffer within the channel to simulate a peek. You can override this method if your underlying transport supports realpeek
operations. If the defaultpeek
implementation is used,recv
should readself.peek_buffer
prior to calling the underlyingrecv
.The
timeout
argument works differently from other methods. If no timeout is specified, then the method returns immediately and may return no data. If a timeout is provided, then the method will wait up totimeout
seconds for at least one byte of data not to exceedcount
bytes.- Parameters
count (int) – maximum number of bytes to receive (default: unlimited)
- Returns
data that was received
- Return type
bytes
- abstract recv(count: Optional[int] = None) bytes ¶
Receive data from the remote shell
If your channel class does not implement
peek
, a default implementation is provided. If you provide a custom recv, but use the defaultpeek()
you must return data fromself.peek_buffer
prior to callrecv
.- Parameters
count (int) – maximum number of bytes to receive (default: unlimited)
- Returns
the data that was received
- Return type
bytes
- recvinto(b)¶
- recvline(timeout: Optional[float] = None) bytes ¶
Receive data until a newline is received. The newline is not stripped. This is a default implementation that utilizes the
recvuntil
method.- Parameters
timeout (float) – a timeout in seconds for the recv
- Return type
bytes
- recvuntil(needle: bytes, timeout: Optional[float] = None) bytes ¶
Receive data until the specified string of bytes is found is found. The needle is not stripped from the data. This is a default implementation which utilizes the
recv
method. You can override this if your underlying transport provides a better implementation.- Parameters
needle (bytes) – the bytes to wait for
timeout (Optional[float]) – a timeout in seconds (default: 30s)
- Returns
the bytes that were read
- Return type
bytes
- abstract send(data: bytes)¶
Send data to the remote shell. This is a blocking call that only returns after all data is sent.
- Parameters
data (bytes) – the data to send to the victim
- Return type
None
- sendline(data: bytes, end: bytes = b'\n')¶
Send data followed by an ending character. If no ending character is specified, a new line is used. This is a blocking call.
- Parameters
data (bytes) – the data to send to the victim
end (bytes) – the bytes to append
- Return type
None
- unrecv(data: bytes)¶
Place the given bytes on a buffer to be returned next by recv. This method utilizes the internal
peek
buffer. Therefore, if you implement a custompeek
method, you must also implementunrecv
.- Parameters
data (bytes) – the data to place on the incoming buffer
- Return type
None
- exception pwncat.channel.ChannelClosed(ch)¶
Bases:
pwncat.channel.ChannelError
A channel was closed unexpectedly during communication. This exception provides a
cleanup()
method which will cleanup the channel within the manager to ensure no further errors occur. This method is normally called by the manager itself upon catching the exception, but you should call this method if you intercept and do not re-throw the exception.- Parameters
ch (Channel) – the channel which caused the exception
- cleanup(manager: pwncat.manager.Manager)¶
Cleanup this channel from the manager
- exception pwncat.channel.ChannelError(ch, msg='generic channel failure')¶
Bases:
Exception
Generic failure of a channel operation.
- Parameters
ch (Channel) – the channel which caused the exception
msg (str) – a message describing the failure
- class pwncat.channel.ChannelFile(channel: pwncat.channel.Channel, mode: str, sof: Optional[bytes] = None, eof: Optional[bytes] = None, on_close=None)¶
Bases:
io.RawIOBase
Wrap a channel in a file-like object. Mainly used for process IO by the platform wrappers. It enables platforms to quickly create a file-like object which is bounded by a delimeter and can be returned to the user safely. You will not normally create this class directly, but should use the func:Channel.makefile` method instead.
- Parameters
channel (Channel) – the channel to which we bind the file
mode (str) – a file mode (e.g. “r” or “w”)
sof (Optional[bytes]) – start of file delimeter; we will recv until this before returning.
eof (Optional[bytes]) – end of file delimeter; eof will be set after seeing this bytestr
on_close (Callable[[Channel], None]) – a method to call before closing the file
- property blocking: bool¶
Indicates whether to act like a blocking file or not.
- close()¶
Close the file for reading/writing. This method calls the on_close hook.
- readable() bool ¶
Test if this is a readable file.
- readall()¶
Read all data until EOF
- readinto(b: Union[memoryview, bytearray])¶
Read as much data as possible into the given bytearray or memory view.
- Parameters
b (Union[memoryview, bytearray]) – the buffer data into
- writable() bool ¶
Test if this is writable file.
- write(data: bytes)¶
Write the given data to the channel
- Parameters
data (bytes) – the data to write to the channel
- exception pwncat.channel.ChannelTimeout(ch, data: bytes)¶
Bases:
pwncat.channel.ChannelError
A timeout was reached while reading or writing a channel.
- Parameters
data (bytes) – the data read before the timeout occurred
- pwncat.channel.create(protocol: Optional[str] = None, **kwargs) pwncat.channel.Channel ¶
Create a new channel with the class provided by a registered channel protocol. Some assumptions are made if the protocol is not specified. For example, if no username or password are specified, then either bind or connect protocols are assumed. If a username is specified, the ssh protocol is assumed. In any case, with no protocol, a reconnect is attempted first.
- Parameters
protocol (Optional[str]) – the name of the register channel protocol (e.g. ssh, bind, connect)
- Returns
A newly connected channel
- Return type
- Raises
- ChannelError: if the victim cannot be reached via the specified
protocol
- pwncat.channel.find(name: str) Type[pwncat.channel.Channel] ¶
Retrieve the channel class for the specified name.
- Parameters
name (str) – the name of the channel you’d like
- Returns
the channel class
- Return type
Channel Class Object
- pwncat.channel.register(name: str, channel_class: Type[pwncat.channel.Channel])¶
Register a new channel class with
pwncat
.- Parameters
name (str) – the name which this channel will be referenced by.
channel_class – A class object implementing the channel interface.