1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
import re
from core import messages
from core.loggers import log
from core.module import Module, Status
from core.vectors import ShellCmd, PythonCode
class Su(Module):
"""Execute commands with su."""
aliases = ['ifconfig']
def init(self):
self.register_info(
{
'author': [
'Emilio Pinna'
],
'license': 'GPLv3'
}
)
self.register_vectors(
[
ShellCmd(
"""expect -c 'spawn su -c "${command}" "${user}"; expect -re "assword"; send "${ passwd }\r\n"; expect eof;'""",
name="sh_expect",
postprocess=lambda x: re.findall('Password: (?:\r\n)?([\s\S]+)', x)[0] if 'Password: ' in x else ''
),
PythonCode(
"""
import pexpect as p,sys
c = p.spawn("su ${user} -c ${command}")
c.expect(".*assword:");c.sendline("${ passwd }")
i = c.expect([p.EOF,p.TIMEOUT])
if i!=p.TIMEOUT:
sys.stdout.write(c.before[3:].decode("utf-8","replace"))
""",
name="pyexpect")
]
)
self.register_arguments([
{'name': 'passwd', 'help': 'User\'s password'},
{'name': 'command', 'help': 'Shell command', 'nargs': '+'},
{'name': '-user', 'help': 'User to run the command with', 'default': 'root'},
{'name': '-stderr_redirection', 'default': ' 2>&1'},
{'name': '-vector-sh',
'choices': ('system', 'passthru', 'shell_exec', 'exec', 'popen', 'proc_open', 'perl_system', 'pcntl')},
{'name': '-vector', 'choices': self.vectors.get_names()}
])
def setup(self):
"""Probe all vectors to find a working su command.
The method run_until is not used due to the check of shell_sh
enabling for every tested vector.
Args:
self.args: The dictionary of arguments
Returns:
Status value, must be Status.RUN, Status.FAIL, or Status.IDLE.
"""
args_check = {
'user': self.args['user'],
'passwd': self.args['passwd'],
'command': 'whoami'
}
(vector_name,
result) = self.vectors.find_first_result(
names=[self.args.get('vector', '')],
format_args=args_check,
condition=lambda result: (
# Stop if shell_sh is in FAIL state
self.session['shell_sh']['status'] == Status.FAIL or
# Or if the result is correct
self.session['shell_sh']['status'] == Status.RUN and result and result.rstrip() == self.args['user']
)
)
if self.session['shell_sh']['status'] == Status.RUN and result and result.rstrip() == self.args['user']:
self.session['shell_su']['stored_args']['vector'] = vector_name
return Status.RUN
else:
log.warn(messages.module_shell_su.error_su_executing)
return Status.IDLE
def run(self, **kwargs):
# Join the command list and
# Escape the single quotes. This does not protect from \' but
# avoid to break the query for an unscaped quote.
self.args['command'] = ' '.join(self.args['command']).replace("'", "\\'")
format_args = {
'user': self.args['user'],
'passwd': self.args['passwd'],
'command': self.args['command']
}
if self.args.get('vector_sh'):
format_args['vector'] = self.args['vector_sh']
if self.args.get('stderr_redirection'):
format_args['stderr_redirection'] = self.args['stderr_redirection']
return self.vectors.get_result(
name=self.args['vector'],
format_args=format_args
)
|