Thursday, 14 February 2019

Threat Hunting #24 - RDP over a Reverse SSH Tunnel

Establishing an RDP connection over a reverse SSH tunnel using plink.exe and FreeSSHd or equivalent utilities provides the attacker a convenient pseudo VPN access method, via which they can use a mouse and a keyboard to discover and access more systems with less noise and minimum footprint.

Differentiating between a legit and suspicious RDP activity requires serious RDP baselining especially on large and interconnected networks where multiple parties (vendors, IT Help Desk, Network and System Team etc.)  use the same protocol, for legit purposes and in a dynamic way.

In this post we will be covering some artifacts left by this technique that a threat hunter can use to detect this simple yet effective "interactive command and control" procedure.

  • we won't be covering all type of indicators, FireEye did already a great write-up highlighting different type of indicators including network signatures and some forensics related artifacts (registry, TerminalServices-LocalSessionManager logs etc). 
  • For details regarding how to perform RDP Tunneling with FreeSsh and Plink see this nice write up by NetSpi.


PC01| (External Attacker System) <--- SSH (RDP - Account: PC02\IEUser) ---> PC02| (VICTIM System)

Ok, let's start!

On the Victim Machine (PC02), the attacker will execute the following command:

plink.exe -P 80 -C -R -l test -pw test

Now the attacker can open his preferred RDP client (i.e. mstsc, xfreerdp) and connect to the loopback address on port 12345, he will be prompted for a username and password (in our case he will be using  PC02\IEUser).

This will result in the following main indicators:

1.1 EventID 4624 with Logon Type =10 AND  Source IP address = loopback address  and also Source Workstation Name equal to the Account Domain|Subject-Account Name ( both indicators are very abnormal)

1.2. EventID 1149 (TerminalService-RemoteConnectionManger) with confirming the same indicators in 1.1:

Until now we are good, but what if the attacker type the local IP address of PC02 (Victim PC) instead of omitting this field:

plink.exe -P 80 -C -R -l test -pw test

This small command change will completely null-out the 2 first indicators:

Mmmmm... Ok what to do now?

Don't worry EventID 5156 got your back! (very useful for other use cases, we will be discussing in future posts) 

As you can see, all the loopback communications with port 3389 are recorded, which is valid for other port forwarding and/or RDP tunneling utilities.

Another small detail we've observed is that failed logins 4625 are not logged when initiated via the SSH Tunnel:

Hunting with IBM Qradar AQL - Examples:

A) select sourceip, sourceport, destinationip, destinationport from events where eventid=5156 and (sourceport=3389 or destinationport=3389) and (INCIDR('',sourceip) OR INCIDR('',destinationip))

B) select username, sourceip, "Source Workstation" from events where eventid=4624 and "LogonType"=10 and (INCIDR('',sourceip) OR INCIDR('::1/128',sourceip)) 

Hunting with SIGMA for the same behavior and using sysmon eventid 3 (Network Connect):

You can convert this rule into Splunk or other supported SIEM/Log Management solution hunting queries here, see the following Splunk query example:

(EventID="3" Image="*\\svchost.exe" SourcePort="3389" (DestinationIp="127.*" OR DestinationIp="::1"))


Wednesday, 13 February 2019

Threat Hunting #23 - Microsoft Windows DNS Server / Analytical

DNS queries and responses are a key data source for network defenders in support of incident response as well as intrusion discovery. If these transactions are collected for processing and analytics in a big data system, they can enable a number of valuable security analytic scenarios.

In this post we suppose that you have already configured DNS Analytical and the logs are being forwarded to your Log Management or SIEM solution (not part of this post). Our main objective in this post is to share with you some basic use cases that you can start with to have some visibility on eventual suspicious DNS communications.

The main MS DNS Analytics events we will be using are limited to:
  • 256 - QUEY_RECEIVED -> DNS query
  • 257 - RESPONSE_SUCCESS -> DNS response
Example of 256 event:

QUERY_RECEIVED: TCP=0; InterfaceIP=; Source=; RD=1;; QTYPE=1; XID=33615; Port=65478; Flags=256; PacketData=0x834F01000001000000000000056C6F67696E046C69766503636F6D0000010001; AdditionalInfo = VirtualizationInstanceOptionValue: .

Example of 257 event:

RESPONSE_SUCCESS: TCP=0; InterfaceIP=; Destination=; AA=0; AD=0;; QTYPE=1; XID=706; DNSSEC=0; RCODE=0; Port=55896; Flags=33152; Scope=Default; Zone=..Cache; PolicyName=NULL; PacketData=0x02C2818000010007000000000563746C646C0D77696E646F777375706461746503636F6D0000010001C00C000500010000073700240A6175646F776E6C6F61640D77696E646F7773757064617465056E73617463036E657400C035000500010000006E000F02777509617A75726565646765C054C06500050001000000440008027775026563C068C080000500010000012C001F02777503777063096170722D35326464320B6564676563617374646E73C054C09400050001000000B2001203686C620B6170722D35326464322D30C0A5C0BF00050001000000B2001104637331310377706305763063646EC054C0DD000100010000075300045DB8DDF0; AdditionalInfo= VirtualizationInstance:.

As can be see above, the fields of interest we will need for our use cases are the following:
  • Source or Destination IP of the machine that initiated the DNS request or that will receive the DNS Lookup answer.
  • QNAME that contains the domain name that was requested.
  • QTYPE indicate the requested DNS attribute (A, AAAA, MX, PTR, TXT etc.).
  • RCODE indicate the operation result code (i.e. 0 No-error, 3 Non Existent Domain etc.). 

Use Case 1 - DNS requests to public IP online resolution web services:

Many malwares in the wild implement a first check to verify the public IP of the organization they've already infected and if it's within their targeted geographical scope they will operate accordingly, others implement the same check to avoid malware researchers and/or known online malware sandboxes. Below an example of an AQL hunting query you can use directly or turn it into a detection rule:

select sourceip, "QNAME" from events where (eventid=256 or eventid=257) and QNAME imatches '(?i)((.*myip.*)|(.*ipchicken.*)|(.*ipinfo.*)|(.*ipaddr.*)|(.*meineip.*)|(.*meuip.*)|(.*portquiz.*)|(.*portchecktool.*)|(.*ipid.*)|(.*iptools.*)|(.*hostip.*)|(.*canyouseeme.*))'

Note that you can expand the query to include more known good IP location WebService (to get through WebProxy reputation filters) . 

Use Case 2 - DNS request to suspicious TLDs:

In this UC we will be comparing the queried domain names with a list of less business oriented Top Level Domain (i.e. .xyz, .ninja) which are not necessarily tied to malware or cyber attack activity, but as a Threat Hunter you will need to have this visibility and can be correlated with other building block events (i.e. unsigned program running from programdata and issuing DNS queries to a .xyz TLD). 

For this example we will be using a list for the 2018 Top Shady TLDs by Symantec (note that the malicious TLDs are way more than those 20): 

select sourceip, "QNAME" from events where QNAME IMATCHES '(.*country)|(.*stream)(.*download)|(.*xin)|(.*gdn)|(.*racing)|(.*jetzt)|(.*win)|(.*bid)|(.*vip)|(.*ren)|(.*kim)|(.*loan)(.*mom)|

Use Case 3 - DNS TXT or RRSIG Exfiltration:

A peak of DNS queries of type "TXT" or "RRSIG" (QTYPE=16 or QTYPE=46) may indicate some data exfiltration or DNS tunneling activity, for more information about DNS Query Types check here.

AQL query:

select sourceip, "QNAME", COUNT(*) as cc from events where (eventid=256 or eventid=257) and UTF8(payload) IMATCHES '(?i)((.*QTYPE=16.*)|(.*QTYPE=46.*))' GROUP BY sourceip, QNAME last 7 DAYS

Look for high count in short period (i.e. in 1 day more than 100 of TXT DNS requests from same source IP and the domain is not a known email provider).

Use Case 4 - DGA - Too many NX response from same source IP:

A peak in NXDomain responses (RCODE=3) may indicate a Domain generation algorithm activity (before landing on the newly DGA domain, the malware will perform several attempts, which majority of them are non existent domain names):

select sourceip, "QNAME", COUNT(*) as cc from events where eventid=257 and UTF8(payload) IMATCHES '(?i)(.*QTYPE=1.*RCODE=3.*)' GROUP BY sourceip, QNAME last 7 DAYS 

Use Case 5 - DNS requests to Very Long Domain Names :

Long domain names could be indicative of DGA or malware kill-switch or simply a legit long domain name (we've excluded QTYPE 249 "Transaction Key" for false positives removal):

select qname from events where "EventID"=256 and strlen("QNAME")>30 and not (UTF8(payload) IMATCHES '.*QTYPE=249.*') last 7 DAYS

Use Case 6 - DNS requests to known Dynamic DNS providers:

For this UC, you will need to build a reference list of known dynamic domain providers and map every QNAME of QTYPE=1 (A record) to this list. Example of such as list can be found here.  

Usually ddns are associated either to malware activity or to IoT, like home camera, routers etc. 



Monday, 11 February 2019

IronPort: Password-Protected Archives

One of the main methods attackers use to deliver malicious files to the victim's inbox is adding the file to a password-protected archive and embedding the archive password in the email body either explicitly or in an image. This allows the attacker to bypass the Email security appliance Anti-Virus, IDS, etc.

So, to catch such attacks, we quarantine all incoming emails with protected archives in a special IronPort Quarantine. This quarantine is configured to release its contents after a chosen number of hours e.g. 3 hours. This 3-hour time window gives the SOC analyst the chance to avoid campaigns of 200+ malicious emails going through to the victim's inbox.

 1) We create a new quarantine and call it "Protected_Archives_Q". Setting the "Retention Period" to 3 hours and the "Default Action" to "Release".
Monitor => "Policy, Virus and Outbreak Quarantines" => click "Add Policy Quarantine"

N.B. In the image below, we set the "Retention Period" to 3 hours, but it is up to the SOC team to chose the best value according to their working hours and business needs. Attacks on weekends should be considered. Also, the company having different users in different Time Zones requires the SOC team to have more quarantines, more filters, and more policies. We will discuss that in later posts.

2) We create a new "Content Filter" and call it "Protected_Archives".
"Mail Policies" => "Incoming Content Filters" ==> "Add Filter"

3) We add new condition for compressed file types.
"Add Condition" => "Attachment File Info" => "File Type" => "Is" => "Compressed"

4) We add another condition for protected files.

"Attachment Protection" => "One or more attachments are protected."

5) In the "Apply Rule" dropbox, we select "Only if all conditions match".

6) We add our action, which is to quarantine emails that match the previous two conditions in Step 3 and step 4, in the "Protected_Archives_Q" quarantine.
"Add Action" => "Quarantine" => "Send message to quarantine:" => "Protected_Archives_Q"

Now our content filter looks like below:

7) We finally assign the "Protected_Archive" content filter to the default Incoming Mail Policy.

"Mail Policies" => "Incoming Mail Policies" => "Content Filters" => Select "Enable" on "Protected_Archive"

This is not the end of it. Actually, SOC team has a lot to do when it comes to cases like protected archives. For example, with each false positive e.g. legit sender that happens to send protected archives to your users, the SOC analyst will have to update the filter to exempt "", like below.

Even exempting certain senders (envelope senders) from your filter is not enough, for example, there has to be another content filter to verify "SPF" of e.g. and this SPF filter must be with a less order than "Protect_Archives" i.e. processed first. Don't worry, we will cover this later.

It is also noteworthy that SOC team should make the user aware that e.g. banks never send their customers the password for e.g. statements in the same email as the attachment.

Saturday, 9 February 2019

Threat Hunting #22 - Detecting user accounts set with password to never expire

Having a normal user account's password set to never expire is a bit abnormal, often it will be associated to a service account or to a bad practice of having domain admin like accounts set with Pwd to never expire.

Although it seems to be a trivial idea, I've learned that few pay attention to it (from a security point of view rather than compliance requirements). In this short post we'll be exploring 3 methods for hunting for similar events:

Method 1:

Using AD Explorer.exe you can hunt live using the following search filter:
  • UserAccountControl = 66048 (account enabled and password set to never expire)
  • CN exclude "Service Account" (if you have a different OU for SA, exclude them all so you are left with only normal user accounts)
  • PrimarygroupID=513 (user account)

Here are the values/descriptions for the AD attribute for userAccountControl

512 - Enable Account
514 - Disable account
544 - Account Enabled - Require user to change password at first logon
4096 - Workstation/server
66048 - Enabled, password never expires
66050 - Disabled, password never expires
262656 - Smart Card Logon Required
532480 - Domain controller

Method 2:

Using eventid 4738 "user account was changed" and filtering by Old UAC Value and New UAC Value attributes :

We are looking for the following combination values:

  •  Old UAC Value : 0x10  -> New UAC Value: 0x210
  •  Old UAC Value : 0x11 -> New UAC Value: 0x210
  •  Old UAC Value : 0x15 -> New UAC Value: 0x210

New and Olad UAC values meaning :

0x10: Account Enabled
0x11: Account Disabled
0x210: Account Enabled, Password Never Expires
0x15: Account Disabled, Passwod Not Reruied 
0x211: Account Disabled, Password Never Expires 

Example of an IBM Qradar AQL query:

select "SourceUserName", "TargetAccount", "ChangedAttributes" from events where eventid=4738 and not (UTF8(payload) imatches '(.*0x11.+0x210.*)|(.*0x15.+0x210.*)|(.*0x10.+0x210.*)||(.*0x211.+0x210.*)') last 90 days

Always verify the if TargetAccount is associated to a legit service or not. Pay particular attention when UAC changes from 0x10 to 0x210 (very rare).  Below an example of a matching legit event where the target account name was a service account.

Method 3:

Using sysmon Process Creation event or similar (EDR query language) look for processes with commandline value like "passwordchg''

CBR rule:  cmdline:passwordchg*


Friday, 8 February 2019

Threat Hunting #21 - Hiding in plain sights with real or rogue computer accounts - Part 2/2

In Part 1 of hiding in plain sights with a rogue computer account, we've discussed the problem of filtering false positives based on the presence or not of the "$" sign in the source or destination account name of a specific event.  In this part we will demonstrate how an attacker can use this "technique" and what are the resulting artifacts that an analyst can refer to:

Method 1: using psexec to move laterally 

After obtaining valid domain privileged credentials (we name here EXAMPLE\admin01), the attacker will create a fake computer account (named EXAMPLE\SERVER01) using Net.exe.

This move, will generate an event 4720 User Account Created (instead of 4741 for Computer Account Created):

Next the attacker will use psexec.exe to start a privileged interactive shell from PC01 to the Primary Domain Controller (

This action, will generate some artifacts related to PsExec excution we've already discussed in a previous post. In this case we are more interested by possible artifacts related to the use of the fake/rogue computer account (SERVER01$).

On PC01 (client) you can see below, no file system user profile is loaded (which is expected, no local authentication):

Same for the server side (|DC), no file system or registry user profile is loaded (expected as well, because we are running in the context of a system service PsExec created spoolsrv):

For more information about the different windows user profiles please refer to this article.

Method 2:  Using Net.exe use to move laterally with the fake computer account

Same as for method 1, no user profile is loaded (registry, file system and user profile service application logs). BUT because our authentication went through ntlm, we can see below some event logs that can help us spot the abnormal authentication activity (if monitored):

But, for 4624, not always the source workstation names is populated, only when the authentication package is NTLM, for kerberos it will usually be equal to "-".

Method 3: Logon with explicit credentials using RunAs utility

Same as for method 2,  the authentication will go via NTLM which will generate same artifacts:


  1. No user profile is loaded (file system, registry) for the above remote access methods.
  2. If NTLM is used as the authentication package, the source workstation name will be populated, in 4624, otherwise if it's Kerberos only the source IP will be logged.
  3. Net users or Net users /domain will return only accounts without the $ sign in their names (not necessarily a real computer account).
  4. Implement the use cases we've shared in Part 1/2 of this post. 


IronPort: Blacklisted Attachments

In the next few posts, we will be discussing how to make use of the Email Security Appliance, IronPort, to enhance your enterprise email security. We start today with the list of attachment file extensions you should block.

By blocking these extensions, we mean that emails with such extensions must be quarantined in a specific IronPort "Quarantine" folder.

1) we create a new quarantine and  call it "Attachments_Blacklist_Q". This allows you to later release any false positive emails and also to grab those attachments for malware analysis.

2) Then we create a new "Incoming Content Filter" and call it "Attachments_Blacklist".

3) Withing the new content filter, we add a new "Conditionfor blocking all executables by "File Type". 

Please remember that this is not enough and we have to add all potentially malicious file extensions explicitly.

4) We add the following regular expressions:


In the next post, we will explain reasons behind blocking each of these file extensions.

5) In The "Actions" section, click "Add Action", then select the quarantine folder created in Step 1.

6) Finally, we assign our new content filter to the default policy in the "Incoming Mail Policies" page and commit the changes.

N.B. Please note this requires very careful testing so that you don't cause any business disruption.

Thursday, 7 February 2019

Threat Hunting #20 - Detecting Process Doppelgänging using event 4985

In this post we won't be covering the details of how this process impersonation technique works. There are several good articles detailing the modus operandi of Process Doppelgänging.

In a nutshell, this technique calls several APIs related to NTFS transactions which allow to substitute the PE content before even the process is created.

Interestingly we've found that Windows creates a security event to track NTFS transaction's state changes (EventID=4985):

Trying to baseline what's "normal" for EID 4985 from more than 10 windows servers:

We've observed also on 4 other machines with Win7|Win10 that lsass.exe, svchost.exe and TrustedInstaller.exe are the source of 100% of logged 4985 events.

Testing Process Doppelgänging  on a Windows 7 machine yield the following:


EventID=4985 and LogonID !='0x3E7' or process path not in:

  • c:\windows\system32\svchost.exe
  • c:\windows\system32\lsass.exe|
  • c:\windows\servicing\TrustedInstaller.exe
  • c:\windows\system32\poqexec.exe
  • c:\windows\winSxS\*\TiWorker.exe

Threat Hunting #19 - Procdump or Taskmgr - memory dump

Dumping lsass.exe process memory using procmon.exe or taskmgr.exe (both are signed and trusted microsoft utilities) and then extracting secrets offline is a bit stealthier than running a rogue program.

Using Sysmon event 10 "Process A accessed Process B" and filtering by CallTrace, and TargetImage attribute data, we can detect both process memory dumping actions:

As can be seen above, both utilities call APIs exported by dbghelp.dll or dbgcore.dll to invoke memory dump write functions (i.e. MiniDumpWriteDump function).

Detection Logic:

Sysmon: EventID=10 and CallTrace contains "Dbghelp.dll" or "Dbgcore.dll" and TargetImage=="lsass.exe or any other sensitive process (i.e. Point of Sale related processes or alike)"

IBM Qradar AQL example:

select "SourceImage", "TargetImage" from events where eventid=10 and utf8(payload) imatches '(?i)((.*dbghelp.*)|(.*dbgcore.*))'  and TargetImage imatches '.*lsass.*'


Threat Hunting #18 - Run/RunOnce - Shell-Core EID 9707/9708

Detecting process-cmdline of programs running from Run/RunOnce Auto startup locations using events Microsoft-Windows-Shell-Core/Operational EID 9707/9708 (turned on by default ... good for forensics ... execution history and count)

Events File Path: %SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-Shell-Core%4Operational.evtx

Below a summary of programs running or that were run from Run/RunOnce for one machine:

Those events are extremely valuable to find traces of previous infections using Run or RunOnce as a startup mechanism.

Threat Hunting #17 - Suspicious System Time Change

Pay attention to which process & account changes your system's time

System time changes are logged by the security event 4616. Legit system time changes will have:

  • svchost.exe as process name 
  • NT AUTHORITY\LOCAL SERVICE as account name
Anything else is worth a look:


Threat Hunting #16 - Lateral Movement via DCOM - ShellWindows & ShellBrowserWindow

Windows Distributed Component Object Model (DCOM) is transparent middleware that extends the functionality of Component Object Model (COM) beyond a local computer using remote procedure call (RPC) technology. COM is a component of the Windows application programming interface (API) that enables interaction between software objects. Through COM, a client object can call methods of server objects, which are typically Dynamic Link Libraries (DLL) or executables (EXE).

Permissions to interact with local and remote server COM objects are specified by access control lists (ACL) in the Registry. By default, only Administrators may remotely activate and launch COM objects through DCOM.

Adversaries may use DCOM for lateral movement. Through DCOM, adversaries operating in the context of an appropriately privileged user can remotely obtain arbitrary and even direct shellcode execution through Office applications as well as other Windows objects that contain insecure methods.

In this post we will be mainly focusing on key indicators of detection related to the use of the following two COM objects:

  • ShellWindows (ClsID = {9BA05972-F6A8-11CF-A442-00A0C90A8F39})
  • ShellBrowserWindow (ClsID = {c08afd90-f2a1-11d1-8455-00a0c91f3880})

The advantage of using those COM objects is that from a parent and child process relationship it looks legit because anything executed remotely by the attacker (i.e. cmd.exe, powershell.exe etc.) will be a child process of explorer.exe (which is very common). Upon the execution of those 2 methods, we've observed that the only solid indicator we can rely on is the facts that explorer.exe will bind to a listening local tcp port (RPC dynamic tcp-port >=49152). Which is very suspicious (rarely explorer.exe will have network connections, and if it dose it will be tied to a Microsoft IP range and not high tcp-port to high tcp-port).

Below an example of how it looks like when executing cmd.exe remotely using DCOM\ShellBrowserWindow COM object:



process_name:explorer.exe and ipport:[49152 TO *] and netconn_count:[1 TO *]

We can use security event 5158 to detect the same behavior:

IBM AQL hunting query:

select sourceport, destinationport from events where eventid=5158 and UTF8(payload) IMATCHES '(?i)(.*explorer\.exe.*)' last 30 DAYS

Above query executed on a real environment, for 1 moth period returned nothing (few false positives, -->  good for us):