1
0
mirror of https://github.com/calebstewart/pwncat.git synced 2024-11-24 01:25:37 +01:00

Merge pull request #55 from pitust/master

Upgrade the prompt
This commit is contained in:
Caleb Stewart 2020-09-14 15:38:28 -04:00 committed by GitHub
commit fb6424bde1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 51 deletions

View File

@ -145,32 +145,6 @@ slipped through the cracks and been observed in the wild. When this happens, `pw
will do whatever it can to preserve your terminal, but you may be greeted with some will do whatever it can to preserve your terminal, but you may be greeted with some
peculiar output or command failures. peculiar output or command failures.
### Dash Support
The Debian shell `dash` aims to be a very minimalistic shell. It's focus is not on user
interface, but on running scripts quickly and correctly. As a result, some of the features
we expect from an interactive shell simply don't work in `dash`. `pwncat` tries not to
depend on a specific shell environment, so if you start your reverse or bind shell with
`/bin/sh` or `/bin/dash`, then you may get a weird prompt. `dash` does not obey the
terminal escape sequences which `pwncat` adds, so you may get a very long terminal like this:
```shell script
\[\033[01;31m\](remote)\[\033[00m\] \[\033[01;33m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]$
```
Currently, the only workaround is to use the `prompt` command at the local `pwncat` prompt.
The command allows you to modify the prompt which `pwncat` will automatically set whenever
resetting the remote terminal. Two options are provided: "basic" and "fancy". The "fancy"
prompt is the default which causes the above output in Dash. To switch to the basic prompt
you can use the following command at the `pwncat` prompt:
```shell script
prompt --basic
```
While this is inconvenient, it does not affect the behaviour of `pwncat`. All `pwncat`
features will continue to function properly no matter what your prompt looks like.
### BSD Support ### BSD Support
While BSD is a Unix-based kernel, in practice it's userland tools are noticeably While BSD is a Unix-based kernel, in practice it's userland tools are noticeably

View File

@ -20,7 +20,7 @@ class Command(CommandDefinition):
Complete.NONE, Complete.NONE,
group="mutex", group="mutex",
action="store_true", action="store_true",
help="Set a basic prompt with no color or automatic system information", help="Set a basic prompt with no color or automatic system information. There _should_ be no reason to use that anymore (unless your local terminal has no ANSI support)",
), ),
"--fancy,-f": Parameter( "--fancy,-f": Parameter(
Complete.NONE, Complete.NONE,
@ -33,13 +33,8 @@ class Command(CommandDefinition):
def run(self, args): def run(self, args):
if args.fancy: if args.fancy:
pwncat.victim.remote_prefix = "\\[\\033[01;31m\\](remote)\\[\\033[00m\\]" pwncat.victim.remote_prompt = """$(command printf "\\033[01;31m(remote)\\033[0m \\033[01;33m$(whoami)@$(hostname)\\033[0m:\\033[1;36m$PWD\\033[0m$ ")"""
pwncat.victim.remote_prompt = (
"\\[\\033[01;33m\\]\\u@\\h\\[\\033[00m\\]:\\["
"\\033[01;36m\\]\\w\\[\\033[00m\\]\\$ "
)
else: else:
pwncat.victim.remote_prefix = "(remote)" pwncat.victim.remote_prompt = f"(remote) {pwncat.victim.host.ip}:$PWD\\$ "
pwncat.victim.remote_prompt = f"{pwncat.victim.host.ip}:$PWD\\$ "
pwncat.victim.reset(hard=False) pwncat.victim.reset(hard=False)

View File

@ -113,12 +113,8 @@ class Victim:
# Saved remote terminal state (for transition to/from raw mode) # Saved remote terminal state (for transition to/from raw mode)
self.saved_term_state = None # util.enter_raw_mode() self.saved_term_state = None # util.enter_raw_mode()
# util.restore_terminal(self.saved_term_state, new_line=False) # util.restore_terminal(self.saved_term_state, new_line=False)
# Prompt and prompt prefix # Prompt
self.remote_prefix = "\\[\\033[01;31m\\](remote)\\[\\033[00m\\]" self.remote_prompt = """$(command printf "\\033[01;31m(remote)\\033[0m \\033[01;33m$(whoami)@$(hostname)\\033[0m:\\033[1;36m$PWD\\033[0m$ ")"""
self.remote_prompt = (
"\\[\\033[01;33m\\]\\u@\\h\\[\\033[00m\\]:\\["
"\\033[01;36m\\]\\w\\[\\033[00m\\]\\$ "
)
# Aliases for equivalent commands # Aliases for equivalent commands
self.binary_aliases = { self.binary_aliases = {
"python": [ "python": [
@ -368,14 +364,7 @@ class Victim:
progress.update(task_id, status="prompt") progress.update(task_id, status="prompt")
if self.shell == "/bin/sh": self.run(f"export PS1='{self.remote_prompt}'")
progress.log(
f"[yellow]warning[/yellow]: /bin/sh does not support colored prompts."
)
self.remote_prefix = "(remote)"
self.remote_prompt = f"{pwncat.victim.host.ip}:$PWD\\$ "
self.run(f"export PS1='{self.remote_prefix} {self.remote_prompt}'")
# This should be valid in any POSIX compliant shell # This should be valid in any POSIX compliant shell
progress.update(task_id, status="checking for pty") progress.update(task_id, status="checking for pty")
@ -416,7 +405,7 @@ class Victim:
# This stuff won't carry through to the PTY, so we need to reset it again. # This stuff won't carry through to the PTY, so we need to reset it again.
self.run("unset PROMPT_COMMAND") self.run("unset PROMPT_COMMAND")
self.run(f"export PS1='{self.remote_prefix} {self.remote_prompt}'") self.run(f"export PS1='{self.remote_prompt}'")
# Make sure HISTFILE is unset in this PTY (it resets when a pty is # Make sure HISTFILE is unset in this PTY (it resets when a pty is
# opened) # opened)
@ -1839,7 +1828,7 @@ class Victim:
self.has_cr = True self.has_cr = True
self.has_echo = True self.has_echo = True
self.run("echo") self.run("echo")
self.run(f"export PS1='{self.remote_prefix} {self.remote_prompt}'") self.run(f"export PS1='{self.remote_prompt}'")
def flush_output(self, some=False): def flush_output(self, some=False):
""" """
@ -1909,7 +1898,7 @@ class Victim:
self.run("unset HISTFILE; export HISTCONTROL=ignorespace") self.run("unset HISTFILE; export HISTCONTROL=ignorespace")
self.run("unset PROMPT_COMMAND") self.run("unset PROMPT_COMMAND")
self.run("unalias -a") self.run("unalias -a")
self.run(f"export PS1='{self.remote_prefix} {self.remote_prompt}'") self.run(f"export PS1='{self.remote_prompt}'")
self.run(f"tput rmam") self.run(f"tput rmam")
def recvuntil(self, needle: bytes, interp=False, timeout=None): def recvuntil(self, needle: bytes, interp=False, timeout=None):