Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Friday, July 31, 2020

Decrypt Aisuru Bot Encoded Strings with Qiling Framework

Qiling is an advanced binary emulation framework, with the following features:

  • Cross platform: Windows, MacOS, Linux, BSD, UEFI
  • Cross architecture: X86, X86_64, Arm, Arm64, MIPS
  • Multiple file formats: PE, MachO, ELF
  • Emulate & sandbox machine code in a isolated environment
  • Supports cross architecture and platform debugging capabilities
  • Provide high level API to setup & configure the sandbox
  • Fine-grain instrumentation: allow hooks at various levels (instruction/basic-block/memory-access/exception/syscall/IO/etc)
  • Allow dynamic hotpatch on-the-fly running code, including the loaded library
  • True framework in Python, making it easy to build customized security analysis tools on top

Qiling is backed by Unicorn engine.

Using Qiling is very easy and since it can emulate & sandbox machine code we can take advantage of it to run malicious code/malware without affecting the host.

Statically looking at the strings of "aisuru" bot we can see that it employs some encoding scheme.


These strings are then fed to a function sequentially to get the decrypted string.


The function "sub_80482A0" helps in decoding the encoded strings. Instead of reversing or debugging the function we can use Qiling to get the decoded string.



For this particular case to get the decoded string we could need the following inputs to Qiling,

  1. The binary
  2. Address of the encoded string
  3. Start and End addresses of the function that decodes the string
  4. Address of the decoded string after the function has successfully run
(1). 552b07d4f8f611841eeb9a608c3d6e8526563b96df0b6676267dc274c1195853

(2). The addresses of the encoded strings starts from "0x080525A0" and goes on. Each of the encoded string needs to be put into EAX register and the decoding function has to be called.

(3). The decoding function starts at address "0x080482A0" and ends at "0x08048370".

(4). After some poking around the registers I was able to conclude that the register EDX holds the address of the decoded string.

We now have all the relevant inputs that Qiling requires. With just few lines of python script we can dump all the decoded strings. Below code does that job for us,





The decrypted string list where commands, C2, paths etc are visible now.


References
  1. https://n1ght-w0lf.github.io/tutorials/qiling-for-malware-analysis-part-2/

Sunday, December 22, 2019

WinDbg pykd 101 - Dumping Meterpreter Payload

WinDbg is a kernel-mode and user-mode debugger that is included in Debugging Tools for Windows. WinDbg has a very powerful scripting language but using it can sometimes be very annoying. Alternatively there's an extension "pykd" that can used to run python scripts to automate various repetitive tasks while debugging.

In this blog post we'll see how to use pykd to automate dumping of Metrepreter DLL injected into legitimate process memory. For purpose of demonstration I injected Merterpreter DLL into a "notepad" process. We can take a look at the notepad process memory using "Process Hacker".


The highlighted memory sections are suspicious since it doesn't belong to any of the loaded modules and it has a memory protection value of "RWX". As you can see the other loaded modules have a memory protection value of "RX".

Looking at one of the memory sections reveals the Meterpreter DLL payload (there's another section that has the shellcode for reflectively loading the DLL). We can dump the notepad process and load the same into WinDbg.



The headers of the DLL in WinDbg at that memory location from notepad process.



Now we can automate the payload dumping part using pykd. To load pykd first copy the "pykd.dll" (according to the architecture) under the "winext" directory in WinDbg folder. I'm using a 64 bit version of WinDbg so my extension folder is under "\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext".

Once done load the extension using "!load pykd" command. If everything worked well you should see no output :)

The python script will be used to dump the memory section that contains traces of Meterpreter related strings. The script does the following,

  1. Search for the pattern (using 's' command)
  2. Check the pattern's associated memory region  (using '!vprot' command)
  3. Gets the base address & region size of the memory section (output from vprot)
  4. Dump the memory section (using '.writemem' command)
You can get the python shell post loading of pykd extension using "!py" command.



To interact with WinDbg you can use the "pykd.dbgCommand". All WinDbg commands can be executed using this function and the output can be displayed or saved to a variable.

During analysis it was found that the Meterpreter payload has a unique pattern ('[REU') in the MZ header section. Lets use that term and search it throughout the process memory.



Using the above we can write our logic into a python file and run it inside WinDbg using pykd extension. To run the python file use the "!py " format. The complete script looks like below,

from pykd import *
import sys

def get_val(data, index):
 data = data.splitlines()
 for i in data:
  if index in i:
   val = i.split(':')[1].strip()
   return val
 return False

if len(sys.argv) < 3:
 print("Usage !py " + sys.argv[0] + "  ")
 exit(1)

pattern = sys.argv[2]
directory = sys.argv[1]

res = pykd.dbgCommand("s -a 0 L?80000000 " + pattern)

if res == None:
 print("[*] Pattern not found!")
 exit(1)

res = res.splitlines()

for i in res:
 addr = i.split("  ")[0]
 vprot_res = pykd.dbgCommand("!vprot %s" % addr)
 base_addr = get_val(vprot_res, "BaseAddress")
 region_size = get_val(vprot_res, "RegionSize")

 if base_addr and region_size:
  filename = directory + "\\" + base_addr + ".bin"
  cmd = ".writemem %s %s L?%s" % (filename, base_addr, region_size)
  pykd.dbgCommand(cmd)
  print("[*] Wrote memory dump to: %s of size %s from base address: %s" % (filename, region_size, base_addr))

The script takes the output directory and search string as input and dump the associated memory section. There's lot of scope for further improving the script :)



Looking at the dumped file inside PE studio confirms it is a DLL.



References:

https://rayanfam.com/topics/pykd-tutorial-part1/