pwnypack.flow – Communication

The Flow module lets you connect to processes or network services using a unified API. It is primarily designed for synchronous communication flows.

It is based around the central Flow class which uses a Channel to connect to a process. The Flow class then uses the primitives exposed by the Channel to provide a high level API for reading/receiving and writing/sending data.

Examples

>>> from pwny import *
>>> f = Flow.connect_tcp('ced.pwned.systems', 80)
>>> f.writelines([
...     b'GET / HTTP/1.0',
...     b'Host: ced.pwned.systems',
...     b'',
... ])
>>> line = f.readline().strip()
>>> print(line == b'HTTP/1.0 200 OK')
True
>>> f.until(b'\r\n\r\n')
>>> f.read_eof(echo=True)
... lots of html ...
>>> from pwny import *
>>> f = Flow.execute('cat')
>>> f.writeline(b'hello')
>>> f.readline(echo=True)
class pwnypack.flow.ProcessChannel(executable, argument..., redirect_stderr=False)

Bases: object

This channel type allows controlling processes. It uses python’s subprocess.Popen class to execute a process and allows you to communicate with it.

Parameters:
  • executable (str) – The executable to start.
  • argument... (list of str) – The arguments to pass to the executable.
  • redirect_stderr (bool) – Whether to also capture the output of stderr.
close()

Wait for the subprocess to exit.

fileno()

Return the file descriptor number for the stdout channel of this process.

kill()

Terminate the subprocess.

read(n)

Read n bytes from the subprocess’ output channel.

Parameters:n (int) – The number of bytes to read.
Returns:n bytes of output.
Return type:bytes
Raises:EOFError – If the process exited.
write(data)

Write n bytes to the subprocess’ input channel.

Parameters:data (bytes) – The data to write.
Raises:EOFError – If the process exited.
class pwnypack.flow.SocketChannel(sock)

Bases: object

This channel type allows controlling sockets.

Parameters:socket (socket.socket) – The (already connected) socket to control.
close()

Close the socket gracefully.

fileno()

Return the file descriptor number for the socket.

kill()

Shut down the socket immediately.

read(n)

Receive n bytes from the socket.

Parameters:n (int) – The number of bytes to read.
Returns:n bytes read from the socket.
Return type:bytes
Raises:EOFError – If the socket was closed.
write(data)

Send n bytes to socket.

Parameters:data (bytes) – The data to send.
Raises:EOFError – If the socket was closed.
class pwnypack.flow.TCPClientSocketChannel(host, port)

Bases: pwnypack.flow.SocketChannel

Convenience subclass of SocketChannel that allows you to connect to a TCP hostname / port pair easily.

Parameters:
  • host (str) – The hostname or IP address to connect to.
  • port (int) – The port number to connect to.
class pwnypack.flow.Flow(channel, echo=False)

Bases: object

The core class of Flow. Takes a channel and exposes synchronous utility functions for communications.

Usually, you’ll use the convenience classmethods connect_tcp() or execute() instead of manually creating the constructor directly.

Parameters:
  • channel (Channel) – A channel.
  • echo (bool) – Whether or not to echo all input / output.
close()

Gracefully close the channel.

static connect_ssh(*args, **kwargs)

Create a new connected SSHClient instance. All arguments are passed to SSHClient.connect().

classmethod connect_tcp(host, port, echo=False)

Set up a TCPClientSocketChannel and create a Flow instance for it.

Parameters:
  • host (str) – The hostname or IP address to connect to.
  • port (int) – The port number to connect to.
  • echo (bool) – Whether to echo read/written data to stdout by default.
Returns:

Flow: A Flow instance initialised with the TCP socket channel.

Return type:

:class

classmethod execute(executable, *arguments, **kwargs)

execute(executable, argument..., redirect_stderr=False, echo=False):

Set up a ProcessChannel and create a Flow instance for it.

Parameters:
  • executable (str) – The executable to start.
  • argument... (list of str) – The arguments to pass to the executable.
  • redirect_stderr (bool) – Whether to also capture the output of stderr.
  • echo (bool) – Whether to echo read/written data to stdout by default.
Returns:

Flow: A Flow instance initialised with the process channel.

Return type:

:class

classmethod execute_ssh(command, arguments..., pty=False, echo=False)

Execute command on a remote server. It first calls Flow.connect_ssh() using all positional and keyword arguments, then calls SSHClient.execute() with the command and pty / echo options.

Parameters:
  • command (str) – The command to execute on the remote server.
  • arguments... – The options for the SSH connection.
  • pty (bool) – Request a pseudo-terminal from the server.
  • echo (bool) – Whether to echo read/written data to stdout by default.
Returns:

Flow: A Flow instance initialised with the SSH channel.

Return type:

:class

interact()

Interact with the socket. This will send all keyboard input to the socket and input from the socket to the console until an EOF occurs.

classmethod invoke_ssh_shell(*args, **kwargs)

invoke_ssh(arguments..., pty=False, echo=False)

Star a new shell on a remote server. It first calls Flow.connect_ssh() using all positional and keyword arguments, then calls SSHClient.invoke_shell() with the pty / echo options.

Parameters:
  • arguments... – The options for the SSH connection.
  • pty (bool) – Request a pseudo-terminal from the server.
  • echo (bool) – Whether to echo read/written data to stdout by default.
Returns:

Flow: A Flow instance initialised with the SSH channel.

Return type:

:class

kill()

Terminate the channel immediately.

classmethod listen_tcp(host='', port=0, echo=False)

Set up a TCPServerSocketChannel and create a Flow instance for it.

Parameters:
  • host (str) – The hostname or IP address to bind to.
  • port (int) – The port number to listen on.
  • echo (bool) – Whether to echo read/written data to stdout by default.
Returns:

Flow: A Flow instance initialised with the TCP socket channel.

Return type:

:class

read(n, echo=None)

Read n bytes from the channel.

Parameters:
  • n (int) – The number of bytes to read from the channel.
  • echo (bool) – Whether to write the read data to stdout.
Returns:

n bytes of data.

Return type:

bytes

Raises:

EOFError – If the channel was closed.

read_eof(echo=None)

Read until the channel is closed.

Parameters:echo (bool) – Whether to write the read data to stdout.
Returns:The read data.
Return type:bytes
read_until(s, echo=None)

Read until a certain string is encountered..

Parameters:
  • s (bytes) – The string to wait for.
  • echo (bool) – Whether to write the read data to stdout.
Returns:

The data up to and including s.

Return type:

bytes

Raises:

EOFError – If the channel was closed.

readline(echo=None)

Read 1 line from channel.

Parameters:echo (bool) – Whether to write the read data to stdout.
Returns:The read line which includes new line character.
Return type:bytes
Raises:EOFError – If the channel was closed before a line was read.
readlines(n, echo=None)

Read n lines from channel.

Parameters:
  • n (int) – The number of lines to read.
  • echo (bool) – Whether to write the read data to stdout.
Returns:

n lines which include new line characters.

Return type:

list of bytes

Raises:

EOFError – If the channel was closed before n lines were read.

until(s, echo=None)

Read until a certain string is encountered..

Parameters:
  • s (bytes) – The string to wait for.
  • echo (bool) – Whether to write the read data to stdout.
Returns:

The data up to and including s.

Return type:

bytes

Raises:

EOFError – If the channel was closed.

write(data, echo=None)

Write data to channel.

Parameters:
  • data (bytes) – The data to write to the channel.
  • echo (bool) – Whether to echo the written data to stdout.
Raises:

EOFError – If the channel was closed before all data was sent.

writeline(line=b'', sep=b'\n', echo=None)

Write a byte sequences to the channel and terminate it with carriage return and line feed.

Parameters:
  • line (bytes) – The line to send.
  • sep (bytes) – The separator to use after each line.
  • echo (bool) – Whether to echo the written data to stdout.
Raises:

EOFError – If the channel was closed before all data was sent.

writelines(lines, sep=b'\n', echo=None)

Write a list of byte sequences to the channel and terminate them with a separator (line feed).

Parameters:
  • lines (list of bytes) – The lines to send.
  • sep (bytes) – The separator to use after each line.
  • echo (bool) – Whether to echo the written data to stdout.
Raises:

EOFError – If the channel was closed before all data was sent.