Age | Commit message (Collapse) | Author | Files | Lines |
|
Add the ability to select which location to create FIFOs when running in
pipes mode, by passing the directory name to sploit where a target
executable would usually go. This has been an API feature from the start,
but not exposed via the sploit runner command-line interface.
There are a couple new use-cases where this is very convenient, including
scriptifying sploit in pipes mode (testing, for example) and when running
sploit under Docker. If pipes are placed in the working directory, all
project files can be shared with a single bind mount.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Print the current version (sourced from git describe) when sploit
starts up.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
Reviewed-by: Malfurious <m@lfurio.us>
|
|
Moving this io cleanup code to the finally block allows it to also run
when recovering from an exception. This prevents cases where the target
may hang if the user sploit script crashes, and avoids requiring the
user to press an additonal CTRL-C to move on.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
A new function, Comm.shutdown(), is added. It will close only the
stdout stream of the communications backend, potentially making the
termination of the target program more fluid.
The name 'shutdown' is chosen to emulate shutdown(2) from the low-level
socket api, which is used to close just part of a full-duplex file
descriptor. This is in contrast to 'close', which I would expect to
completely terminate the given object IO.
comm.shutdown() is now called by main.py, after the user script returns,
to ensure that the subsequent readall() doesn't get stuck because our
target is blocked reading its stdin.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
This just adds a fancy 'SPLOIT' header to the beginning of Sploit's
startup preamble data. It has the ability to display a few lines of
text beside itself, but most of the things we've planned to put here are
not available yet, so just the operating mode is printed for now.
The SPLOIT text has a colored stripe which, at the moment, also
indicates the operating mode. This stripe was originally chosen to
balance out the amount of color present in the preamble text, but I've
grown to like it.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
The log module is updated to support binary encodings, colors, and for
improved compatibility with Python's print() builtin.
Encoding semantics are switched up, since it seems like some of the more
interesting encoding modes (from a CTF perspective) actually use
bytes-like objects as their high-level form (that is, bytes are encoded
to another form, such as hex, then decoded back to the original form).
So the logged value is now passed to encode instead of decode, and only
if the object is of type 'bytes', as unicode strings are now considered
out-of-scope for this operation. Additionally, the bytes wrapper (b'')
is no longer visible in the logged content.
For readability, several standard colors have been defined for use
within Sploit:
- RED: Errors
- YELLOW: Warnings
- GREEN: Status messages / Startup messages
- WHITE: Target output
- GRAY: User output / Alt text
Logging functions now support an optional color option to select the
desired color, and have specific defaults based on who is invoking the
log (see below...)
Logging functions are now also fully compatible with the builtin print()
function. This is because Sploit now replaces the standard print() with
a logging function within the user's script (which is done to maintain
additional consistency of messages displayed in the console).
Function ilog (internal log) has default values tuned for the library's
convenience: Text goes to stderr, and is presented as status messages
(green).
Function elog (external log) has default values tuned for the user: Text
goes to stdout, and is presented as alt text to distinguish it from data
read from the target. Within the user context, 'print' refers to this
function.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
A couple of facts have influenced the decision to remove this option:
- If a sploit script uses a shebang to launch sploit, it is
tricky to specify this option. Specifically, one must add it
to their shebang line, which couples more information to the
script than was originally intended.
- Single-pass pipe mode wasn't all that useful. One can
accomplish the same thing by running pipe-daemon, and it is
easy to exit after one iteration. Electing to run normal pipe
mode requires you to know you only want to run once, which is
much more common when running via direct subprocess.
As a result of this change, running in pipe mode will now be equivalent to
the previous pipe-daemon mode, and subprocess target mode remains single
pass.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Apparently python won't run garbage collection on stuff owned by the
exec context if you define a function in the exec. This can lead to
random leaks, but it is most impactful in daemon mode. If the globals
dictionary given to exec isn't cleaned up, there will be a random
reference to comm that still exists. This holds a reference to the
Pipes object which prevents it from getting cleaned up before we try to
make a new one. Making a new one needs the fifos to have been cleaned
up, so it relies on the fact that the old one was supposed to be
cleaned up.
The most straightforward and non-intrusive way I could think to fix this
was to just manually run the garbage collector after exec. This is able
to find the leaked references and clean it all up.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
The handling from the daemon mode code will also work in the process and
pipes cases. Putting it in a common location removes the need for the
outer try/except. It is also easier to read/maintain in general.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
If the user's script contains
from sploit import *
then the exported 'comm' communication object is clobbered by the 'comm'
source module. Switching the name to 'io' avoids this issue, is more
to the point, and is even fewer characters to type.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Rather than implicitly inheriting names in scope for the user-script,
this collection is sanitized and we only export the 'comm' communication
object. This seems to be a safer way to operate and addresses an issue
with sub-scopes in the user's script not functioning properly.
(Previously, user-defined functions did not have access to globals, or
library functions.)
Additionally, the user's code is now passed through compile() to attach
the original file name. This is useful for debugging / diagnostic
situations, to make it more obvious if a crash originated from the
user's script.
Signed-off-by: Malfurious <m@lfurio.us>
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
If the user presses Ctrl+C while waiting on a connection, we want to
gracefully exit.
If the user presses Ctrl+C during the script, we want to stop executing
the script and restart the loop.
If any other exception happens during the script, we want to print out
the stacktrace as normal, but continue the loop.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
With the "read rest of output" code in the Comm destructor, it would
continue to read output even in situations where some error happened and
we expect sploit to die or when the user presses Ctrl+C to end sploit.
By moving it to the end of the script running code in main, it behaves
more intuitively.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Previously, you could specify a directory which must exist under /tmp.
Now, you can give the full path to a directory to be used by Pipes.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|
|
First part of the MVP for the larger Sploit rework effort.
Add project structure, python packaging, basic comms, and "log" hook.
From in or out of the sploit directory, you can run the "sploit.py"
script, run python -m sploit, or import the sploit modules from the
python3 shell.
You can also pip install Sploit and from anywhere you can run the sploit
command, run python -m sploit, or import the sploit modules from the
python3 shell.
Running as a standalone application, Sploit can run in a "target" mode,
a "pipe" mode, and a "pipe daemon" mode. In "target" mode, Sploit will
launch a target program as a subprocess and run an exploit script
against its I/O. In "pipe" mode, Sploit will create named fifos and
wait for a program to connect to them to run an exploit script against
them. In "pipe daemon" mode, Sploit will run similar to the "pipe" mode,
but automatically recreate the fifos with the same name after each
execution.
Basic comm operations of read, readline, write, and writeline are
available to the exploit script.
A "log" hook is executed whenever data is read in from the target
program. This will just print the data out, but it can be configured to
decode it with a specific encoding or you could replace the function for
different behavior.
Signed-off-by: dusoleil <howcansocksbereal@gmail.com>
|