The root of this problem was a typo: missing square braces around
enumeration. However, it also shouldn't have been raising a module
failed error in that case.
After fixing that problem, I found a few more bugs while testing
with Metasploitable2, so I fixed those:
- Added small sleeps in escalation to let the shell keep up
- stat behaves oddly, so added a loop to retry on parsing failure
- Fixed the **syntax** of the mtr gtfobins payload
- Fixed the nmap gtfobins payload
The mtr gtfobins payload is still not right, as it is unable to
read files as it should, but I'll work on that moving forward.
For now, there are no exceptions and escalation is working properly
through `nmap`.
This marks a huge step in pwncat. We're finally merging
the platforms branch. The API has completely changed at
this point. I've bumped the version number in setup.py
and tagged the old version appropriately. The
readthedocs stable page will still point to the old
API while latest should provide documentation on the
updated API.
Also added markdown table generator/jinja filter for report generation.
This is currentl the best I can do since commonmark (and therefore rich)
doesn't support tables at the moment. 😭
I have opened the Windows C2 repository, and added the ability for
pwncat to automatically download the C2 DLLs. If you don't have internet
or would rather grab them yourself, you can place them in
~/.local/share/pwncat (or point the `windows_c2_dir` config at the
directory where you do place them). If `stageone.dll` and `stagetwo.dll`
exist in that directory, pwncat will not attempt to download them from github.
Reports are generated based on platform and use Jinja2.
Report templates are in pwncat/data/reports. I still need
to implement the full report for the individual platforms, but
have some boilerplate in the generic template. The module will
also render markdown to the terminal via rich markdown, however
tables are currently not rendered properly.
A PrivateKey fact is now also an implant unless the key is not
authorized. When we locate a private key by enumeration, the
key is assumed to be authorized until it fails. If a private
key fails to connect, it's implant types are removed, but the fact
is kept in the database. The authorized keys implant also reuses
this fact type, but defines a different remove routine to actaully
remove the authorized key from the target.
I went through each command to make sure they work.
Some commands aren't needed anymore and aren't implemented.
They will likely be removed eventually, but I've left an
error message there in case I want it later. This is another
check for #95.
Ensured the session is only started/closed once per module run.
Also, added calls to `session.close` after interactive exit from
main entrypoint. Closing a session also logs any tampers or implants
left behind before closing the session.
Still need to test remote functionality, but that requires an
implementation of a reconnect command (or capability in `connect`). In
the meantime, escalate, install, and remove all work. On more step for #95.