Ejemplo n.º 1
0
    def test_upload_blind(self):

        obj, data = self._get_detection_obj_data(
            self.url_blind % ''
        )
        self.assertEqual(data, self.expected_data_blind)

        # Send file without --force-overwrite, should fail
        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        obj.write('AAAA', remote_temp_path)
        self.assertFalse(os.path.exists(remote_temp_path))

        # Now set --force-overwrite and retry
        obj.channel.args['force_overwrite'] = True

        # Send long binary
        data = open('/bin/ls', 'rb').read()
        obj.write(data, remote_temp_path)
        
        # Since it's blind, read md5 from disk
        checkdata = open(remote_temp_path, 'rb').read()
        self.assertEqual(strings.md5(checkdata), strings.md5(data))
        os.unlink(remote_temp_path)
        
        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send short ASCII data
        data = 'SHORT ASCII DATA'
        obj.write(data, remote_temp_path)
        
        checkdata = open(remote_temp_path, 'rb').read()
        self.assertEqual(strings.md5(checkdata), strings.md5(data))
        os.unlink(remote_temp_path)    
    def test_upload(self):

        obj, data = self._get_detection_obj_data(self.url % '')
        self.assertEqual(data, self.expected_data)

        if not EXTRA_UPLOAD:
            return

        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send long binary
        data = open('/bin/ls', 'rb').read()
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))
        obj.execute('rm %s' % (remote_temp_path))

        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send short ASCII data, without removing it
        data = 'SHORT ASCII DATA'
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))

        # Try to append data without --force-overwrite and re-check the previous md5
        obj.write('APPENDED DATA', remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))

        # Now set --force-overwrite and rewrite new data on the same file
        obj.channel.args['force_overwrite'] = True
        data = 'NEW DATA'
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))
        obj.execute('rm %s' % (remote_temp_path))
Ejemplo n.º 3
0
    def rendered_detected(self):

        randA = rand.randstr_n(2)
        randB = rand.randstr_n(2)

        payload = '"%s".join("%s")' % (randA, randB)
        expected = randA.join(randB)

        if expected == self.render(payload):

            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            os = self.evaluate(
                """'-'.join([__import__('os').name, __import__('sys').platform])"""
            )
            if os and re.search('^[\w-]+$', os):
                self.set('os', os)
                self.set('evaluate', self.language)
                self.set('write', True)
                self.set('read', True)

                expected_rand = str(rand.randint_n(2))
                if expected_rand == self.execute('echo %s' % expected_rand):
                    self.set('execute', True)
                    self.set('bind_shell', True)
                    self.set('reverse_shell', True)
Ejemplo n.º 4
0
    def test_upload(self):

        obj, data = self._get_detection_obj_data(self.url % '')
        self.assertEqual(data, self.expected_data)
        
        if not EXTRA_UPLOAD:
            return

        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send long binary
        data = open('/bin/ls', 'rb').read()
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))
        obj.execute('rm %s' % (remote_temp_path))

        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send short ASCII data, without removing it
        data = 'SHORT ASCII DATA'
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))

        # Try to append data without --force-overwrite and re-check the previous md5
        obj.write('APPENDED DATA', remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))

        # Now set --force-overwrite and rewrite new data on the same file
        obj.channel.args['force_overwrite'] = True
        data = 'NEW DATA'
        obj.write(data, remote_temp_path)
        self.assertEqual(obj.md5(remote_temp_path), strings.md5(data))
        obj.execute('rm %s' % (remote_temp_path))
Ejemplo n.º 5
0
    def rendered_detected(self):

        randA = rand.randstr_n(2)
        randB = rand.randstr_n(2)

        # Check this to avoid detecting Twig as Jinja2
        payload = '{{"%s".join("%s")}}' % (randA, randB)
        expected = randA.join(randB)

        if expected == self.render(payload):

            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            os = self.evaluate("""'-'.join([__import__('os').name, __import__('sys').platform])""")
            if os and re.search('^[\w-]+$', os):
                self.set('os', os)
                self.set('evaluate', self.language)
                self.set('write', True)
                self.set('read', True)

                expected_rand = str(rand.randint_n(2))
                if expected_rand == self.execute('echo %s' % expected_rand):
                    self.set('execute', True)
                    self.set('bind_shell', True)
                    self.set('reverse_shell', True)
    def test_upload_blind(self):

        obj, data = self._get_detection_obj_data(self.url_blind % '',
                                                 technique='T')
        self.assertEqual(data, self.expected_data_blind)

        if not EXTRA_UPLOAD_BLIND:
            return

        # Send file without --force-overwrite, should fail
        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        obj.write('AAAA', remote_temp_path)
        self.assertFalse(os.path.exists(remote_temp_path))

        # Now set --force-overwrite and retry
        obj.channel.args['force_overwrite'] = True

        # Send long binary
        data = open('/bin/ls', 'rb').read()
        obj.write(data, remote_temp_path)

        # Since it's blind, read md5 from disk
        checkdata = open(remote_temp_path, 'rb').read()
        self.assertEqual(strings.md5(checkdata), strings.md5(data))
        os.unlink(remote_temp_path)

        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        # Send short ASCII data
        data = 'SHORT ASCII DATA'
        obj.write(data, remote_temp_path)

        checkdata = open(remote_temp_path, 'rb').read()
        self.assertEqual(strings.md5(checkdata), strings.md5(data))
        os.unlink(remote_temp_path)
Ejemplo n.º 7
0
    def detect_engine(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s{*%s*}%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.render(payload):
            self.set('language', 'php')
            self.set('engine', 'smarty')
Ejemplo n.º 8
0
    def detect_engine(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s<#--%s-->%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.inject(payload):
            self.set('language', 'java')
            self.set('engine', 'freemarker')
Ejemplo n.º 9
0
    def detect_engine(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s{*%s*}%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.inject(payload):
            self.set('language', 'php')
            self.set('engine', 'smarty')
Ejemplo n.º 10
0
    def detect_engine(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s<#--%s-->%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.inject(payload):
            self.set('language', 'java')
            self.set('engine', 'freemarker')
Ejemplo n.º 11
0
    def detect_engine(self):

        randA = rand.randstr_n(2)
        randB = rand.randstr_n(2)

        payload = '{{"%s".join("%s")}}' % (randA, randB)
        expected = randA.join(randB)

        if expected == self.inject(payload):
            self.set('language', 'python')
            self.set('engine', 'jinja2')
            self.set('eval', 'python')
Ejemplo n.º 12
0
    def detect_engine(self):

        randA = rand.randstr_n(2)
        randB = rand.randstr_n(2)

        payload = '{{"%s".join("%s")}}' % (randA, randB)
        expected = randA.join(randB)

        if expected == self.inject(payload):
            self.set('language', 'python')
            self.set('engine', 'jinja2')
            self.set('eval', 'python')
Ejemplo n.º 13
0
    def rendered_detected(self):

        randA = rand.randstr_n(2)

        # Check this to avoid false positives
        payload = 'p %s' % randA
        expected = '<p>%s</p>' % randA

        if expected == self.render(payload):

            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            os = self.evaluate("""global.process.mainModule.require('os').platform()""")
            if os and re.search('^[\w-]+$', os):
                self.set('os', os)
                self.set('evaluate', self.language)
                self.set('write', True)
                self.set('read', True)

                expected_rand = str(rand.randint_n(2))
                if expected_rand == self.execute('echo %s' % expected_rand):
                    self.set('execute', True)
                    self.set('bind_shell', True)
                    self.set('reverse_shell', True)
Ejemplo n.º 14
0
    def test_upload(self):
        template = 'AAAA%sAAAA'

        channel = Channel({
            'url' : 'http://127.0.0.1:15001/reflect/jinja2?inj=*'
        })
        jinja2obj = Jinja2(channel)
        jinja2obj.detect()
        del channel.data['os']
        self.assertEqual(channel.data, self.expected_data)
        
        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        
        # Send long binary
        data = open('/bin/ls', 'rb').read()
        jinja2obj.write(data, remote_temp_path)
        self.assertEqual(jinja2obj._md5(remote_temp_path), strings.md5(data))
        jinja2obj.execute('rm %s' % (remote_temp_path))
        
        # Send short ASCII data, without removing it
        data = 'SHORT ASCII DATA'
        jinja2obj.write(data, remote_temp_path)
        self.assertEqual(jinja2obj._md5(remote_temp_path), strings.md5(data))

        # Try to append data without --force-overwrite and re-check the previous md5
        jinja2obj.write('APPENDED DATA', remote_temp_path)
        self.assertEqual(jinja2obj._md5(remote_temp_path), strings.md5(data))
        
        # Now set --force-overwrite and rewrite new data on the same file
        jinja2obj.channel.args['force_overwrite'] = True
        data = 'NEW DATA'
        jinja2obj.write(data, remote_temp_path)
        self.assertEqual(jinja2obj._md5(remote_temp_path), strings.md5(data))
        jinja2obj.execute('rm %s' % (remote_temp_path))
Ejemplo n.º 15
0
    def rendered_detected(self):

        randA = rand.randstr_n(2)

        # Check this to avoid false positives
        payload = 'p %s' % randA
        expected = '<p>%s</p>' % randA

        if expected == self.render(payload):

            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            os = self.evaluate(
                """global.process.mainModule.require('os').platform()""")
            if os and re.search('^[\w-]+$', os):
                self.set('os', os)
                self.set('evaluate', self.language)
                self.set('write', True)
                self.set('read', True)

                expected_rand = str(rand.randint_n(2))
                if expected_rand == self.execute('echo %s' % expected_rand):
                    self.set('execute', True)
                    self.set('bind_shell', True)
                    self.set('reverse_shell', True)
Ejemplo n.º 16
0
    def test_upload(self):

        channel = Channel({
            'url' : 'http://127.0.0.1:15002/smarty-3.1.29-unsecured.php?inj=*'
        })
        smartyobj = Smarty(channel)
        smartyobj.detect()
        del channel.data['os']
        self.assertEqual(channel.data, self.expected_data)
        
        remote_temp_path = '/tmp/tplmap_%s.tmp' % rand.randstr_n(10)
        
        # Send long binary
        data = open('/bin/ls', 'rb').read()
        smartyobj.write(data, remote_temp_path)
        self.assertEqual(smartyobj._md5(remote_temp_path), strings.md5(data))
        smartyobj.execute('rm %s' % (remote_temp_path))
        
        # Send short ASCII data, without removing it
        data = 'SHORT ASCII DATA'
        smartyobj.write(data, remote_temp_path)
        self.assertEqual(smartyobj._md5(remote_temp_path), strings.md5(data))

        # Try to append data without --force-overwrite and re-check the previous md5
        smartyobj.write('APPENDED DATA', remote_temp_path)
        self.assertEqual(smartyobj._md5(remote_temp_path), strings.md5(data))
        
        # Now set --force-overwrite and rewrite new data on the same file
        smartyobj.channel.args['force_overwrite'] = True
        data = 'NEW DATA'
        smartyobj.write(data, remote_temp_path)
        self.assertEqual(smartyobj._md5(remote_temp_path), strings.md5(data))
        smartyobj.execute('rm %s' % (remote_temp_path))
Ejemplo n.º 17
0
    def detect(self):

        self._detect_dust()

        if self.get('engine'):
    
            log.info('%s plugin has confirmed injection' % (
                self.plugin)
            )
            
            # Clean up any previous unreliable render data
            self.delete('unreliable_render')
            self.delete('unreliable')

            # Further exploitation requires if helper, which has
            # been deprecated in version [email protected] .
            # Check if helper presence here.

            rand_A = rand.randstr_n(2)
            rand_B = rand.randstr_n(2)
            rand_C = rand.randstr_n(2)
            
            expected = rand_A + rand_B + rand_C

            if expected in self.inject('%s{@if cond="1"}%s{/if}%s' % (rand_A, rand_B, rand_C)):
                
                log.info('%s plugin has confirmed the presence of dustjs if helper <= 1.5.0' % (
                    self.plugin)
                )            
        
        # Blind inj must be checked also with confirmed rendering
        self._detect_blind()

        if self.get('blind'):

            log.info('%s plugin has confirmed blind injection' % (self.plugin))

            # Clean up any previous unreliable render data
            self.delete('unreliable_render')
            self.delete('unreliable')

            # Set basic info
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            # Set the environment
            self.blind_detected()
Ejemplo n.º 18
0
    def detect(self):

        self._detect_dust()

        if self.get('engine'):
    
            log.info('%s plugin has confirmed injection' % (
                self.plugin)
            )
            
            # Clean up any previous unreliable render data
            self.delete('unreliable_render')
            self.delete('unreliable')

            # Further exploitation requires if helper, which has
            # been deprecated in version [email protected] .
            # Check if helper presence here.

            rand_A = rand.randstr_n(2)
            rand_B = rand.randstr_n(2)
            rand_C = rand.randstr_n(2)
            
            expected = rand_A + rand_B + rand_C

            if expected in self.inject('%s{@if cond="1"}%s{/if}%s' % (rand_A, rand_B, rand_C)):
                
                log.info('%s plugin has confirmed the presence of dustjs if helper <= 1.5.0' % (
                    self.plugin)
                )            
        
        # Blind inj must be checked also with confirmed rendering
        self._detect_blind()

        if self.get('blind'):

            log.info('%s plugin has confirmed blind injection' % (self.plugin))

            # Clean up any previous unreliable render data
            self.delete('unreliable_render')
            self.delete('unreliable')

            # Set basic info
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            # Set the environment
            self.blind_detected()
Ejemplo n.º 19
0
    def rendered_detected(self):

        randA = rand.randstr_n(3)

        # {{7*'7'}} and a{#b#}c work in freemarker as well
        # {%% set a=%i*%i %%}{{a}} works in Nunjucks as well
        payload = '{{"%s\n"|nl2br}}' % (randA)
        expected = "%s<br />" % (randA)

        if expected == self.render(payload):
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)
Ejemplo n.º 20
0
    def rendered_detected(self):

        randA = rand.randstr_n(3)

        # {{7*'7'}} and a{#b#}c work in freemarker as well
        # {%% set a=%i*%i %%}{{a}} works in Nunjucks as well
        payload = '{{"%s\n"|nl2br}}' % (randA)
        expected = "%s<br />" % (randA)

        if expected == self.render(payload):
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)
Ejemplo n.º 21
0
    def rendered_detected(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s<#--%s-->%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.render(payload):
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            expected_rand = str(rand.randint_n(2))
            if expected_rand == self.execute('echo %s' % expected_rand):
                self.set('execute', True)
                self.set('write', True)
                self.set('read', True)
                self.set('bind_shell', True)
                self.set('reverse_shell', True)

                os = self.execute("""uname""")
                if os and re.search('^[\w-]+$', os):
                    self.set('os', os)
Ejemplo n.º 22
0
    def rendered_detected(self):

        randA = rand.randstr_n(1)
        randB = rand.randstr_n(1)

        payload = '%s<#--%s-->%s' % (randA, rand.randstr_n(1), randB)
        expected = randA + randB

        if expected == self.render(payload):
            self.set('engine', self.plugin.lower())
            self.set('language', self.language)

            expected_rand = str(rand.randint_n(2))
            if expected_rand == self.execute('echo %s' % expected_rand):
                self.set('execute', True)
                self.set('write', True)
                self.set('read', True)
                self.set('bind_shell', True)
                self.set('reverse_shell', True)

                os = self.execute("""uname""")
                if os and re.search('^[\w-]+$', os):
                    self.set('os', os)