Posted on Leave a comment

Finding Local Administrators on a Domain Member Stations, (Wed, Apr 24th)

Now that we’ve got a list of domain admins ( https://isc.sans.edu/forums/diary/Where+have+all+the+Domain+Admins+gone+Rooting+out+Unwanted+Domain+Administrators/24874 ), lets find all the accounts that have local Administrator rights.
Local Admin used to be a common thing, back in the early XP days when Windows Security was new.  It was common back then to see everyone’s AD account have local admin on their own machine, so that they could do things like update the clock, install printer drivers, or install games when they took their laptop home.

Sound familiar?  Well, those days are gone (or they should be).  In 99% of cases, you absolutely, positively do NOT need local admin for anything on a domain member computer (especially if it’s not a server) that’s administered by IT staff.  You might need an extra right here or there, but even then, it’s very likely that you don’t.  Windows 10 and even Windows 7 both do a good job without giving folks admin rights.  (We won’t talk about that dark Windows 8 detour that nobody took, but W8 does just as good a job on this score)

What local admin does give you is rights that you shouldn’t have, to perhaps install malware that might then access system files that nobody wants changed.  And if you don’t use LAPS, local admin on one station will likely give you local admin on ALL the stations, which from a malware point of view is as good as domain admin in lots of organizations.

So let’s get on with it – to find local admins across the board, you’ll want something that looks like this:

import-module ActiveDirectory

function get-localadmin {
  param ($strcomputer)
  $admins = Gwmi win32_groupuser –computer $strcomputer  
  $admins = $admins |? {$_.groupcomponent –like ‘*”Administrators”‘}
  $admins |% {
    $_.partcomponent –match “.+Domain=(.+),Name=(.+)$” > $nul
    $matches[1].trim(‘”‘) + “” + $matches[2].trim(‘”‘)
  }
}

$i = 1
$localadmins = @()
$targets = Get-ADComputer -Filter * -Property DNSHostName
foreach ($targethost in $targets) {
  write-host “Testing” $targethost.DNSHostName “,” $i “hosts completed”
  if (Test-Connection -ComputerName $targethost.DNSHostName -count 2 -Quiet) {
    $admins = get-localadmin $targethost.DNSHostName
    foreach ($a in $admins) {
      $val = new-object psobject
      $val | add-member -membertype NoteProperty -name Hostname -value $targethost.name
      $val | add-member -membertype NoteProperty -name AdminID -value $a
      $localadmins += $val
      }
  ++$i
  }
}
$localadmins | export-csv -append localadminusers.csv

Note that this code will grab everything, so when it hits the domain controllers it’ll enumerate domain admins (which is the honest truth when you think about it).  Note also that if a station is not on the network when you run this script, of course you won’t be able to enumerate any user information from it.

Run this on your own domain, user our comment form let us know if you find anything unexpected!

===============
Rob VandenBrink
Compugen

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

Posted on Leave a comment

Where have all the Domain Admins gone? Rooting out Unwanted Domain Administrators, (Wed, Apr 24th)

Ever been in an internal security assessment or penetration test, and need to list all domain admins?
First of all, why would you need to do that?  All to often, you’ll find that way too many people have domain admins – you know, “just in case”
People like:

  • developers – who needed local admin on that one server, that one time, but we gave them domain admin and then forgot
  • or developers, because don’t all devs need domain admin?
  • IT VP’s and dev managers, because they used to be admins
  • the CEO, because they insisted
  • Steve, because Steve needed to update the timezone or install a printer at home, and the helpdesk mistakenly gave Steve domain admin rights for that

You get the idea.

So, aside from the people that are actual members of “Domain Admins”, there are lots of groups that have elevated privileges in a domain, so we’ll need to enumerate all of those too.  And you can put groups into groups, so we’ll have to recurse through that mess to get the full list of users.  This can take quite a while in the GUI, but it’s only a few lines of code in PowerShell:

 

$DomainAdmins = @()
$a = $()
‘Domain Admins’, ‘Administrators’, ‘Enterprise Admins’, ‘Schema Admins’, ‘Server Operators’, ‘Backup Operators’ | ForEach-Object {
    $groupName = $_
    $a = Get-ADGroupMember -Identity $_ -Recursive | Get-ADUser | Select-Object Name, samaccountname, @{n=’GroupName’;e={ $groupName }}
    $DomainAdmins += $a
}
$DomainAdmins | export-csv alldomainadmins.csv

This will list all the Admin users, and the group membership that put them there.  So you might find the same person on this list a few times (but that’s a good thing in most cases).

If you just want the de-dup’d list of unique userids (without how they got there), add this snip to your code:

$uniqadmins = ($DomainAdmins | select SamAccountName,name )  | Sort-Object -Property samaccountname -Unique

$pctdomadmins = ($uniqadmins.count / (Get-ADUser -filter * ).count) *100
write-host $pctdomadmins “percent of domain users have domain admin rights”

$pctdomadmins$uniqadmins | export-csv uniqadmins.csv

When you run this against your domain, what is your percentage?  Did you find any surprises?  Please, use our comment form and let us know!

===============
Rob VandenBrink
Compugen

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

Posted on Leave a comment

Malicious VBA Office Document Without Source Code, (Tue, Apr 23rd)

A couple of years ago, we posted diary entry “VBA and P-code“: we featured a VBA P-code disassembler developed by Dr. Bontchev. VBA source code is compiled into P-code, which is stored alongside the compressed source code into the ole file with VBA macros.

Dr. Bontchev also published a PoC Word document with VBA code: it contained just the P-code, and no VBA source code. Hence to analyze the document, you could not extract the source code, but you had to disassemble the P-code with pcodedmp.py.

Yesterday, I was pointed towards a malicious Word document found in-the-wild that was hard to analyze. It turned out the VBA source code had been wiped (recently, this method has also been referred to as VBA stomping).

Here’s how I analyzed this document. First, I get this output with oledump.py:

With this output and the context I was given, I can already conclude that this is a malicious document: the recipient received an unexpected .docm file from an unknown sender -> maldoc.

Remark also that stream A3 has no M indicator, while its name (Module1) indicates it should contain VBA code. That’s why I use option -i to get more info:

For every stream with VBA code, option -i will display 2 numbers: the size of the compiled code (P-code) and the size of the compressed VBA source code.

For stream A3, I see that the compressed VBA code is 1280 bytes in size. So why is there no M indicator?

Decompressing the VBA code throws an error:

I take a look at the raw, compressed VBA code (using suffix s for source code):

It has been wiped: the compressed VBA code has been overwritten with 0x00 bytes!

If you were still unsure if this document was malicious or not: now you can cast aside any doubt. Microsoft Office applications do not produce documents like this. This document has been tampered with to try to bypass AV detection.

And if your job is to determine if a document like this is malicious or not, you can report your findings now: this is a maldoc.

But if you need to figure out what this maldoc does, there’s a bit more to analyze.

Using suffix c (compiled), I select all bytes that make up the P-code:

Notices strings Winmgts and Win32_Process (reversed): it looks like this maldoc creates a new process via WMI.

Now I’m using pcodedmp.py to look at the disassembly:

Here is the disassembled P-code. P-code is executed by a stack machine: first arguments are put on the stack, and then functions are called that pop arguments from the stack and push results to the stack.

Here I see a string constant (consisting of digits) assigned to variable E_MO, and then passed as argument to function B_RA, who’s output is used as argument to CreateObject. The result is assigned to variable F_DC. Thus the string is an obfuscated object name, and function B_RA does the deobfuscation.

In the following screenshot, I see a variable (SP_LL) of the Word document (ActiveDocument) that is passed to function B_RA, to be deobfuscated, and then executed (F_DC.Exec).

And here is function B_RA:

It contains a For loop, function Mid is used to select substrings of 3 characters long, which are then converted to an integer and then have 0x1A (26) subtracted from them, to be finally converted to a character. With this information, I can make an educated guess on how to decode the obfuscated string.

But first, I need to find the value of variable SP_LL. Since this is a .docm file, I need to search into XML files contained in a ZIP file. zipdump.py with its YARA functionality is what I need here:

File settings.xml contains variable SP_LL:

With re-search.py and a regular expression to match strings of 10 digits or longer, I extract the value for SP_LL (a long string of digits):

Next I need to break this string up in substrings of 3 digits. I can do this too with re-search.py, and a regular expression for 3 digits:

Now I need to convert these numbers to characters. numbers-to-string.py was designed to do just this. I use option -n 1 to process one number per line (by default, numbers-to-string.py expects at least 3 numbers per line):

This is not yet the decoded string we want: I need to subtract 26 from each number, like this:

Here I recognize cmd.exe … Finally, I use option -j to join all lines into a single line:

And this is a command that launches PowerShell with a downloader script.

 

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

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

Posted on Leave a comment

.rar Files and ACE Exploit CVE-2018-20250, (Mon, Apr 22nd)

Reader Carlos submitted an email with attached RAR file.

In the past, when you received a RAR file as attachment in an unexpected email, it often contained a single malicious Windows executable. For the infection to occur, one would have to open the attachment and double-click the executable.

Nowadays, a RAR file can also be an ACE exploit, like the popular %%cve:2018-20250%%. Infection typically occurs by opening the attachment, and then restarting the computer or performing a logoff/logon cycle.

With oledump.py and plugin plugin_msg.py, one can inspect .msg files:

There’s an attachment with extension .rar:

And it is indeed a RAR file containing an executable.

If it would be an ACE file masquerading as a RAR file (.rar extension in stead of .ace), one would see the following:

The binary data does not start with “Rar!”, instead, one will see “ACE” a few bytes into the binary data.

The example above is a normal ACE file. ACE files with a path traversal exploit will have an abnormal path stored in the ACE file:

 

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

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

Posted on Leave a comment

Analyzing UDF Files with Python, (Fri, Apr 19th)

Yesterday, Xavier wrote a diary entry about malicious UDF files.

I wrote about the analysis of .ISO files before, and it turns out the same techniques work for UDF files too.

Python module isoparser can also parse UDF files:

We can retrieve the content:

And calculate the hash of the contained EXE:

 

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

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

Posted on Leave a comment

Malware Sample Delivered Through UDF Image, (Wed, Apr 17th)

I found an interesting phishing email which was delivered with a malicious attachment: an UDF image (.img). UDF means “Universal Disk Format” and, as said by Wikipedia[1], is an open vendor-neutral file system for computer data storage. It has supplented the well-known ISO 9660 format (used for burning CD & DVD) that was also used in previous campaign to deliver malicious files[2].

Here is a copy of the mail:

From: 
To: 
Subject: Overdue Invoice
Valued customer,
Attached is your invoice as scheduled, your credit/debit card will be charged. Your bill will be delivered along with your ordered items(s).
Please review the receipt at your earliest convenience and get back to us in case of anomalies.

Thank you for your continued patronage.

Warm regards.

The attached files was called “invoice#003.img” with the SHA256 hash: 886338ebc04e728338874b07365d4fd337998e1786893b680065358e815a6d02. At the moment, the file is flagged by 23 AV on Virustotal[3]. To read the content of the archive safely, you can use the ‘loop’ driver on a Linux system:

# mount -o loop /tmp/invoice#003.img /mnt/malicious/
# ls -l /mnt/malicious
total 1296
-r-xr-xr-x 1 nobody nogroup 1325568 Apr 14 23:45 invoice#003.exe
# shasum -a 256 /tmp/malicious/invoice*
b3aef0e1d7a71edbc858a81e66f354be1974aafdd4449f2972e4dae1c82f2b8a  /mnt/malicious/invoice#003.exe

Here, the VT score is 35[4], it’s a classic malware written in AutoIT, nothing special. It tries to connect to kingdevil[.]ddns[.]net:4156.
Let’s have a look at the UDF image:

00008220: 2020 2020 2020 2020 2020 2020 2020 2020
00008230: 2020 2020 2020 2020 2020 2020 2020 494d                IM
00008240: 4742 5552 4e20 5632 2e35 2e38 2e30 202d  GBURN V2.5.8.0 -
00008250: 2054 4845 2055 4c54 494d 4154 4520 494d   THE ULTIMATE IM
00008260: 4147 4520 4255 524e 4552 2120 2020 2020  AGE BURNER!
00008270: 2020 2020 2020 2020 2020 2020 2020 2020
00008280: 2020 2020 2020 2020 2020 2020 2020 2020
00008290: 2020 2020 2020 2020 2020 2020 2020 2020
000082a0: 2020 2020 2020 2020 2020 2020 2020 2020
000082b0: 2020 2020 2020 2020 2020 2020 2020 2020
000082c0: 2020 2020 2020 2020 2020 2020 2020 2020
000082d0: 2020 2020 2020 2020 2020 2020 2020 2020
000082e0: 2020 2020 2020 2020 2020 2020 2020 2020
000082f0: 2020 2020 2020 2020 2020 2020 2020 2020
00008300: 2020 2020 2020 2020 2020 2020 2020 2020
00008310: 2020 2020 2020 2020 2020 2020 2020 2020
00008320: 2020 2020 2020 2020 2020 2020 2032 3031               201
00008330: 3930 3431 3530 3034 3635 3430 300c 3230  9041500465400.20
00008340: 3139 3034 3135 3030 3436 3534 3030 0c30  19041500465400.0
00008350: 3030 3030 3030 3030 3030 3030 3030 3000  000000000000000.
00008360: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00008370: 0001 0049 6d67 4275 726e 2076 322e 352e  ...ImgBurn v2.5.
00008380: 382e 3000 0000 0000 0000 0000 0000 0000  8.0.............

ImgBurn is a well-known Windows tool used to create CD/DVD images[5] and guess what? A stock Windows handle this type of file without any extra tool:

So be careful with .img files! They should also be added to the list of prohibited file extensions in your mail relays or change the file association in your Windows environments to NOT open them Windowd Explorer.

[1] https://en.wikipedia.org/wiki/Universal_Disk_Format
[2] https://isc.sans.edu/forums/diary/Malicious+iso+Attachments/22636
[3] https://www.virustotal.com/#/file/886338ebc04e728338874b07365d4fd337998e1786893b680065358e815a6d02/relations
[4] https://www.virustotal.com/#/file/b3aef0e1d7a71edbc858a81e66f354be1974aafdd4449f2972e4dae1c82f2b8a/detection
[5] https://www.imgburn.com

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

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

Posted on Leave a comment

A few Ghidra tips for IDA users, part 2 – strings and parameters, (Wed, Apr 17th)

Continuing with my preliminary exploration of Ghidra. If we continue with the call to RegOpenKeyExA from last time (yes, I know this code is unreachable as we discussed last time, but let’s keep going anyway).

If we look back up at the first parameter, we see 0x80000001. Off the top of my head, I don’t remember which key that is (well, actually, I’ve been doing this long enough that I do, but let’s pretend that I don’t). In IDA, I’d right-click on that hex value and choose ‘Use standard symbolic constant’ to replace that with the constant definition from one of the Windows header files that defines those. It turns out, Ghidra lets us do this, too. In Ghidra, right click and choose ‘Set Equate’ and it pops up a dialog box similar to IDA’s from which you can choose the proper constant to use in place of the hex value.

Just like in IDA, if you know the constants for registry keys start with ‘HKEY_’ (or you looked it up on MSDN, now known as, docs.microsoft.com) you could start typing that and it would narrow down the choices. In this case, it is easily visible. So, double-click on ‘HKEY_CURRENT_USER’ or click and choose OK and the constant is replaced. Notice that you have the option here to just do the substitution for this one instance or across the entire program. I’m going to leave this at the default, but there may be times when you want to replace the hex value with the symbolic constant everywhere (nearly every time I teach FOR610 a student will ask me if IDA has that capability and, if it does, I’m not aware of it).

Looking above that at the second parameter, I usually want to know which particular subkey is being opened. In IDA, I just hover over the label for the string and it shows me the entire string. In Ghidra, if I hover over it, it shows me part of the string, but not the whole thing. Hmm… That is a bit of a problem. If I double-click on the label, both IDA and Ghidra take me to the place in memory where the string is located, but again, Ghidra doesn’t show me the entire string. In the hex column it only shows me the first 9 bytes in hex and then gives me the ellipsis, but in the string part, it still doesn’t show the whole thing. It shows the first 40-something characters and then the ellipsis.

In hunting around, I was not able to find a setting to increase that, though I’m sure there must be a way somewhere. If not in a setting, then in the code itself (which is now available on github). You can see the entire string though, if you go through the Search menu (choosing ‘For Strings…’ option). In this case, since I could see the CurrentVersion substring, I just searched for that and found the following.

In the end, though, I realized I didn’t need to go to that much effort, there was a much easier way to see the string. Just go back to the decompiler window. As I mentioned in the previous diary, one way that the decompiler makes our lives as malware analysts much easier is it saves us the effort of having to try to match up the PUSHes or MOVes to figure out which parameter is which. This is especially true when you get into 64-bit malware on Windows which uses a lot more fastcall and the MOVes into registers may not appear in the order you expect. So, when I glance over into the decompiler window, I see this.

Very nice, it has my symbolic constant, it shows the entire string. That’s just about everything I think I need to know about that API call.

I think that’s enough for this diary, I have at least one more to come (probably next week). Again, as I mentioned in the first 2 entries in this series, this is all just from a very brief time playing with Ghidra. I haven’t had a lot of time to dig deep yet, but so far, I’m liking what I’m finding. If you have any thoughts, comments, corrections, or tips of your own, please e-mail me or use the comments below.

—————
Jim Clausing, GIAC GSE #26
jclausing –at– isc [dot] sans (dot) edu

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

Posted on Leave a comment

Odd DNS Requests that are Normal, (Tue, Apr 16th)

If you ever heard me talk about DNS, you will know that I am a big fan of monitoring DNS queries, and I think DNS query logs are the best “band for the buck” log source to detect anomalous behavior. Everything that happens on your network, good or bad, tends to be reflected in DNS.

But there are a couple common “odd” DNS request types that are often mistaken for malicious, or unusual but are actually quite normal. Here are my favorite once:

  • Anti Malware Checks:

I got an example from Sophos Anti Virus here, but other vendors use a similar technique:

0.0.3.0.0.0.0.0.0.2.0.0.0.0.1.01.00.sfi_unknown.f.01.mac.sophosxl.net
0.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.sfi_unknown.b.f.01.mac.sophosxl.net
3.1o19sr00s2s17s4qp3759pn9ro30n2n4n941on29s3s35qppp742380s6487np3.poqp0r741pn37393648s20n65203rn4o44387s5831o276q6s5rqsr16n809qp4.86752ss34q9sns005o.35n2s0s521p9rn7o75q0r479rpqq7o0oq6r6o20p.i.01.mac.sophosxl.net
3.1o18sr00s2s17s4qp3759pn9ro30n2n4n941on29s3s35qppp742380s6487np3.poqp0r741pn37393648s2779qp6or2108n4o66o276n931p8287709r73q098rp.86752ss34q9sns005o3pp76q83qr6344r79q7rpns9.485n1675n4750q4n.i.01.mac.sophosxl.net
0.0.3.0.0.0.0.0.0.2.0.0.0.0.1.01.00.sfi_unknown.f.01.mac.sophosxl.net
0.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.sfi_unknown.b.f.01.mac.sophosxl.net
3.1o19sr00s2s17s4qp3759pn9ro30n2n4n941on29s3s35qppp742380s6487np3.poqp0r741pn37393648s20n65203rn4o44387s5831o276q6s5rqsr16n809qp4.86752ss34q9sns005o.35n2s0s521p9rn7o75q0r479rpqq7o0oq6r6o20p.i.01.mac.sophosxl.net
3.1o18sr00s2s17s4qp3759pn9ro30n2n4n941on29s3s35qppp742380s6487np3.poqp0r741pn37393648s2779qp6or2108n4o66o276n931p8287709r73q098rp.86752ss34q9sns005o3pp76q83qr6344r79q7rpns9.485n1675n4750q4n.i.01.mac.sophosxl.net

At first sight, you may mistake these requests for typical DNS covert channels. But they are actually associated with Sophos Antivirus. The reason for these queries is that Anti-Malware uses DNS to check if certain files are malicious. The software will send a hash of the file to the vendor and receive back an indication if the file is malicious or not. This will also allow the vendor to compile statistics on the popularity of certain software which will then often be used to compile risk scores (sorry… feed a machine learning AI engine that will protect you from 0-day attacks… or something like this if you read the vendor ads for various products like this). In some ways, this is an exfiltration activity. Just not malicious.

  • Mail Servers

We all know that clients usually try to resolve A or AAAA records. But let’s take a look at the snapshot below of the records types from a quick query log sample (collected via bro in this case):

The high percentage of PTR records may appear odd. In this case, however, the network includes a busy mail server. Mail servers, for anti-spam filtering, often resolve IP addresses to match forward and reverse resolution.

  • Other .arpa hostnames

Talking about PTR records. Pretty much everybody reading this, probably knows about in-addr.arpa and ipv6.arpa and how it is used for reverse resolution. But these are not the only “.arpa” records you see. One record I see more and more is ipv4only.arpa. This record is used to detect if the host is on an IPv6 only network, and DNS64 is used to map IPv4 addresses to IPv6. This record should resolve to 192.0.0.170/171. Only the A record exists. For a AAAA query, you will not get an answer unless your name servers (do to DNS64), is making one up. There are actually a few more .arpa hostnames but this is the one I usually see quite frequently.

  • develooper.com

When I saw this first, it looked like a typosquatting domain to me. But the company behind this domain is an active contributor to a number of open source projects, and in my case, it was their contribution of resources to perl.org that triggered the DNS requests.

Any odd DNS requests that you ran down to only find them to be harmless?

 

 

 


Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

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

Posted on Leave a comment

Configuring MTA-STS and TLS Reporting For Your Domain, (Sat, Apr 13th)

Currently, the majority of HTTP traffic uses TLS (HTTPS) [1]. This is in part due to free and easy to manage certificates from Let’s Encrypt, but also due to HTTP Strict Transport Security, an HTTP header that will tell browsers to only connect to your site via HTTPS [2].

For email, we typically use TLS to connect from our mail client to our mail server. But for email, the weak link is connections between mail servers as they forward email. Years ago, STARTTLS became a popular feature. It does allow servers to discover that the other server supports TLS, and upgrades can happen “on the fly”. The system is very simple and efficient, but suffers a major shortcoming: The initial connection is in the clear without TLS, and an adversary may easily alter the content, removing the TLS header, so users will never know that their server sent the email in the clear [3].

More recently, two new standards emerged: MTA-STS (SMTP MTA Strict Transport Security) which can be used to advertise that your mail server supports STARTTLS [5], and SMTP TLS Reporting which allows other mail servers to send you reports about whether or not your mail server responded properly to TLS.

Implementing these standards for your domain is a bit tricky. In this post, I will talk about implementing MTA-STS and TLS Reporting for your domain. I will not talk about how to tell your mail server to verify MTA-STS as it sends email, or how to send TLS reports.

There are two parts to these standards: DNS TXT records that advertise that you are supporting them, and a policy file with details that is served via HTTPS.

Step 1:

First of all, make sure your systems are configured correctly and are using proper TLS certificates. In particular mail servers often use bad certificates as you can get away with it. But once you have MTA STS enabled, all these checks need to pass. As a quick check, I recommend hardenize.com (I found the cache doesn’t always get cleared if you re-test, so you may wait a while or do some manual checks after the initial check with hardenize). Hardenize was created by Ivan Ristic who also created the famous ssllabs test. But unlike ssllabs, hardenize goes beyond just https and beyond just basic TLS issues.

After you pass all the tests, it is time to get started on MTA-STS

Step 2: 

Setup a virtual host at “mta-sts.example.com”. The hostname has to be “mta-sts”. You could add this host name to your existing web server, but it may be cleaner to set up a distinct server (virtual host) for this hostname. It has to support TLS, so make sure to setup TLS and probably a Let’s Encrypt certificate with it.

Step 3:

Create the policy file. The policy file has to live in mta-sts.example.com/.well-known/mta-sts.txt . The file is a simple text file. For example:

version: STSv1
mode: testing
mx: isc.sans.edu
mx: mail.dshield.org
max_age: 600

The version should always be “STSv1”. The mode can be “testing” (do not enforce the policy), “enforce” or “none”. Starting with “testing” is recommended. Next, you list your mail servers. The max_age indicates how many seconds the policy is cashed. Start with something short like 10 minutes until you got it all right.

Test that the policy can be retrieved and it should be returned with a Content-Type of “text/plain”.

Step 4:

Next, you need to add two DNS entries. One for MTA-STS and one for SMTP TLS Reporting:

_mta-sts.example.com TXT "v=STSv1; id=201904131609"

Again, the version is always STSv1. The ID can be any string. It is used to detect if the policy changed.

_smtp._tls.example.com TXT "v=TLSRPTv1; rua=mailto:[email protected]"

The version is again fixed. the “rua” part indicates where to send the reports. you may list multiple email addresses separated by a comma. It is also possible to specify an http(s) URI to receive the reports. The reports are small JSON files like (thanks to “S J” for sharing this report received from Google):

{"organization-name":"Google Inc.","date-range":{"start-datetime":"2019-04-12T00:00:00Z","end-datetime":"2019-04-12T23:59:59Z"},"contact-info":"[email protected]","report-id":"2019-04-12T00:00:00Z_domain.com","policies":[{"policy":{"policy-type":"no-policy-found"},"summary":{"total-successful-session-count":1}}]}

And that should be it. Let me know how it goes or add a comment with any additional tips you have. Check Hardenize.com after you are done to make sure all of this works nicely.

[1] https://letsencrypt.org/stats/
[2] https://tools.ietf.org/html/rfc6797
[3] https://www.eff.org/deeplinks/2014/11/starttls-downgrade-attacks
[4] https://tools.ietf.org/html/rfc8561
[5] https://tools.ietf.org/html/rfc8560


Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

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

Posted on Leave a comment

When Windows 10 Comes to Live: The First Few Minutes in the Live of a Windows 10 System, (Fri, Apr 12th)

We often get emails from readers stating that they feel their system is compromised, even though they “do nothing”. Most of the time, our response is “that’s normal”. Indeed, most modern operating systems, not just Windows, will trigger lots of network traffic without user activity. But I found little documentation about what exactly to expect from a “normal” Windows 10 system. So I ran a quick experiment:

Microsoft offers a number of free virtual machines. I picked the “Microsoft Edge Windows 10 (x64) Stable 1809” system. The reason I went this route is that it first of all made things more reproducible, and secondly, these virtual machines do not include additional software, so you only get the default Windows 10 behavior. These systems are also in a default configuration.

The initial plan was to only record the first boot. But I discard this quickly. After 5 minutes, I had a few hundred MBytes of traffic as Windows first downloaded a lot of updates (including VMware Tools). So I modified my plan: I let the system run for about an hour, until all updates were applied, then I rebooted it a couple of times again making sure that it didn’t download additional updates. Finally, I recorded the first few minutes after a reboot.

You can find the raw packet capture at https://isc.sans.edu/diaryimages/WindowsStartup.pcapng . I am using the PCAPNG format as I started to add comments to some of the packets. But here are the basic features:

I recorded 87 seconds. During that time, I captured 531 packets and 196kBytes. 20 DNS requests and responses, 18 TCP connections and 30 UDP connections. My host communicated with 18 other IPv4 hosts (there is no significant IPv6 traffic as the network didn’t support IPv6).

Here is the short summary of the pcap:

IP address of the system: 172.16.29.198
MAC Address: 00:0c:29:1f:55:7b
Hostname: MSEDGEWIN10

The system was configured to log in automatically. I did not open a browser window and did not interact with the system beyond powering it on.

Here are some of the main features of the pcap:

  • initially, the operating system configures itself (IPv6 router solicitations, DHCPv6 and DHCPv4). 
  • The operating system is trying to configure a proxy via WPAD a couple of times
  • Content for tiles is downloaded (e.g. Weather) in the clear.
  • There are TLS connections to Bing and events.data.microsoft.com, likely for more content.
  • connections to canonicalizer.ucsuri.tcs which is part of Microsofts “Smartscreen” anti-malware.
  • inference.location.live.net: Microsoft’s geolocation
  • additional Live.com systems for things like Microsoft’s login features.

There was also a DNS lookup for puppet.localdomain. Not sure if Windows is looking for a Puppet server here for configuration files.

See anything I missed? 


Johannes B. Ullrich, Ph.D. , Dean of Research, SANS Technology Institute
Twitter|

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