Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new tmux mode #94

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,35 @@ yay -S arsenal
./run -t -e # just like the -t mode but with direct execution in the other pane without quitting arsenal
```

## Launch new tmux mode

Previous mode was working only when only one session was running. Since libtmux does not provide a way to identify tmux session the code is running in.


This new mode will need a `pane_path` which pattern is `<session_name>:<window_name>:[<pane_id>]`

Regarding `pane_path` :
- session identified by `session_name` must exist.
- if windows identified by `window_name`:
- does not exist: it will be created then pane number is ignored if specified
- exist and `pane_id`:
- is not specified: command will be sent to all panes in the window
- does not exist: a new pane will be created (similar to previous mode)
- exist: guess what

Note: within tmux session `prefix-q` willdisplay panes number

```
# will send command to all pane in arsenal-windows (windows creation needed)
./run --tmux-new tmux-pentest:arsenal-windows:

# will send command to a new pane
./run --tmux-new tmux-pentest:arsenal-windows:99

# will send command to pane 3
./run --tmux-new tmux-pentest:arsenal-windows:3
```

## Add external cheatsheets

You could add your own cheatsheets insode the my_cheats folder or in the ~/.cheats folder.
Expand Down
60 changes: 60 additions & 0 deletions arsenal/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
from .modules import gui as arsenal_gui


class PanePathAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if not re.fullmatch("^[^:]+:[^:]+:[0-9]*", values):
raise ValueError("Not a PANE_PATH")
setattr(namespace, self.dest, values)


class App:
tmux_server = None
tmux_session = None

def __init__(self):
pass
Expand Down Expand Up @@ -47,6 +56,8 @@ def get_args(self):
group_out.add_argument('-x', '--copy', action='store_true', help='Output to clipboard')
group_out.add_argument('-e', '--exec', action='store_true', help='Execute cmd')
group_out.add_argument('-t', '--tmux', action='store_true', help='Send command to tmux panel')
group_out.add_argument("-z", "--tmux-new", action=PanePathAction, metavar="PANE_PATH",
help="Send command to tmux pane", dest="tmux_new")
group_out.add_argument('-c', '--check', action='store_true', help='Check the existing commands')
group_out.add_argument('-f', '--prefix', action='store_true', help='command prefix')
parser.add_argument('-V', '--version', action='version', version='%(prog)s (version {})'.format(__version__))
Expand All @@ -55,6 +66,8 @@ def get_args(self):

def run(self):
args = self.get_args()
if args.tmux_new:
self.check_tmux(args)

# load cheatsheets
cheatsheets = cheat.Cheats().read_files(config.CHEATS_PATHS, config.FORMATS,
Expand Down Expand Up @@ -158,6 +171,9 @@ def start(self, args, cheatsheets):
except ImportError:
self.prefil_shell_cmd(cmd)
break
elif args.tmux_new:
self.process_tmux(args, cmd.cmdline)
break
# DEFAULT: Prefill Shell CMD
else:
self.prefil_shell_cmd(cmd)
Expand Down Expand Up @@ -192,6 +208,50 @@ def prefil_shell_cmd(self, cmd):
# restore TTY attribute for stdin
termios.tcsetattr(stdin, termios.TCSADRAIN, oldattr)

def check_tmux(self, args):
try:
import libtmux
except ImportError:
raise RuntimeError("Could not load libtmux") from None
pane_path = args.tmux_new.split(":")
try:
self.tmux_server = libtmux.Server()
self.tmux_session = self.tmux_server.sessions.get(session_name=pane_path[0])
except libtmux._internal.query_list.ObjectDoesNotExist:
raise RuntimeError(f"Could not find session {pane_path[0]}") from None

def process_tmux(self, args, cmdline):
pane_path = args.tmux_new.split(":")
new_window = False
import libtmux
try:
window = self.tmux_session.select_window(pane_path[1])
except libtmux.exc.LibTmuxException:
window = self.tmux_session.new_window(attach=False, window_name=pane_path[1])
new_window = True
if new_window:
pane = window.panes[0]
elif pane_path[2] == "": # all panes
pane = None
elif int(pane_path[2]) > len(window.panes):
pane = window.split_window(attach=False)
time.sleep(0.3)
else:
pane = window.panes[int(pane_path[2])]
if pane:
if args.exec:
pane.send_keys(cmdline)
else:
pane.send_keys(cmdline, enter=False)
pane.select_pane()
else:
for pane in window.panes:
if args.exec:
pane.send_keys(cmdline)
else:
pane.send_keys(cmdline, enter=False)
pane.select_pane()


def main():
try:
Expand Down
2 changes: 1 addition & 1 deletion arsenal/modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@

savevarfile = join(HOMEPATH, ".arsenal.json")

PREFIX_GLOBALVAR_NAME = "arsenal_prefix_cmd"
PREFIX_GLOBALVAR_NAME = "arsenal_prefix_cmd"
Loading