Closed pitust closed 4 years ago
I'm not exactly clear what you mean. What happens at the beginning is that it starts a pty and grabs few bits of information to identify the remote system. If it's slow, it's because your connection to the remote machine is slow. TryHackMe is notorious for having ungodly slow machines (understandably since they're running thousands of them, presumably). pwncat
is basically just grabbing the hostname, the mac address of network cards that are available, and the current shell. Then it identifies which method to use for spawning a pty. Normally, that's script
or python
, but it checks which one exists first. You need a pty for pwncat to work properly. The only part that isn't strictly necessary is the hostname and mac address part, but without that you have no way to uniquely identify that host. There's only one C2 channel so there's no way to "background" those actions. As with everything that happens in pwncat, it has to wait for them to complete to continue.
I might be able to speed it up by compiling multiple of those into one command (essentially an in-memory script) and feeding it to the remote shell, then reading the data back instead of running each individually, but there's not a way to background anything.
No, here is my idea: a new binary, pwncatd, already has all the scripts loaded and it created a victim. When a new request comes to a unix domain socket, it forks and runs as if it was normal pwncat. Main process keeps listening. This is much faster than doing everything when the user actually requests it (or at least, ot starts quicker)
it takes a long time to run Victim()
locally. I checked. That is what i want to optimize. I propably wasn't clear about it.
I've done some digging, and a large factor was gtfobins.json
. The file was (is) huge. We may be able to move to a better file format for this data at some point. Adding to this was the fact that when creating the file format and testing the gtfobins
module, we wanted comments in the JSON to allow us to document what was going on. This lead us to the commentjson
python module. This module is incredibly slow. I removed all the comments and minified the JSON file, but still was seeing about 2
seconds loading time with a return directly after Victim()
in __main__.py
(down from 2.7
to be fair).
With that in mind, I took a look at some different python JSON modules. The builtin module clocked in at about 0.98
seconds. orjson
isn't compatible with the standard JSON interface so would require some more modification of the gtfobins
module to make it work. I tried rapidjson
and it clocked in at about 0.8
seconds.
I've settled on rapidjson
. I've added it to the requirements.txt
and setup.py
scripts, and pushed an update. This shaves off about 1.7
-2.0
seconds off the startup time (an about 60% speed up for starting up). Hopefully this will help. Any further optimization for the GTFObins data seems unnecessary. I commented out the entire loading process for gtfobins.json
and saw little to no increase in performance (at best, on one run I saw 0.77 vice 0.80 seconds).
Also, for what it's worth, just starting pwncat
and returning just before creating the Victim
object now takes about 0.70
while returning just after creating the Victim
object takes about 0.80
seconds. So, creating the Victim
object now only takes on average about 0.1
seconds. Nothing really happens before that so the rest of the loading time is basically just python loading modules, which python is notoriously bad at.
While I don't think the proper solution is creating a pwncat
daemon, I appreciate you bringing this up because it forced me to do some digging and find this bug. I understand python can be annoying with it's loading times, and I'll do everything I can to reduce it, but with a lot of imports python is just really slow at starting up.
I haven't heard back in more than 2 weeks. I'm going to close this issue. Feel free to reach out if you have any more issues or comments. Thanks!
Is your feature request related to a problem? Please describe. pwncat takes a long time to start. Most of this time is loading dependencies and creating a Victim. Describe the solution you'd like Implement a daemonize feature to allow for pwncat to run in the background and connect to it via a much dumber (and therefore faster) socket implementation (eg. the other pwncat or ncat, or a custom-made one especially for this purpose)