Phrozen Timeline

Assignment Goals (SLAE-1530)

  • Create a custom crypter like the one shown in the "crypters" video

  • Free to use any existing encryption schema

  • Can use any programming language

What is the purpose of a Crypter

A crypter is very close to encoders. It is a tiny application designed to encrypt a payload and decrypt the payload at runtime.

The payload is encrypted and embedded inside a host program often called a stub, when the stub is executed, it will decrypt the encrypted payload and redirect execution flow at decrypted payload address. Sometimes execution flow is not redirected but instead a new thread or a new process is created to host the payload execution.

Conversely to encoders, crypters uses complexes encryptions schema (RC4, AES, Blowfish, Camelia etc...) to keep the payload obfuscated. Each time a stub is generated, the encrypted payload will look completely different, it is a good solution to beat signature based detection systems.

Because of their complexity, crypters are often coded with higher level language such as C/C++, Delphi, .NET etc..

Read more...

Assignment Goals ( SLAE-1530)

  • Take up 3 shellcodes from Shell-Storm and create polymorphic versions of them to beat pattern matching.

  • The polymorphic versions cannot be larger 150% of the existing shellcode.

  • Bonus points for making it shorter in length than original.

Foreword

On Shell-Storm, you will not always find the original assembly code for shellcodes you choose. To solve this issue, we've created a tiny Python script to convert a shellcode from its string form to raw format (stdout). We can easily pipe output result to Ndisasm and recover an assembly code very close to the original version.

Read more...

Assignment Goals (SLAE-1530)

  • Take up at least 3 shellcode samples created using Msfpayload for Linux/x86.

  • Use GDB/Ndisasm/Libemu to dissect the functionality of the shellcode.

  • Present your analysis.

Shellcode Candidates

We will use Msfvenom from Metasploit Framework to generate three different payloads for Linux x86-32.

We can easily enumerate payloads for this architecture and operating system using the following command:

local@user:$ msfvenom -l payloads | grep "linux/x86"

We decided to use the three following payloads:

  1. linux/x86/read_file
  2. linux/x86/chmod
  3. linux/x86/exec
Read more...

Assignment Goals (SLAE-1530)

  • Create a custom encoding scheme.

  • PoC with using execve-stack as the shellcode.

Creating our own encoder

Shellcode encoders are useful for two main reasons:

  • Minimize the risk of getting cough by detection systems.
  • Avoid bad characters from our original shellcode.

An encoder take a shellcode in input and output a different looking shellcode without affecting it functionality.

The main disadvantage with encoding is that your shellcode size will naturally increase.

Read more...

Assignement Goals (SLAE-1530)

1) Study about the Egg Hunter shellcode.

2) Create a working demo of the Egghunter.

3) Should be configurable for different payloads.

What is an Egg Hunter Shellcode ?

An egg hunter is a very small piece of shellcode designed to find another shellcode in memory (usually a bigger one). To do so, it scans the whole process memory in search of a special pattern. This pattern is called an egg and is preceded from the the second and bigger shellcode. When an egg is found in memory, the egg hunter shellcode will redirect execution flow to the second one.

An egg is composed of 4 bytes (the size of a memory address in x86-32 processors) for example 0x44434241 (ABCD Little Endian). We generally repeat the egg once to avoid "collisions".

Imagine if we choose ABCD as our egg, ABCD is a common string and we could find this pattern at multiple memory location but ABCDABCD less likely.

ABCD is not a good choice anyway since it is too common, even if we repeat it. It is important to choose something you don't often see in programs and memory, for example egg! or 3gg!.

Read more...

Assignment Goals (SLAE-1530)

1) Create a TCP Reverse Shellcode for Linux x86-32.

2) The port number should be easily configurable.

3) The IP address should be easily configurable.

3) Bonus if getting referenced in exploit-db or shell-storm.

TCP Reverse Shell Principle

In first exercise we learnt how to create our own TCP Bindshell shellcode using few syscalls (socketcall(), dup2() and execve()).

A reverse shell is almost identical to a classic bindshell, this time instead of having a shellcode that listen for new clients, we will create a shellcode that will connect back to a remote server.

Fortunately, on Linux by default, we do not have any restrictions to manage sockets in client mode.

Read more...

Weakness Description

Microsoft Windows suffer from a serious lack of protection in their authentication mechanism which could led in privilege escalation.

Indeed, in default installation of Windows (all version), the account lockdown policy is disabled plus authentication API's doesn't limit number of attempts per seconds which could led to a medium to fast brute-force attacks.

Using our PoC and depending of the number of cores available in the target system you could test from few thousands to dozen of thousands of password per second.

Considering that those kind of authentication API's could be used by any Windows account, even a Guest user could use the PoC to recover / crack the password of any local user and escalate his privilege.

Read more...

Bellow script demonstrate how to create a very basic multithreaded web file and directory fuzzer.

It is far from being as fast as other famous web fuzzers (wfuzz, dirb, gobuster etc..) but it is at least a good start to understand how to create yours.

#!/bin/python3

'''
    -= Just a web fuzzer example =-
    (@DarkCoderSc)

    Dependencies:
        - pip install progressbar2
'''

import requests
import progressbar 
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
from multiprocessing import Lock
import argparse

#
# Acquire parameters
#
parser = argparse.ArgumentParser(description="Just a web fuzzer example")

parser.add_argument('-u', '--url', action="store", dest="base_url", required=True, help="Target base URL to fuzz (ex: http://example.com/")
parser.add_argument('-w', '--wordlist', action="store", dest="wordlist_file", metavar="in-file", type=argparse.FileType('r'), required=True, help="Plain text wordlist file location.")
parser.add_argument('-x', '--extensions', action="store", dest="extensions", nargs='*', required=False, help="Append file extension at the end of each candidates (ex: .php .php5 .html .html5)")

try:
    argv = parser.parse_args()
except IOError:
    parser.error()


#
# Log Defs
#
def success(message):
    print("[\033[32mOK\033[39m] " + message)

def fail(message):
    print("[\033[31mKO\033[39m] " + message)

def debug(message):
    print("[\033[33m!!\033[39m] " + message)


#
# Fuzzer
#
def fuzz(args):
    lock = args[0]
    pbar = args[2]

    global base_url

    target_url = base_url + args[1]

    req = requests.head(target_url)

    status = req.status_code

    message = "{} - {}".format(status, target_url)

    if (status == 200):
        success(message)
    elif (status != 404):
        debug(message)

    lock.acquire()
    try:                   
        global progress

        progress += 1

        pbar.update(progress)
    finally:
        lock.release()   
    return

base_url = argv.base_url
if not base_url.endswith("/"):
    base_url += "/"

with open(argv.wordlist_file.name, "r", errors="ignore") as file:
    candidates = file.readlines()

    widgets = [
        ' [', progressbar.Timer(), '] ',
        progressbar.Bar(),
        ' (', progressbar.ETA(), ') ',
    ]

    ext_count = 1
    if argv.extensions:
        ext_count = len(argv.extensions) +1

    pbar = progressbar.ProgressBar(maxval=(len(candidates) * ext_count), widgets=widgets, redirect_stdout=True)         

    progress = 0

    pbar.start()
    try:
        pool = ThreadPool()
        try:    
            lock = Lock()

            for index, candidate in enumerate(candidates):
                candidate = candidate.strip()            

                if not candidate:
                    continue

                pool.map(fuzz, [[lock, candidate, pbar]])

                if (ext_count > 1):
                    for extension in argv.extensions:
                        pool.map(fuzz, [[lock, (candidate + extension), pbar]])            

        finally:
            pool.close()
            pool.join()
    finally:
        pbar.finish()
Read more...

Description

This Delphi unit demonstrate how to manipulate EOF Data of a Valid Microsoft Windows Portable Executable (PE) File.

EOF (End Of File) is often used by Malware authors to offer their Malware users a way to edit Malware payload configuration (Ex: C2 informations) without having access to source code.

You often encounter such techniques in:

  • Remote Access Tool/Trojan (RAT)
  • File Wrapper / Binder
  • Downloader
  • Loader / Botnets
Read more...

Tiny snippet to know whether or not target process id is running under 32bit or 64bit architecture.

If result is True, target process is running under 64bit architecture.

If result is False, target process is running under 32bit architecture.

// ...

uses Windows, SysUtils;

// ...
type
  TArchitecture = (x86, x64, xUnknown);
// ...

function IsProcessX64(AProcessId : Cardinal) : TArchitecture;
var AProcHandle   : THandle;
    AWow64Process : bool;
begin
  result := xUnknown;
  ///

  {
    If we are not in a 64Bit system then we are for sure in a 32Bit system
  }
  if (TOSVersion.Architecture = arIntelX86) then
    Exit();
  ///

  AProcHandle := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, AProcessId);
  if AProcHandle = 0 then
    Exit;
  try
    isWow64Process(AProcHandle, AWow64Process);
    ///

    if AWow64Process then
      result := x86
    else
      result := x64;
  finally
    CloseHandle(AProcHandle);
  end;
end;
Read more...