Downloads from browsers are often used to initiate cyberattacks. Targeted attacks may use watering holes or spear-phishing messages with links, while commodity threats often originate from malicious ad campaigns or are downloaded by software bundlers. With this being one of the most common entry points for malware, you might be excited to know that Windows Defender Advanced Threat Protection (Windows Defender ATP) tracks the origin of most files that are downloaded by Microsoft Edge or Google Chrome, and that you could use this information on Advanced hunting to search for abnormal activities or pivot to related machines.
In most cases, FileOriginUrl and FileOriginIP are the URLs and IPs from which the file was downloaded, while FileOriginReferrerUrl is the URL that referred or linked to the download URL. This referrer URL is often the URL of a site page or a webmail page with a download link. Alternatively, this referrer URL might just be the previous link in a long chain of redirects used to proliferate malware.
Our main source for this information is the Zone.Identifier alternate data stream, that is used by multiple applications to set the “mark of the web” of downloaded files. Starting from Windows 10 version 1703, the Windows Defender ATP sensor collects this data for all the reported files. In Advanced hunting, we recently exposed a few fields that we parse from the stream—our FileOriginUrl column is parsed from the HostUrl field, FileOriginIP is parsed from HostIpAddress, and FileOriginReferrerUrl is parsed from ReferrerUrl.
Multiple Windows applications currently set a file’s origin details in that stream. Microsoft has enabled Edge to set this information, so do Office programs, unzipping events, and more. Google has updated the Chrome browser accordingly, and so have multiple other products such as WinRar. When explorer.exe copies files with this information, it sets this information for the new copies as well. All application developers can set this data for files that they create—see this Firefox bug for more details.
It is, however, important to note that any program could set these fields in the Zone.Identifier alternate data stream, so the usage and actual meaning of values may vary. For example, during file extraction, many file compression apps use the path of the archive as the FileOriginReferrerUrl of the extracted files. As a result, this field will contain a local path instead of the expected web page URL.
In some cases, we could get the file origin information from other sources, but would still upload it to use the above columns. Specifically, in Windows Defender Antivirus events, the file origin details are received from the IOfficeAntiVirus API, which is used by browsers, Microsoft Office, file-sharing apps, and many other apps to request the enabled AV to scan downloaded files. In these events, FileOriginUrl is set with the URL from which the detected file was downloaded.
NOTE: All data that is available through Advanced hunting is from your tenant. You can find more information on data privacy here.
If you see a suspicious download, you may want to see which other files were downloaded from that URL or site. In this example, Windows Defender ATP raised an alert for malicious activity. As you can see in the process tree and its side-pane, a file was downloaded from a site called napptayiyal[.]com.
By going to the URL page for napptayiyal[.]com in Windows Defender ATP, you can see that this site was recently registered through a privacy protection service and is hosted on AWS.
The URL page will show you all downloads from that site. However, let’s run a similar simple query in Advanced hunting, where we can continue to tweak the query to filter noise or expand our search as shown in the next few examples.
To see what fields parse_url() can extract, read this documentation.
parse_url() returns a dynamic object, so in order to apply an endswith condition on it, we need to first convert it to a string using tostring().
Over the years, we have observed many malicious payloads being downloaded from popular online services like GitHub, Dropbox, Google Drive, OneDrive, Azure blob storage, and AWS storage. All these cloud vendors, including Microsoft, are committed to blocking and removing malicious payloads, but these services continue to be infection vectors. It is often easier for attackers to host files on public cloud infrastructure than to set up their own infrastructure. The good reputation and popularity of these services also make content they serve generally difficult for security providers and defenders to regulate.
In this example, we focus on downloads from Dropbox, such as the one described in this post by FireEye. Dropbox hosts user content under dl.dropboxusercontent.com. As you can see in this query, most downloads have the referrer page within www.dropbox.com. For malware, however, this is usually not the case—attackers want the download to be seamless, without users seeing that dropbox.com is even involved.
FileCreationEvents | where FileOriginUrl startswith "https://dl.dropboxusercontent.com/" | extend ReferrerHost=tostring(parse_url(FileOriginReferrerUrl).Host) | summarize count(), any(FileName) by ReferrerHost
Windows Defender Antivirus scans every file downloaded through the browser and reports both the details of the file that was detected and the URL it was downloaded from. In this query, we pivot from the download URLs of detected files to other downloads from the same hosts, specifically the downloads that were not detected. In this example we explicitly filter out threat categories that are less severe, such as software bundlers or Potentially Unwanted Applications (PUA), so we could hunt for the more interesting stuff.
let detectedDownloads = MiscEvents | where ActionType == "AntivirusDetection" and isnotempty(FileOriginUrl) | project EventTime, FileOriginUrl, FileName, MachineId,
ThreatName=tostring(parse_json(AdditionalFields).ThreatName) // Filter out less severe threat categories on which we do not want to pivot | where ThreatName !startswith "PUA"
and ThreatName !startswith "SoftwareBundler:"
and FileOriginUrl != "about:internet"; let detectedDownloadsSummary = detectedDownloads // Get a few examples for each detected Host:
// up to 4 filenames, up to 4 threat names, one full URL) | summarize DetectedUrl=any(FileOriginUrl), DetectedFiles=makeset(FileName, 4), ThreatNames=makeset(ThreatName, 4)
by Host=tostring(parse_url(FileOriginUrl).Host); // Query for downloads from sites from which other downloads were detected by Windows Defender Antivirus FileCreationEvents | where isnotempty(FileOriginUrl) | project FileName, FileOriginUrl, MachineId, EventTime,
Host=tostring(parse_url(FileOriginUrl).Host) // Filter downloads from hosts serving detected files | join kind=inner(detectedDownloadsSummary) on Host // Filter out download file create events that were also detected. // This is needed because sometimes both of these events will be reported,
// and sometimes only the AntivirusDetection event - depending on timing. | join kind=leftanti(detectedDownloads) on MachineId, FileOriginUrl // Summarize a single row per host - with the machines count
// and an example event for a missed download (select the last event) | summarize MachineCount=dcount(MachineId), arg_max(EventTime, *) by Host // Filter out common hosts, as they probably ones that also serve benign files
| where MachineCount < 20 | project Host, MachineCount, MachineId, FileName, DetectedFiles,
FileOriginUrl, DetectedUrl, ThreatNames, EventTime, SHA1 | order by MachineCount desc
I apologize if this post was a bit long, but I hope you have found it interesting. You are more than welcome to visit the GitHub repository to find other interesting queries or contribute your own ideas. If all these seem new to you, experience Windows Defender ATP for free now.
Also, perhaps you would be interested in other posts on Advanced hunting. The next hunting tip demoes hunting on top of downloads that originate from email links. You may also like this entry-level tutorial for Advanced hunting or an in-depth look into hunting on Powershell commands.
I really appreciate you reading this far. Honestly, mom, this means a lot to me. ;)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.