Monday, March 20, 2017

A quick REVENGE Analysis

Another free weekend, another suspicious link provided by a colleague of mine and another compelling feeling to understand "how it works".  The following analysis is made "just for fun" and is not part of my professional analyses which have to follows a complete different process before being released. So please consider it as a "sport activity".

A colleague of mine provided me a suspicious link which I decided to analyze.

The infection starts by redirecting the browser to the page "" through a GET request with the following parameters:
The page is not build to return rendered content but rather to return three different scripts. Indeed the returned visible page holds a weird displayed content as follows:

Weird visible content by:

Getting a little deeper on the page source code it is easy to experience nice obfuscated scripts, which look like (at least to my experience) a first infection stage. Let's have fun and try to understand how this new sample works. The following image shows an obfuscated piece of code portion. We are getting into the first stage of analysis.

First Stage: The fun begins.

Just few steps on google V8 engine to de-obfuscate the first stage which uses a couple of techniques to run VBscript on the target machine. The first implemented trick, as shown in next image, is to use the classic  but "ever green" window.execScript which is no longer supported on Explorer >= 11. execScript takes two parameters: "the code to be run" and the "used programming language". The function invokes the right interpreter depending on "programming language" parameter.

Second Stage: Running VBScript

The second trick is to use eval to de-obfuscate the second stage and later on to run its functions through VBArray technique.  Decoding the second stage was easier if compared to the first stage since less obfuscation rounds are involved. Once de-obfuscated the second stage I've run into another "browser" stage (let's call it Third Stage) written in VisualBasic Language as follows:

Third Stage: The VBScript saving Windows PE
The resulting script is quite simple to read no further obfuscated loops were involved.  The script per se is quite big so I am not going to describe every single line of code but just the most interesting one (at least in my personal opinion), so let's focalize on the "random function" (showed in the following image) which returns strLen number of "random" letters from a well defined alphabet :).

Third Stage: Implemented "random" function

This function is used later on to save the PE FileSystemObject into temporary file by using the number "8" as parameter to the rnds function. A nice and dirty IoC would be: "8 letters" from "abcdehiklmnoprstuw02346" alphabet ".exe" into system temporary directory as shown in the next image. 

Third Stage: Saving PE Object using 8 "random" (not really) characters

The FileSystemObject is then executed through the WScript.Shell technique as shown in the next image.

Third Stage: Running the fake shell32.dll

A key argument is defined as "gexywoaxor" and a stream is taken from an url as shown in the following image.

Third Stage: Key and Stream

A special function is crafted to decrypt the stream having as a key the defined one. The decoded stream is getting saved and launched according to the fake shell32.dll.

Third Stage: Decryption stream function (key= gexywoaxor)
Most of you would recognize RIG Exploit kit which used to decrypt streaming (ADOBE StreamObj) objects through inline xor. That decrypt function would not use a simple xor, and for such a reason I would consider it as new version of RIG Exploit Kit. The overall behavior looks like standard RIG EK having threes infection browser scripts and stream decoding procedure.

Finally I've got a Windows PE on my temporary directory and a script launching it from browser ! 

Let's move on and see what it does. A first run the PE file gets information from its Command and Control server which, on my time, happened to be: (France)
It downloaded a Public Key (maybe for encrypting files ?) as follows:

Fourth Stage: Downloaded Public Key
This behavior reminds me a romantic Ransomware attack, which happens to fit pretty well with RIG distribution rings. The sample starts with simple http GET but later on it keeps trace of its malicious activity (encrypted files) by posting, on the same C&C, the number of encrypted files and a unique serial number as well. The sample returns back two parameters: id and count.

Fourth Stage: POST to C&C

id is different for every infection while it could be consider as a unique constant for a given one. count constantly increases its value as a counter depending to the number of encrypted files.
The sample presents some tricks to control the running environments such as (but not limited to): IsDebugPresent and VolumeChecking. The sample is a multi-thread encryptor which spawns an encrypting thread for each found system folder (limiting to 10 per times). The sample is not packed/encrypted from a well known packer/encryptor as the following image shows, but the real code (payload) is encoded into a Fourth Stage (let me define the Windows PE as fourth stage of infection).

Fourth Stage: No known packers/encrypters are found

The following image shows the real payload dynamically build in the heap of the fourth stage. As analyst I decided to not extract it but rather following on the original sample in order to understand how happens the control flow switch.

Stage Fifth: HEAP built payload 

The fifth stage is run by the following code which after having built the payload straight into the memory gets the control flow by simple dynamic "call" to dynamic memory [ebp+var_4].

Fifth Stage: getting control by call [ebp+var_4]
This is the last stage where the payload runs over the folders, read files and encrypt them by using a dynamically loaded cryptbase.dll and the downloaded public key. The payload per-se saves itself and get persistence by infiltrating on register keys. The following images show where the payload copies itself in the target machine

Fifth Stage: Payload Persistence
Te payload saves itself as svchost file creating a folder named Microsofts\ Windows NT\svchost.exe as the most classic payloads does ! Cryptobase.dll functions are dynamically loaded, only few library functions have been involved which takes easy to track them down (the following images show the tracking down imported libraries).

Stage Fifth: Cryptobase.dll tracking functions
Finally the SaveFile function write the ransom file: # !!!HELP_FILE!!! #.TXT  to physical drives having the following content and encrypts file through .REVENGE extension

Ransom File
Since the implemented languages are: English, Italian, German, Polish and Korean  it is easy t believe this ransomware attack would target European countries mainly.

While the infected website ( has promptly been closed (now it belongs to GoDaddy) the Command and Control page is still up and running. Indeed the command and control appears to be an old vulnerable fake website created on 2016-10-07T08:19:40Z weaponized with an ancient content back to November 2014. The website is not a real one, it's a simple "lorem ipsum" with no apparent purpose. The following images shows the apparent not real website.

Command and Control Vulnerable Web Site

Despite the reverse engineering difficulty and/or the technical details I addressed in this quick and dirty post, I found an unusual C&C behavior. Usually attackers want to protect their C&C and are the first system (page, connection, services) to be closed and/or moved after a first disclosure. Indeed the attacker wont be "syncholed" by receiving injection commands into her malicious network. Contrary in this example the current C&C looks to be alive from October 2016. Please note that I am not saying it servers RIG from 2016 but it might have served many different EK over time, which makes me thinking to a well defined operation attributable to a RIG as a service group.

Useful IoC:
- url:
- url:
- ip:
- ip:
- email:
- email:
- email:
- string: 5427136ABEE9451E
- string: # !!!HELP_FILE!!! #.TXT
- string: gexywoaxor 
- file extension: REVENGE
- File Name: 8 characters from {abcdehiklmnoprstuw02346}.exe

A similar dropper (Third Stage) has been published on March 9th 2017 on pastebin.

Sunday, February 12, 2017

Crypt0l0cker Revival !

A couple of days ago a colleague of mine gave me a "brand new" malicious content delivered by a single HTML page. The page was sent to an email box as part of a biggest attack. I found that vector particularly fun and so I'd like to share some of the steps who took me through a personal investigation path made not for professional usage but just for fun.

At first sight the HTML page looks like the following image.

Figure1: Attack Vector. A simple HTML page

A white backgrounded HTML page with a single line test on it saying: "print this document please". But what document ? Honestly I am in front of one of the ugliest "fake email" I ever seen. But let's move on and se what it really carries on. Opening the HTML content with a simple editor we might see a suspicious obfuscated Javascript. We are facing a first obfuscation stage. 

Figure2: Obfuscated First Stage

Since Javascript is an interpreted language (such as .NET or .Java) is not hard to understand its behavior, indeed after some rounds of "substitutions" and "concatenations" it easy to get the following clear text result showing the end of the first stage.

Figure3: Clear Text First Stage
That script is going to create an additional "script tag" on the current document by injecting an external script from: "". The injected script will be called with the following code signature: "saveAs(blob, 'image.js');" with 2 arguments: 
  1. blob. The raw content of "big_encoded_data" (please refer to Figure3)
  2. image.js. The saving name
In order to better understand what that function saveAs(blob, image.js) does we need to analyze the external FileServer.js. The entry point of the external script is the function "saveAs(arg1, arg2)" which has been defined as follows:

Figure4: FileServer.js Original Entry

saveAs(blob, name) is a simple wrapper function headed to FileServer constructor which is defined as follows:

Figure5: FileServer.js constructor

The script saves the "blob" content to the temporary folder giving to it a specific name (image.js in our case). As you might notice from the script content: "Apple do not allow, see " if the victims opens the file with Safari/Mail the attack vector will have no effect since Safari/Mail does not allow you to trigger the script on "" event. This is why I did't see any file when I opened the infected HTML content. Back to the original script (Figure3) we see the aveAs function called on page.load so the resulting image.js is going to be saved in the temporary local folder, in case of email clients, it will be triggered as soon as saved! So lets move on our next stage: the big_encoded_data variable (Figure3) which is going to be saved as image.js file. The big_encoded_data owns a first obfuscation stage made by encoding the downloader in base64. Once decoded from base64 and beautified the results looks like the following image

Figure6: Stage 2 base64 decoded obfuscated downloader

The downloader is still obfuscated by a high number of simple returning array-strings variables. It took almost 45 minutes to decode the entire second stage downloader. The resulting downloader is shown in the following image.

Figure7: Second Stage Downloader
A first check on fileSystem API and on the Element Type is super interesting (at least to me). We are analyzing an attack based on a specific file system, Windows native. The deobfuscated downloader grabs a file from "" and saves it to a temporary directory. By using ActiveXObject (Windows native) it saves the file and it runs it through command line c["run"]("cmd.exe /c " + f + g, "0"); where f takes the temporary folder f = b["GetSpecialFolder"]("2"); and g takes the temporary name g = b["GetTempName"]();.

This is the end of the second stage downloader.

The downloaded file is a PE Executable packed as well. Fortunately the used packer is the PiMP Stub by Nullsoft: a quite famous installer used by several software house.

Figure8: NullSoft Installer

The PiMP installer takes .dlls and runs them as the resulting software. The used resources are compressed in its own body by a well known algorithm: .7zip. Kation.DLL is the only DLL included in the dropped file and so it is the run DLL by PiMP installer. Kation wraps out ADVAPI32.DLL and KERNEL32.DLL as you might see from Figure9. ADVAPI32 is a core Microsoft library which includes the Microsoft encryption libraries such as: EncryptFileA, EncryptFileW and so on and so forth. It's not hard to guess a new Ransomware infection from that API calls.

Figure9: Usage of Encryption Libraries

From a static analysis prospective it becomes clear that some of the used strings are dynamically allocated. For example in sub_10001170 (frame 0XBC) several UFT-16 strings within decryption loop are involved showing out the control flow passing to Etymology.Vs (Figure11).

Figure10: Setting the running pointer

Figure11: Decoding Functions

The real behavior is hidden into the Etymology.Vs encrypted file included in the PiMP solution as well. Running the infected sample it disclosures its real behavior: shown in Figure12.

Figure12: Ransom Request

Here we go,  we have just discovered a brand new Crypt0L0cker ! it asks for bitcoin (Figure13), of course.  Looking at network communications, a Domain Name Generator Algorithm (DNGA), [wow, it sounds new from CryptoL0Cker !] fires up as soon as the dropped file is executed. It looks for valid registered subdomains belonging with  Until a valid Command and Control answers to the CryptoLocker client it hides itself and performs simple DNS query as follows:


The process to contact the Command and Control in order to exchange key and to notify the attacker could be very time consuming, in some of my runs it took until 2 hours depending on the available Command and Control at the time being. It would be very nice to have extra time to reverse the DNGA but unfortunately my weekend time is ending up. 

Figure13: Ransom Request Web Page

Development language is French, and many piece of code reminds me the "gaming world".   The main Command and Control domain is registered in Moscow (RU) and the registrant is "privacy protected".

Results for Target:
Created Date :2017-02-07T12:37:10Z
Updated Date :2017-02-08T10:38:54Z
Results for Target:
Created Date :2017-02-07T12:37:10Z
Updated Date :2017-02-08T10:38:54Z

The ransom page (available on the following link) is registered by EPAG Domain Sercives GmbH (Bonn, Germany) and is written in Franc language:

Ok Let's have some brand new IoC:

Malicious hashes:

Malicious urls:

- base dns:

.?????? (6 characters)


Enjoy your new IoC

Thursday, December 15, 2016

Malware Training Sets: A machine learning dataset for everyone

One of the most challenging tasks during Machine Learning processing is to define a great training (and possible dynamic) dataset. Assuming a well known learning algorithm and a periodic learning supervised process what you need is a classified dataset to best train your machine. Thousands of training datasets are available out there from "flowers" to "dices" passing through "genetics", but I was not able to find a great classified dataset for malware analyses. So, I decided to do it by myself and to share the dataset with the scientific community (and everybody interested on it) in order to give to everyone a base point to start with Machine Learning for Malware Analysis. The first challenge I faced was to define features and how to extract them.  Basically I had two choices:
  1. Extracting features directly from samples. This is the easiest solution since the possible extracted features would be directly related to the sample such as (but not limited to): file "sections", "entropy", "Syscalls" and decompiled assembly n-grams.
  2. Extracting features on samples analysis. This is the hardest solution since it would include both static analysis such as (but not limited to): file sections, entropy, "Syscall/API" and dynamic analysis such as (but not limited to): "Contacted IP", "DNS Queries", "execution processes", "AV signatures" , etc. etc. Plus I needed a complex system of dynamic analysis including multiple sandboxes and static analysers.   
I decided to follow the hardest path by extracting features from both: static analysis and dynamic analysis of samples detonation in order to collect as much features as I can letting to the data scientist the freedom to decide what feature to use and what feature to drop in his data mining process. The analyses where performed through the sample detonation in several SandBoxes (free and commercial ones) which defined a first stage of ontologically homogeneous blocks called "Analyses Results" (AR). AR are too much verbose and they are not  performing well in any text algorithm of my knowledge.

After more readings on the topic I came up with Malware Instruction Set for Behaviour Analysis ( MIST) described in Philipp Trinius et Al. (document available here).  MIST is basically a result based  optimised representation for effective and efficient analysis of behaviour using data mining and machine learning techniques. It can be obtained automatically during analysis of malware with a behaviour monitoring tool or by converting existing behaviour reports. The representation is not restricted to a particular monitoring tool and thus can also be used as a meta language to unify behaviour reports of different sources. The following image shows the MIST encoding structure. 

A simple example coming directly from the aforementioned paper is showed in the following image where "load.dll" has been detected. The ‘load dll’ system call is executed by every software during process initialisation and run-time several times, since under Windows, dynamic-link libraries (DLLs) are used to implement the Windows subsystem and offer an interface to the operating system. Following how the load.dll has been encoded into MIST meta language.

I decided to use the same concept of "meta language" but with auto-descriptive logic (without encoding the category operation since it would not afflict the analyses) and every information organised into a well formed JSON File rather then into a line based text file in order to be used in external environments with zero effort.  The produced datasets looks like following:

DataSet Snippest (click to enlarge)
Each JSON Property could be used as an algorithmic feature of your desired Machine Learning algorithm, but the most significative ones would be the "properties" ones (the one labelled properties). Each property, by meaning of each field placed under the "properties" section of the produced JSON file, is optional and is structured as follows:

category_action_with_description |  "sanitized" involved subjects with spaces

So for example:

"sig_copies_self": "e5ed769a e5ed769a 98e83379"

It means the category is sig (stands for signature) and the action is "copies itself".  e5ed769a e5ed769a 98e83379 are 3 sanitize evidences of where the samples copies itself (see the Sanitization Procedure) 

 "sig_antimalware_metascan": ""

It means the category is sig (stands for signature) and the action is "antimalware_metascan". The evidences are empty by meaning no signature found from metascan (in such a case).

"sig_antivirus_virustotal": "ffebfdb8 9dbdd699 600fe39f 45036f7d 9a72943b"

It means the signature virus_total found 5 evidences (ffebfdb8 9dbdd699 600fe39f 45036f7d 9a72943b).

A fundamental property is the "label" property which classifies the malware family. I decided to name this field "label" rather than: "malware_name", "malware_family" or "classification" in order to let the compatibility with many implemented machine learning algorithms which use the field "label" to properly work (it seems to be a defacto standards for many engine implementations).

Sanitization Procedures

Aim of the project is to provide an useful and classified dataset to researchers who want to investigate deeper in malware analysis by using Machine Learning techniques. It is essential to give a speed up in performances on text mining and for such a reason I decided to use some well known sanitization techniques in order to "hash" the evidences letting unchanged the meaning but drastically improving the speed for an algorithm point of view. The following picture shows the sanitization procedures:

Sanitization Procedures (click to enlarge)

From a developer prospective the cited (and showed) procedures are not well written; for example are not protected and ".replace" could be not safe within specific inputs. For such a reason I will not release such a code. But please keep in mind that the result of my project is not the "sanitization code" but the outcome of it: the classified malware analyses datased, so I focused my attention on features extraction, samples collection,  aggregation, conversion, and of course analyses, not really in developing production code.

Training DataSets Generation: The Simplified Process

The whole process to obtain the training datasets is described in the following flowchart. The detonation of a classified Malware into multiple sandboxes produces multiple static and dynamic analyses colliding into an analyses results artefact (AR).  AR would be translated into a MIST elaborated meta language to be software agnostic and to give freedom to data scientists.

Data Samples

Today (please refers to blog post date) the collected classified datasets is composed by the following samples:
  • APT1 292 Samples
  • Crypto 2024 Samples
  • Locker 434 Samples
  • Zeus 2014 Samples
If you own classified Malware samples and you want to share it with me in order to contribute at the Machine Learning Training Datasets you are welcome, just drop me an email !
I will definitely process the samples and build new datasets to share to everybody.

Where can I download the training datasets ?  HERE

Available Features and Frequency

The following list enumerates the available features per each sample. The features, as mentioned, are optional by meaning you might have no all the same features for every sample. If the sample you are analysing does not have a specific feature you want consider it as None (or undefined) since that feature was not available for the specified sample. So if you are writing your of machine learning algorithm you should include a "purification procedure" which will ignore None features from training and or query.

List of current available features with occurrences counter. :

   'file_access': 138759,
   'sig_infostealer_ftp': 13114,
   'sig_modifies_hostfile': 5,
   'sig_removes_zoneid_ads': 16,
   'sig_disables_uac': 33,
   'sig_static_versioninfo_anomaly': 0,
   'sig_stealth_webhistory': 417,
   'reg_write': 11942,
   'sig_network_cnc_http': 132,
   'api_resolv': 954690,
   'sig_stealth_network': 71,
   'sig_antivm_generic_bios': 6,
   'sig_polymorphic': 705,
   'sig_antivm_generic_disk': 7,
   'sig_antivm_vpc_keys': 0,
   'sig_antivm_xen_keys': 5,
   'sig_creates_largekey': 16,
   'sig_exec_crash': 6,
   'sig_antisandbox_sboxie_libs': 144,
   'sig_mimics_icon': 2,
   'sig_stealth_hidden_extension': 9,
   'sig_modify_proxy': 384,
   'sig_office_security': 20,
   'sig_bypass_firewall': 29,
   'sig_encrypted_ioc': 476,
   'sig_dropper': 671,
   'reg_delete': 2545,
   'sig_critical_process': 3,
   'service_start': 312,
   'net_dns': 486,
   'sig_ransomware_files': 5,
   'sig_virus': 781,
   'file_write': 20218,
   'sig_antisandbox_suspend': 2,
   'sig_sniffer_winpcap': 16,
   'sig_antisandbox_cuckoocrash': 11,
   'file_delete': 5405,
   'sig_antivm_vmware_devices': 1,
   'sig_ransomware_recyclebin': 0,
   'sig_infostealer_keylog': 44,
   'sig_clamav': 1350,
   'sig_packer_vmprotect': 1,
   'sig_antisandbox_productid': 18,
   'sig_persistence_service': 5,
   'sig_antivm_generic_diskreg': 162,
   'sig_recon_checkip': 4,
   'sig_ransomware_extensions': 4,
   'sig_network_bind': 190,
   'sig_antivirus_virustotal': 175975,
   'sig_recon_beacon': 23,
   'sig_deletes_shadow_copies': 24,
   'sig_browser_security': 216,
   'sig_modifies_desktop_wallpaper': 83,
   'sig_network_torgateway': 1,
   'sig_ransomware_file_modifications': 23,
   'sig_antivm_vbox_files': 7,
   'sig_static_pe_anomaly': 2194,
   'sig_copies_self': 591,
   'sig_antianalysis_detectfile': 51,
   'sig_antidbg_devices': 6,
   'file_drop': 6627,
   'sig_driver_load': 72,
   'sig_antimalware_metascan': 1045,
   'sig_modifies_certs': 46,
   'sig_antivm_vpc_files': 0,
   'sig_stealth_file': 1566,
   'sig_mimics_agent': 131,
   'sig_disables_windows_defender': 3,
   'sig_ransomware_message': 10,
   'sig_network_http': 216,
   'sig_injection_runpe': 474,
   'sig_antidbg_windows': 455,
   'sig_antisandbox_sleep': 271,
   'sig_stealth_hiddenreg': 13,
   'sig_disables_browser_warn': 20,
   'sig_antivm_vmware_files': 6,
   'sig_infostealer_mail': 617,
   'sig_ipc_namedpipe': 13,
   'sig_persistence_autorun': 2355,
   'sig_stealth_hide_notifications': 19,
   'service_create': 62,
   'sig_reads_self': 14460,
   'mutex_access': 15017,
   'sig_antiav_detectreg': 4,
   'sig_antivm_vbox_libs': 0,
   'sig_antisandbox_sunbelt_libs': 2,
   'sig_antiav_detectfile': 2,
   'reg_access': 774910,
   'sig_stealth_timeout': 1024,
   'sig_antivm_vbox_keys': 0,
   'sig_persistence_ads': 3,
   'sig_mimics_filetime': 3459,
   'sig_banker_zeus_url': 1,
   'sig_origin_langid': 71,
   'sig_antiemu_wine_reg': 1,
   'sig_process_needed': 137,
   'sig_antisandbox_restart': 24,
   'sig_recon_programs': 5318,
   'str': 1443775,
   'sig_antisandbox_unhook': 1364,
   'sig_antiav_servicestop': 78,
   'sig_injection_createremotethread': 311,
   'pe_imports': 301256,
   'sig_process_interest': 295,
   'sig_bootkit': 25,
   'reg_read': 458477,
   'sig_stealth_window': 1267,
   'sig_downloader_cabby': 50,
   'sig_multiple_useragents': 101,
   'pe_sec_character': 22180,
   'sig_disables_windowsupdate': 0,
   'sig_antivm_generic_system': 6,
   'cmd_exec': 2842,
   'net_con': 406,
   'sig_bcdedit_command': 14,
   'pe_sec_entropy': 22180,
   'pe_sec_name': 22180,
   'sig_creates_nullvalue': 1,
   'sig_packer_entropy': 3603,
   'sig_packer_upx': 1210,
   'sig_disables_system_restore': 6,
   'sig_ransomware_radamant': 0,
   'sig_infostealer_browser': 7,
   'sig_injection_rwx': 3613,
   'sig_deletes_self': 600,
    'file_read': 50632,
   'sig_fraudguard_threat_intel_api': 226,
   'sig_deepfreeze_mutex': 1,
   'sig_modify_uac_prompt': 1,
   'sig_api_spamming': 251,
   'sig_modify_security_center_warnings': 18,
   'sig_antivm_generic_disk_setupapi': 25,
   'sig_pony_behavior': 159,
   'sig_banker_zeus_mutex': 442,
   'net_http': 223,
   'sig_dridex_behavior': 0,
   'sig_internet_dropper': 3,
   'sig_cryptAM': 0,
   'sig_recon_fingerprint': 305,
   'sig_antivm_vmware_keys': 0,
   'sig_infostealer_bitcoin': 207,
   'sig_antiemu_wine_func': 0,
   'sig_rat_spynet': 3,
   'sig_origin_resource_langid': 2255

Cite The DataSet

If you find those results useful please cite them :

@misc{ MR,
   author = "Marco Ramilli",
   title = "Malware Training Sets: a machine learning dataset for everyone",
   year = "2016",
   url = "",
   note = "[Online; December 2016]"

Again, if you want to contribute ad you own classified Samples please drop them to me I will empower the dataset.

Enjoy your new researches!

Sunday, October 30, 2016

Dirty COW Notes

I am not used to write about vulnerabilities because there are too much vulnerabilities out here and writing about just one of them is not going to contribute security community at all. So why am I writing about Diry Cow ? I am going to write about it because, in my personal opinion, it is huge. When I say "huge" I don't really mean it will be used to exploit the "entire world" but I mean it highlights two mains issues:
  • Even patched code could easily hide the same vulnerability, just in a different way. How many patched code are not really "patched" ?
  • A new pragmatic approach to identify vulnerabilities: looking into patched code and check the  patch implementation.
But let's start from the beginning by taking a closer look to the exploit code.

Click to enlarge: Taken From Here

As many other kernel vulnerabilities it relays on concurrency; the exploit code fires on two separate threads who will access at the same time to the same resource.  Taking a closer look to the main function you will see that the mmap syscall has been used.

calling mmap function
From documentation:
creates a new mapping in the virtual address space of the calling process. The starting address for the new mapping is specified in addr. The length argument specifies the length of the mapping.

mmap does not create a memory copy but rather it creates a new mapping of that (filedescriptor) memory area. It means the process will read data directly from the original file rather than from a copy of it.  While most of the parameters are obvious the MAP_PRIVATE flag is the "core" of the vulnerability. It enables the "copy on write" (from here the name COW) which basically copies the original data in a new memory area during the write access to the same data. Since the mmap has just mapped a readonly area and the process wants to write data on it, mmap (MAP_PRIVATE) will create a copy of that data on write actions, the modified data will not be propagated to the original memory area. 

Now the exploit runs two threads which will exploit a race condition to get "write access" to the original memory area. The first thread runs several times the function call madvise (memory advise) which is used to increase process performances by tagging a memory area according to its usage: for example  the memory could be tagged as NORMAL,  SEQUENTIAL, FREE or WILLNEED, an so on... In the exploit, the mmap memory is continuously tagged as DONTNEED,  which basically means the memory is not going to be used in the next future so the kernel could free its space and reload the content only when needed.

First Thread implementing madvise

On the other hand another thread is writing on its own memory space (by abusing the pseudo file notation: /proc/self/mem) directly on the mmap area pointing to the opened file. Since we have invoked the mmap function through the MAP_PRIVATE flag we are not going to write on the specifi memory but on a copy of it (copy on write).

Second Thread implementing write on pseudo self/mem

The race condition between those two threads tricks the write on copy on the original memory area since the copied area could be tagged has DONTNEED while the write procedure is not finished yet. And voilà you are going to write in a readonly file !

OK now we figured out how the trick worked so far but what is most interesting is the story behind it?

Going on issue tracker: Linus Trovalds (maximum respect) wrote:

This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix get_user_pages() race for write access") but that was then undone due to problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug"). In the meantime, the s390 situation has long been fixed, and we can now fix it by checking the pte_dirty() bit properly (and do it better). The s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement software dirty bits") which made it into v3.9. Earlier kernels will have to look at the page state itself. Also, the VM has become more scalable, and what used a purely theoretical race back then has become easier to trigger.
S390 is ancient IBM technology.... I am not even sure it still exists on real world (at least if compared to recent systems). Probably linux community forgot about that removal otherwise would left it in the recent memory managers.

Anyhow the bug now "has been fixed" by introducing a new internal Flag called FOLL_COW (really !?J) which basically says "yes I already did the copy on write".
Basically the process can write to even unwritable pte's, but only after it has gone through a COW cycle and they are dirty. Following the diff patch

Dirty Cow Patch3 on October 2016

Dirty Cow vulnerability blowed in my mind a new vulnerability hunting process. On one hand laboratories with extremely sophisticated, tuned and personalised fuzzers perform the "industrial" way (corporate and/or governative) to find new vulnerabilities, on the other hand more romantic and crafty way done by professionals and/or security researchers used to adopt handy works and smart choices. But another smart approach (industrial or romantic) could be to investigate into the patched code by itself.

Patched code is by definition where a bug or issue where located. The most difficult part of finding vulnerabilities (not exploiting them) is to figure out where they are in thousands lines of code. So finding vulnerability on patched code could be much more quick even if with high "hypothetical" complexity since a patch is involved. But as this case testifies ...  is not always the case!

Monday, October 17, 2016

Cybersecurity Awareness

My little contribution on cybersecurity to national TV channel; next to Evgenij Valentinovińć Kasperskij, founder of Kaspersky Anti Virus Engine.

Tuesday, September 20, 2016

Internet of Broken Things: Threats are changing, so are we ?

Hi Folks, this is another blog-post on internet of "broken things". As many of you are familiar with MQTT is one of the most used protocol over the Internet of Things. It's widely used in private area network - to make communications quick and light - and on public network as well - to build communication channels between sensors end / or servers messages -

MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. For example, it has been used in sensors communicating to a broker via satellite link, over occasional dial-up connections with healthcare providers, and in a range of home automation and small device scenarios. t is also ideal for mobile applications because of its small size, low power usage, minimised data packets, and efficient distribution of information to one or many receivers.

Inspired by Luca Lundgren talk on Defcon 24 titled: "Light Weight Protocol! Serious Equipment! Critical Implications!" I decided to verify myself the state of the art on MQTT implementations.

How MQTT works:

Understanding how MQTT protocol works, invented by Andy Stanford-Clark di IBM and Arlen Nipper Cirrus Link Solutions, is crucial to figure out why poorly authentication implementations will cause serious information disclosure issues.. MQTT stands for Message Queue Telemetry Transport and now is an OASIS standard. It has been designed for sending telemetry data and often runs the challenge against REST HTTP API in modern IoT environments. While is not a common protocol to build communication between clouds (and servers) since AMQP (Advanced Message Queuing Protocol) is much more expressive and performant it is often preferred to to build communication between small objects (things) to small objects (things). 

The protocol relays on a central node called "Broker" who is organised in specific programmable topics. Publishers (things) are able to publish informations to specific topics (such as but not limited to: temperature, localization, humidity, etc. ) while subscribers (applications) are able to get data from an interested and explicit topic. The following image represents a general architectural view. It's clear that a poorly implemented authentication mechanism will let the subscribers free to get the overall published data.

MQTT Architecture Flow
The beauty of unauthenticated MQTT sessions is in the subscriber topic list.  Indeed it is able to subscribe to every topic on the selected brokers by simply putting an # as topic even if it does not know the topics list.

Simple Experiment:

Let assume we might find some unauthenticated MQTT brokers, what kind of message could be identified ? Hopefully not sensible data. Let's see it !

Step 1: Discovery.
masscan even if not  assiduously upgraded is still one of my best solution to map Internet. I performed a simple massive scan in order to figure out servers with open ports on 1883 (it's the default MQTT broker port). I know... if a server owns a 1883 open port does not mean it runs a MQTT broker on it.. I totally agree but my point is not a quantitative analysis but a quality analysis, so I do not care about how many real MQTT brokers are out there but if I can find sensible data on one of them. 

sudo bin/masscan --exclude -p1883 --max-rate 10000 -oX mas1883.xml 

After few hours thousands of ip populate my "mas1883.xml" file

Step 2: Identification.
Assuming we get thousands of valid IPs running MQTT brokers we need to try to subscribe to all of them and try to subscribe to every topic. Let's write a quick'n dirty 20 lines of code to make it happens. 

Quick'n dirty script automation subscriptions (click to enlarge) 
Step 3: Results Analysis
After few running hours, I've got back interesting results (they were piped into different files from the launch bash script, so simple I did not even mentioned it). In order to describe the results I'd like to classify them into two simple sections: Note sensible data and Sensible data.

Not sensible data. MQTT messages that does not refer directly to sensible information but still interesting from attackers such as: Temperature,  Presence,  Lights sensors and commercial. If those informations get to malicious physical attacker's hands he can figure out if when to physically attack the building since it is easy to detect human presence. The following image shows  records belonging to Presence Sensors (PIR), Power Sensors, Humidity Sensors, Temperature Sensors and Noise Sensors.

Anonymised Not Sensible Data (click to enlarge)
For example an attacker could use those data to understand if in a room -- of such anonymised building -- are people in there (thanks to the value of the PIR sensor) or if someone is close to the room (thanks to noise sensors) or if somebody has been in the room (thanks to delta temperature sensors). Those informations are useful to plan an attack. So even these informations are not sensible per se it is still important to protect them. 

Another great example comes from an unauthenticated server hosting Samsung Smartthings devices.

Samsung Smartthings devices data (click to enlarge)
As you might see (enlarging the previous image.. :) we can totally monitor the "building". We know where sensors have been placed (network_cabinet, master_bedroom, parkers_closet, garage_door, home_assistant)  and what value do they have. It is not hard to find an empty room or an empty room_door_path to a target in the building.

Sensible data. MQTT data that directly refers to private information such as (but not limited to): Text Messages and Phone Geolocalization.  The following image shows text messages between two users. The used language is Italian and a close translation could be:
- "Talk to you soon"
- "Bye"

Anonymised Private Messages (click to enlarge)

The following image shows private information between pharmaceutical products (please do not ask me more about it... I wont give out much details, the pharmaceutical service has been alerted).

Anonymised Private Message between pharmaceutical services (click to enlarge)

The following image shows an interesting "spying" service (actually it's which communicates geo-location over MQTT unauthenticated brokers.

Geo-location tracks (click to enlarge)

Naturally such a private information should not be freely accessible. For example knowing where people are without their permissions is illegal in many states, or reading their application messages without judiciary consent is illegal in many states as well. Naturally the correlation to such information is illegal as well. Unfortunately attackers are everywhere and thanks to internet and telecommunication their malicious activities could have global impacts. Nowadays everybody has got a smart devices, everybody keeps trace of own steps, everybody keeps monitored own heart and everybody put everything on a cloud who does not belong to him. On the other hand applications are not always well protected making data freely available and exposing data owner to incredible indirect risks.

Final Thoughts:
Unfortunately Is not possible to stop this process: Tomorrow there will be more smart things that today. Unfortunately is not possible to protect everything: products have to get to the market as quick as possible to gain market. This process is quicker than the ability of the security community to safely test everything. De facto we will continue to use even more "smart things" which will monitor everything about our life.

Threats are changing, so are we  ?