Example #1
0
def encodeShellcode(base_address, shellcode):
  base_address_parsed = re.match(REG % '|'.join(NOP.keys()), base_address, re.IGNORECASE)
  if base_address_parsed is None:
    raise Exception("Cannot parse \"%s\"." % base_address)

  base_address_register = base_address_parsed.group("R")
  nop = NOP[base_address_register.lower()];
  base_address_offset = ALPHA3.toInt(base_address_parsed.group("I"))
  nopslide_size = ALPHA3.toInt(base_address_parsed.group("V"))

  patcher = ALPHA3.io.ReadFile("[%s+i32] - EDX.bin" % base_address_register, LOCAL_PATH)
  patch_offset = nopslide_size + len(patcher)

  ALPHA3.PrintVerboseStatusLine("Return address",   "%s+%X"    % (base_address_register, base_address_offset))
  ALPHA3.PrintVerboseStatusLine("Nopslide size",    "%X"       % (nopslide_size,))
  ALPHA3.PrintVerboseStatusLine("Patcher size",     "%X"       % (len(patcher),))
  ALPHA3.PrintVerboseStatusLine("Countslide size",  "%X"       % (nopslide_size,))
  ALPHA3.PrintVerboseStatusLine("Patch address",    "%s+%X+%X" % (base_address_register, base_address_offset, patch_offset))

  base_address_offset_encoded = ALPHA3.encode.dwx_IMUL_30_XOR_dwy(
      base_address_offset, "encoded base address offset", 
     ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
  patch_offset_encoded = ALPHA3.encode.dwx_IMUL_30_XOR_dwy(
      patch_offset, "encoded patch offset",ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
  patcher = ALPHA3.encode.injectCodes(patcher, base_address_offset_encoded +
      patch_offset_encoded)
  countslide = (nop * nopslide_size + patcher + COUNT * nopslide_size)
  return countslide + ALPHA3.x86.ascii.mixedcase.rm32.encodeShellcode("edx", shellcode);
Example #2
0
def RunEncoderTest(encoder_settings, base_address, test_args, int3):
  for i in range(len(test_args)):
    test_args[i] = test_args[i].replace("%shellcode%", "con")
  if (encoder_settings["architecture"] == "x86"):
    shellcode_file = TEST_X86_SHELLCODE_FILE
    shellcode = TEST_X86_SHELLCODE
    test_command = TEST_X86
  elif (encoder_settings["architecture"] == "x64"):
    shellcode_file = TEST_X64_SHELLCODE_FILE
    shellcode = TEST_X64_SHELLCODE
    test_command = TEST_X64
  else:
    ALPHA3.PrintVerboseStatusLine("Problem", "Encoder uses untestable architecture.")
    return ["[%s] Has an untestable architecture \"%s\"" % (encoder_settings["name"], architecture)]
  # Encode shellcode
  if "function args" in encoder_settings:
    encoder_function_args = encoder_settings["function args"];
  else:
    encoder_function_args = {};
  encoded_shellcode = encoder_settings["function"](base_address, shellcode, *encoder_function_args)
  encoding_errors = CheckEncodedShellcode(encoded_shellcode, encoder_settings)
  if encoding_errors:
    ALPHA3.PrintVerboseStatusLine("Problem", "Encoder failed to encode correctly.")
    return ["[%s] created encoded shellcode with bad characters for base address \"%s\":" % (
        encoder_settings["name"], base_address)] + encoding_errors
  # Create test command line:
  if int3 and "--int3" not in test_args:
    test_args += ["--int3"]
  test_args += ["--EH"]
  command = "\"%s\" %s" % (test_command, " ".join(test_args))
  # Output encoder and test command lines:
  ALPHA3.PrintVerboseStatusLine("Encode command", "ALPHA3.py %s %s %s %s --input=\"%s\"" % (
      encoder_settings["architecture"], encoder_settings["character encoding"], encoder_settings["case"], 
      base_address, ALPHA3.io.ShortPath(shellcode_file)))
  ALPHA3.PrintVerboseStatusLine("Test command", "\"%s\" %s" % (
      ALPHA3.io.ShortPath(test_command), " ".join(test_args)))
  # Print test command line:
  try:
    popen = subprocess.Popen(command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  except WindowsError, e:
    if e.winerror == 193: # not a valid Win32 application
      ALPHA3.PrintVerboseStatusLine("Problem", "Encoder cannot be tested on your platform (ignored).")
      return None
    raise
Example #3
0
def encodeShellcode(base_address, shellcode):
  base_address = ALPHA3.toInt(base_address)
  encoded_base_address = ALPHA3.encode.dwx_IMUL_by(base_address, 
      "encoded base address", ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
  if encoded_base_address is not None:
    decoder = ALPHA3.io.ReadFile("dwx_IMUL_by.bin", LOCAL_PATH)
  else:
    encoded_base_address = ALPHA3.encode.dwx_IMUL_30_XOR_dwy(base_address,
        "encoded base address", ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
    decoder = ALPHA3.io.ReadFile("dwx_IMUL_30_XOR_dwy.bin", LOCAL_PATH)
  decoder = ALPHA3.encode.injectCodes(decoder, encoded_base_address)
  return ALPHA3.encode.encodeData(decoder, shellcode,
     ALPHA3.encode.bx_IMUL_30_XOR_by, # Use this encoding function
     ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])  # And these characters to encode
Example #4
0
def dwx_IMUL_30_XOR_dwy(value, status, valid_values):
    dwx, carry = makeValid(0, 4, valid_values)
    dwy, carry = makeValid(0, 4, valid_values)
    for byte in range(0, 4):
        byte_mask = 0xFF << (byte * 8)
        while 1:
            dwx_IMUL_30_XOR_dwy = ((dwx * 0x30) ^ dwy) & 0xFFFFFFFF
            ALPHA3.PrintVerboseStatus(
                status,
                "%08X * 30 ^ %08X == %08X" % (dwx, dwy, dwx_IMUL_30_XOR_dwy))
            if (dwx_IMUL_30_XOR_dwy & byte_mask) == (value & byte_mask):
                break  # OK: next byte
            x_byte = (dwx & byte_mask) >> (byte * 8)
            next_x_byte, carry = makeValid(x_byte + 1, 1, valid_values)
            dwx = (dwx & (0xFFFFFFFF ^ byte_mask)) ^ (next_x_byte <<
                                                      (byte * 8))
            if carry:
                y_byte = (dwy & byte_mask) >> (byte * 8)
                next_y_byte, carry = makeValid(y_byte + 1, 1, valid_values)
                dwy = (dwy & (0xFFFFFFFF ^ byte_mask)) ^ (next_y_byte <<
                                                          (byte * 8))
                assert carry == 0, "Cannot encode value!"  # Should never happen!
    ALPHA3.PrintVerboseStatus()
    return [dwx, dwy]
Example #5
0
def TestEncoder(encoder_settings, base_address, int3):
    assert "tests" in encoder_settings and encoder_settings["tests"], (
        "No tests found in [%s] encoder." % (encoder_settings["name"]))
    problems = []
    test_count = 0
    error_count = 0
    for test_base_address, test_args in encoder_settings["tests"].items():
        if base_address is None or test_base_address.lower(
        ) == base_address.lower():
            if test_count == 0:
                ALPHA3.PrintVerboseSeparator()
                base_address_test_found = True
            else:
                ALPHA3.PrintVerboseLine()
            if ALPHA3.g_output_verbosity_level == 0:
                ALPHA3.PrintStatus("[%s]" % encoder_settings["name"],
                                   "Test %d" % test_count)
            ALPHA3.PrintVerboseCenteredLine(
                "Testing encoder [%s] with base address \"%s\"" %
                (encoder_settings["name"], test_base_address))
            # Run test
            test_count += 1
            test_errors = RunEncoderTest(encoder_settings, test_base_address,
                                         test_args, int3)
            if test_errors:
                error_count += 1
                problems += test_errors
    if test_count == 0:
        if base_address is None:  # No filter, there are no tests!
            problems += [
                "Encoder [%s] has no tests." % encoder_settings["name"]
            ]
    else:
        ALPHA3.PrintVerboseLine()
        # Create a result message:
        if error_count:
            passed_tests_message = "%d/%d tests." % (test_count - error_count,
                                                     test_count)
        else:
            passed_tests_message = "all %d tests." % (test_count)
        if ALPHA3.g_output_verbosity_level == 0:
            ALPHA3.PrintStatusLine("[%s]" % encoder_settings["name"],
                                   "Passed %s" % passed_tests_message)
        else:
            ALPHA3.PrintVerboseCenteredLine(
                "Encoder [%s] passed %s" %
                (encoder_settings["name"], passed_tests_message))
    return problems
Example #6
0
def encodeShellcode(base_address, shellcode):
    base_address = ALPHA3.toInt(base_address)
    encoded_base_address = ALPHA3.encode.dwx_IMUL_by(
        base_address, "encoded base address",
        ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
    if encoded_base_address is not None:
        decoder = ALPHA3.io.ReadFile("dwx_IMUL_by.bin", LOCAL_PATH)
    else:
        encoded_base_address = ALPHA3.encode.dwx_IMUL_30_XOR_dwy(
            base_address, "encoded base address",
            ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
        decoder = ALPHA3.io.ReadFile("dwx_IMUL_30_XOR_dwy.bin", LOCAL_PATH)
    decoder = ALPHA3.encode.injectCodes(decoder, encoded_base_address)
    return ALPHA3.encode.encodeData(
        decoder,
        shellcode,
        ALPHA3.encode.bx_IMUL_30_XOR_by,  # Use this encoding function
        ALPHA3.charsets.valid_charcodes["ascii"]
        ["mixedcase"])  # And these characters to encode
Example #7
0
def encodeShellcode(base_address, shellcode):
    base_address = re.match(REG, base_address, re.IGNORECASE)

    nopslide_size = ALPHA3.toInt(base_address.group("V"))
    base_address = ALPHA3.toInt(base_address.group("I"))

    patcher = ALPHA3.io.ReadFile("[i32] - ECX.bin", LOCAL_PATH)
    patch_address = base_address + nopslide_size + len(patcher)

    ALPHA3.PrintVerboseStatusLine("return address", "%08X" % base_address)
    ALPHA3.PrintVerboseStatusLine("nopslide size", "%X" % nopslide_size)
    ALPHA3.PrintVerboseStatusLine("patcher size", "%X" % len(patcher))
    ALPHA3.PrintVerboseStatusLine("countslide size", "%X" % nopslide_size)
    ALPHA3.PrintVerboseStatusLine("patch address", "%08X" % patch_address)

    patch_address_encoded = ALPHA3.encode.dwx_IMUL_30_XOR_dwy(
        patch_address, "encoded patch address",
        ALPHA3.charsets.valid_charcodes["ascii"]["mixedcase"])
    patcher = ALPHA3.encode.injectCodes(patcher, patch_address_encoded)
    countslide = (NOP * nopslide_size + patcher + COUNT * nopslide_size)
    return countslide + ALPHA3.x86.ascii.mixedcase.rm32.encodeShellcode(
        "ecx", shellcode)
Example #8
0
  ALPHA3.PrintVerboseStatusLine("Encode command", "ALPHA3.py %s %s %s %s --input=\"%s\"" % (
      encoder_settings["architecture"], encoder_settings["character encoding"], encoder_settings["case"], 
      base_address, ALPHA3.io.ShortPath(shellcode_file)))
  ALPHA3.PrintVerboseStatusLine("Test command", "\"%s\" %s" % (
      ALPHA3.io.ShortPath(test_command), " ".join(test_args)))
  # Print test command line:
  try:
    popen = subprocess.Popen(command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  except WindowsError, e:
    if e.winerror == 193: # not a valid Win32 application
      ALPHA3.PrintVerboseStatusLine("Problem", "Encoder cannot be tested on your platform (ignored).")
      return None
    raise
  stdout_data, stderr_data = popen.communicate(encoded_shellcode)
  if (stdout_data == TEST_SHELLCODE_OUTPUT and stderr_data == ""):
    ALPHA3.PrintVerboseStatusLine("Result", "Success")
    return None
  ALPHA3.PrintVerboseStatusLine("Result", "Failed")
  return ["[%s] failed test for base address \"%s\"" % (encoder_settings["name"], base_address),
      "  stdout: %s" % repr(stdout_data),
      "  stderr: %s" % repr(stderr_data)]

def CheckEncodedShellcode(encoded_shellcode, encoder_settings):
  valid_chars = ALPHA3.charsets.valid_chars[encoder_settings["character encoding"]][encoder_settings["case"]]
  errors = []
  index = 0
  for char in encoded_shellcode:
    if char not in valid_chars:
      charcode_str = ALPHA3.charsets.charcode_fmtstr[encoder_settings["character encoding"]] % ord(char)
      errors += ["  Byte %d @0x%02X: %s (%s)" % (index, index, char, charcode_str)]
    index += 1
Example #9
0
def parent_path(path, parents):
  while parents > 0:
    parents -= 1
    path = os.path.split(path)[0]
  return path
sys.path.append(parent_path(__file__, 5))
import ALPHA3


def XX_IMUL_30_XOR_YY_XOR_XX(result, valid_values): # Find a way to encode a byte
  for XX in valid_values:
    XX_IMUL_30 = (XX * 0x30) & 0xFF
    for YY in valid_values:
      XX_IMUL_30_XOR_YY_XOR_XX = XX_IMUL_30 ^ YY ^ XX
      if XX_IMUL_30_XOR_YY_XOR_XX == result:
        return XX, YY
  raise AssertionError("Cannot encode %02X" % (result,))

def PrintValues(i):
  XX, YY = XX_IMUL_30_XOR_YY_XOR_XX(i, ALPHA3.ascii.mixedcase.VALUES)
  print "%02X %02X: %02X * 30 ^ %02X ^ %02X == %02X" % (XX, YY, XX, YY, XX, i)

if __name__ == "__main__":
  if len(sys.argv) == 2:
    i = ALPHA3.toInt(sys.argv[1])
    PrintValues(i)
  else:
    for i in range(0xFF):
      PrintValues(i)
  
Example #10
0

sys.path.append(parent_path(__file__, 5))
import ALPHA3


def XX_IMUL_30_XOR_YY_XOR_XX(result,
                             valid_values):  # Find a way to encode a byte
    for XX in valid_values:
        XX_IMUL_30 = (XX * 0x30) & 0xFF
        for YY in valid_values:
            XX_IMUL_30_XOR_YY_XOR_XX = XX_IMUL_30 ^ YY ^ XX
            if XX_IMUL_30_XOR_YY_XOR_XX == result:
                return XX, YY
    raise AssertionError("Cannot encode %02X" % (result, ))


def PrintValues(i):
    XX, YY = XX_IMUL_30_XOR_YY_XOR_XX(i, ALPHA3.ascii.mixedcase.VALUES)
    print "%02X %02X: %02X * 30 ^ %02X ^ %02X == %02X" % (XX, YY, XX, YY, XX,
                                                          i)


if __name__ == "__main__":
    if len(sys.argv) == 2:
        i = ALPHA3.toInt(sys.argv[1])
        PrintValues(i)
    else:
        for i in range(0xFF):
            PrintValues(i)