API¶
implant.core¶
The core module is transfered to the remote process and will bootstrap pipe communication.
It creates default channels and dispatches commands accordingly.
-
class
implant.core.
BaseHeaderItem
(*, default=None, encoder=None, decoder=None)[source]¶ Bases:
object
A base item of a header.
-
class
implant.core.
Channel
(name=None, *, send, loop=None)[source]¶ Bases:
asyncio.queues.Queue
Channel provides means to send and receive messages bound to a specific channel name.
-
__init__
(name=None, *, send, loop=None)[source]¶ Initialize the channel.
Parameters: - name – the channel name
- send – the partial send method of Channels
- loop – the event loop
-
send
= None¶ The send method bound to this channel’s name. See
Channels.send()
for details.
-
-
class
implant.core.
Channels
(reader, writer, *, loop=None)[source]¶ Bases:
object
Hold references to all channel queues and route messages accordingly.
-
__init__
(reader, writer, *, loop=None)[source]¶ Create a
Channels
instance which delegates incomming messages into their appropriateChannel
queues.Parameters: - reader –
asyncio.StreamReader
- writer –
asyncio.StreamWriter
- loop – the event loop
- reader –
-
coroutine
_finalize_message
(buffer, chunk)[source]¶ Finalize the message if
Header.eom
isTrue
.This will also acknowledge the message if
Header.send_ack
isTrue
.
-
acknowledgements
= None¶ Global acknowledgment futures distinctive by uid.
-
chunk_size
= 32768¶
-
coroutine
enqueue
()[source]¶ Schedule receive tasks.
Incomming chunks are collected and stored in the appropriate channel queue.
-
get_channel
(channel_name)[source]¶ Create a channel and weakly register its queue.
Parameters: channel_name – the name of the channel to create Returns: Channel
instance with a bound send method
-
incomming
= None¶ A collection of all active channels.
-
log
= <logging.Logger object>¶
-
coroutine
send
(channel_name, data, ack=False, compress=6)[source]¶ Send data in a encoded form to the channel.
Parameters: - channel_name – the name of the channel
- data – the python object to send
- ack – request acknowledgement of the reception of that message
- compress – compress the data with zlib
Messages are split into chunks and put into the outgoing queue.
-
-
class
implant.core.
Chunk
(header, channel_name, data)¶ Bases:
tuple
-
__getnewargs__
()¶ Return self as a plain tuple. Used by copy and pickle.
-
static
__new__
(_cls, header, channel_name, data)¶ Create new instance of Chunk(header, channel_name, data)
-
__repr__
()¶ Return a nicely formatted representation string
-
_asdict
()¶ Return a new OrderedDict which maps field names to their values.
-
classmethod
_make
(iterable, new=<built-in method __new__ of type object at 0xa385c0>, len=<built-in function len>)¶ Make a new Chunk object from a sequence or iterable
-
_replace
(**kwds)¶ Return a new Chunk object replacing specified fields with new values
-
channel_name
¶ Alias for field number 1
-
data
¶ Alias for field number 2
-
header
¶ Alias for field number 0
-
-
class
implant.core.
Command
(**parameters)[source]¶ Bases:
object
Common ancestor of all Commands.
-
command_name
= 'implant.core:Command'¶
-
dispatch_data
¶ Data to be dispatched.
-
parameters
= {}¶
-
-
class
implant.core.
CommandRemote
(full_classname)[source]¶ Bases:
object
Delegates remote task to another class.
This is usefull, if one wants not to import remote modules at the master side.
-
log
= <logging.Logger object>¶
-
-
class
implant.core.
ConnectionLostStreamReaderProtocol
(*args, connection_lost_cb, **kwargs)[source]¶ Bases:
asyncio.streams.StreamReaderProtocol
Call a callback on connection_lost.
-
class
implant.core.
Core
(loop, *, echo=None, **kwargs)[source]¶ Bases:
object
Core
starts theDispatcher
.-
coroutine
communicate
(reader, writer)[source]¶ Start the dispatcher and register the
ShutdownRemoteEvent
.- On shutdown:
- the import hook is removed
- the
Dispatcher.dispatch
task is stopped - the
Channels.enqueue
task is stopped
-
coroutine
connect_sysio
()[source]¶ Connect to
sys.stdin
andsys.stdout
.
-
log
= <logging.Logger object>¶
-
classmethod
main
(debug=False, log_config=None, *, loop=None, **kwargs)[source]¶ Start the event loop and schedule core communication.
-
static
setup_import_hook
(module_finder)[source]¶ Add module finder to
sys.meta_path
.
-
static
teardown_import_hook
(module_finder)[source]¶ Remove a module finder from
sys.meta_path
.
-
coroutine
-
class
implant.core.
DispatchCommand
(fqin, command_name, command_class, command_module, params)[source]¶ Bases:
implant.core.DispatchMessage
Arguments for a command dispatch.
-
log
= <logging.Logger object>¶
-
-
class
implant.core.
DispatchException
(fqin, exception, tb=None)[source]¶ Bases:
implant.core.DispatchMessage
Remote execution ended in an exception.
-
implant.core.
DispatchLocalContext
¶ alias of
implant.core.DispatchContext
-
class
implant.core.
DispatchMessage
(fqin)[source]¶ Bases:
object
Base class for command dispatch communication.
-
coroutine
__call__
(dispatcher)[source]¶ Executes appropriate
Dispatcher
methods to implement the core protocol.
-
log
= <logging.Logger object>¶
-
coroutine
-
class
implant.core.
DispatchReady
(fqin)[source]¶ Bases:
implant.core.DispatchMessage
Set the dispatch ready.
-
implant.core.
DispatchRemoteContext
¶ alias of
implant.core.DispatchContext
-
class
implant.core.
DispatchResult
(fqin, result=None)[source]¶ Bases:
implant.core.DispatchMessage
The result of a remote execution.
-
class
implant.core.
Dispatcher
(channels, *, loop=None)[source]¶ Bases:
object
Enables execution of
Command
s.A
Command
is split into local and remote part, where a context with a dedicatedChannel
is provided to enable streaming of arbitrary data. The local part also gets a remote future passed, which resolves to the result of the remote part of theCommand
.-
__init__
(channels, *, loop=None)[source]¶ Create a dispatcher, which executes messages on its own
Channel
to enable Command execution and communication via distinctChannel
s.
-
coroutine
_execute_channels
()[source]¶ Execute messages sent via our
Dispatcher.channel
.
-
channel
= None¶ A channel for the dispatcher itself.
-
channels
= None¶ The collection of all channels.
-
coroutine
execute
(command_name, **params)[source]¶ Execute a command.
First creating the remote side and its future and second executing its local part.
-
coroutine
execute_dispatch_command
(fqin, command_name, params)[source]¶ Create a command and execute it.
-
coroutine
execute_remote
(fqin, command)[source]¶ Execute the remote part of a Command. This method is called by a DispatchCommand message. The result is send via Dispatcher.channel to resolve the pending command future.
-
local_context
(fqin, remote_future)[source]¶ Create a local context to pass to a
Command
s local part.The
Channel
is built via a fully qualified instance name (fqin).
-
log
= <logging.Logger object>¶
-
pending_dispatches
= None¶ A collection of dispatches, which are still not finished.
-
remote_context
(fqin, pending_remote_task)[source]¶ Create a remote context to pass to a
Command
s remote part.The
Channel
is built via a fully qualified instance name (fqin).
-
remote_future
(fqin, command)[source]¶ Create a context for remote command future by sending DispatchCommand and returning its pending future.
-
-
class
implant.core.
FindSpecData
(**parameters)[source]¶ Bases:
implant.core.Command
Find spec data for a module to import from the remote side.
-
command_name
= 'implant.core:FindSpecData'¶
-
fullname
¶ Define a Command parameter.
-
parameters
= {'fullname': <implant.core.Parameter object at 0x7ff315003cf8>}¶
-
-
class
implant.core.
Flag
(*, default=None, encoder=None, decoder=None)[source]¶ Bases:
implant.core.BaseHeaderItem
A boolean flag of a header.
-
class
implant.core.
Header
[source]¶ Bases:
bytes
The chunk header with flags and items.
-
channel_name_len
¶ An item of a header.
-
compression
¶ A boolean flag of a header.
-
data_len
¶ An item of a header.
-
eom
¶ A boolean flag of a header.
-
items
= {'channel_name_len': <implant.core.HeaderItem object at 0x7ff315092860>, 'compression': <implant.core.Flag object at 0x7ff315092588>, 'data_len': <implant.core.HeaderItem object at 0x7ff315092908>, 'eom': <implant.core.Flag object at 0x7ff315092390>, 'recv_ack': <implant.core.Flag object at 0x7ff3150924e0>, 'send_ack': <implant.core.Flag object at 0x7ff315092470>, 'uid': <implant.core.HeaderItem object at 0x7ff315092748>}¶
-
recv_ack
¶ A boolean flag of a header.
-
send_ack
¶ A boolean flag of a header.
-
size
= 23¶
-
uid
¶ An item of a header.
-
-
class
implant.core.
HeaderItem
(fmt, **kwargs)[source]¶ Bases:
implant.core.BaseHeaderItem
An item of a header.
-
size
¶ The size of the item.
-
-
class
implant.core.
Incomming
(*, connection_lost_cb=None, pipe=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>, loop=None)[source]¶ Bases:
asyncio.streams.StreamReader
A context for an incomming pipe.
-
coroutine
readexactly
(n)[source]¶ Read exactly n bytes from the stream.
This is a short and faster implementation then the original one (see of https://github.com/python/asyncio/issues/394).
-
coroutine
-
class
implant.core.
InvokeImport
(**parameters)[source]¶ Bases:
implant.core.Command
Invoke an import of a module on the remote side.
The local side will import the module first. The remote side will trigger the remote import hook, which in turn will receive all missing modules from the local side.
The import is executed in a separate executor thread, to have a separate event loop available.
-
command_name
= 'implant.core:InvokeImport'¶
-
fullname
¶ Define a Command parameter.
-
parameters
= {'fullname': <implant.core.Parameter object at 0x7ff315003cc0>}¶
-
-
class
implant.core.
NoDefault
[source]¶ Bases:
object
Just a marker class to represent no default.
This is to separate really nothing and None.
-
class
implant.core.
NotifyEvent
(**parameters)[source]¶ Bases:
implant.core.Command
Notify about an event.
If the remote side registers for this event, it gets notified.
-
command_name
= 'implant.core:NotifyEvent'¶
-
dispatch_local
¶ Define a Command parameter.
-
event
¶ Define a Command parameter.
-
log
= <logging.Logger object>¶
-
parameters
= {'dispatch_local': <implant.core.Parameter object at 0x7ff315003c88>, 'event': <implant.core.Parameter object at 0x7ff315003c50>}¶
-
-
class
implant.core.
OrderedMeta
[source]¶ Bases:
type
Preserve the order of instance creation.
-
items
= [<implant.core.Flag object>, <implant.core.Flag object>, <implant.core.Flag object>, <implant.core.Flag object>, <implant.core.HeaderItem object>, <implant.core.HeaderItem object>, <implant.core.HeaderItem object>]¶
-
-
class
implant.core.
Outgoing
(*, pipe=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, reader=None, loop=None)[source]¶ Bases:
object
A context for an outgoing pipe.
-
class
implant.core.
Parameter
(*, default=<class 'implant.core.NoDefault'>, description=None)[source]¶ Bases:
object
Define a Command parameter.
-
exception
implant.core.
RemoteClassNotSetException
[source]¶ Bases:
Exception
Raised when remote class is not set for
CommandRemote
-
class
implant.core.
RemoteModuleFinder
(dispatcher, *, loop)[source]¶ Bases:
importlib.abc.MetaPathFinder
Import hook that execute a
FindSpecData
command in the main loop.See pep-0302, pep-0420 and pep-0451 for internals.
-
log
= <logging.Logger object>¶
-
-
class
implant.core.
RemoteModuleLoader
(source, filename=None, is_package=False)[source]¶ Bases:
importlib.abc.ExecutionLoader
Load the found module spec.
-
get_filename
(fullname)[source]¶ Abstract method which should return the value that __file__ is to be set to.
Raises ImportError if the module cannot be found.
-
get_source
(fullname)[source]¶ Abstract method which should return the source code for the module. The fullname is a str. Returns a str.
Raises ImportError if the module cannot be found.
-
-
class
implant.core.
ShutdownRemoteEvent
[source]¶ Bases:
object
A Shutdown event.
Shutting down a remote connection is done by gracefully canceling all remote tasks. See
Core.communicate
for details.
-
class
implant.core.
StopAsyncIterationEncoder
[source]¶ Bases:
object
Encoder for
StopAsyncIteration
.
-
class
implant.core.
Uid
(bytes=None)[source]¶ Bases:
uuid.UUID
A unique id, which is basically a
uuid.uuid1
instance.-
time
¶ The timestamp of the uuid1.
-
-
implant.core.
event_handler
(event_class, handler_=None, decorator=False)[source]¶ Define an event handler for a (new-style) class.
This can be called with a class and a handler, or with just a class and the result used as a handler decorator.
implant.bootstrap¶
Bootstrap of a remote python process.
implant.connect¶
Remote connection is established by a Connector.
-
class
implant.connect.
ConnectorMeta
[source]¶ Bases:
abc.ABCMeta
Connector meta base.
-
connectors
= {'local': <class 'implant.connect.Local'>, 'lxd': <class 'implant.connect.Lxd'>, 'ssh': <class 'implant.connect.Ssh'>}¶
-
scheme
¶ The unique connector scheme is the lowered class name.
-
-
class
implant.connect.
Local
(*, sudo=None)[source]¶ Bases:
implant.connect.SubprocessConnector
A Connector to a local python process.
-
arguments
(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
sudo
¶
-
-
class
implant.connect.
Lxd
(*, container, hostname=None, user=None, sudo=None)[source]¶ Bases:
implant.connect.Ssh
A Connector for accessing a lxd container.
If the hostname is omitted, the lxd container is local.
-
arguments
(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
container
¶
-
hostname
¶
-
sudo
¶
-
user
¶
-
-
class
implant.connect.
Remote
(*, stdin=None, stdout=None, stderr=None, loop=None)[source]¶ Bases:
object
A remote receiving commands.
-
exception
implant.connect.
RemoteMisbehavesError
[source]¶ Bases:
Exception
Exception is raised, when a remote process seems to be not what we expect.
-
class
implant.connect.
Ssh
(*, hostname=None, user=None, sudo=None)[source]¶ Bases:
implant.connect.Local
A Connector for remote hosts reachable via SSH.
If a hostname is omitted, this connector acts like Local.
-
arguments
(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
hostname
¶
-
sudo
¶
-
user
¶
-
-
class
implant.connect.
SubprocessConnector
[source]¶ Bases:
implant.connect.Connector
A Connector uniquely defines a remote target.
-
arguments
(*, code=None, options=None, python_bin=None)[source]¶ Iterate over the arguments to start a process.
Parameters: - code – the code to bootstrap the remote process
- options – options for the remote process
- python_bin – the path to the python binary
-
static
bootstrap_code
(code=<module 'implant.core' from '/home/docs/checkouts/readthedocs.org/user_builds/implant/envs/latest/lib/python3.5/site-packages/implant-0.1.2-py3.5.egg/implant/core.py'>, options=None)[source]¶ Create the python bootstrap code.
-
coroutine
launch
(*, loop=None, code=None, options=None, python_bin=None, **kwargs)[source]¶ Launch a remote process.
Parameters: - code – the python module to bootstrap
- options – options to send to remote
- python_bin – the path to the python binary to execute
- kwargs – further arguments to create the process
-
-
class
implant.connect.
SubprocessRemote
(transport, protocol, *, loop=None)[source]¶ Bases:
implant.connect.Remote
A remote process.
-
returncode
¶ The exit code of the process.
-