Didier Stevens

Wednesday 30 December 2009

Detecting EICAR With a .NET Micro-controller

Filed under: .NET,Entertainment,Hardware — Didier Stevens @ 22:07

I’ve been playing with a .NET Micro Framework micro-controller: the USBizi. A few of its interesting characteristics are that you program it in C# with Visual Studio and that in-circuit debugging (including single-stepping) is supported.

The .NET Micro Framework has no assemblies to support USB in host mode (only guest mode), but the USBizi comes with assemblies for host mode providing support for removable drives like USB sticks. To illustrate this feature, I wrote a program to scan the files on a USB stick for the EICAR test file and replace the content with a message appropriate for the time of the year.

Some ideas I’ve for this device: program it as a hardware keylogger, a hardware password vault, …

using System.Threading;
using System;
using System.IO;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using GHIElectronics.System.SystemDevices;
using GHIElectronics.System;
using GHIElectronics.System.IO;
using GHIElectronics.Hardware;

namespace USBiziEICARDetector
{
    public class Program
    {
        static string sEICAR = @"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*";

        static void Main()
        {
            Boolean bFoundEicar;
            Debug.Print("Starting...");
            while (true)
            {
                // must start system first, no event is associated
                SystemManager.Start(null);
                // wait till we have a device
                while (SystemManager.GetDevices().Length == 0)
                    Thread.Sleep(500);
                // get a list of devices
                Device[] devices = SystemManager.GetDevices();
                // look for a device
                foreach (Device device in devices)
                {
                    // this loop will run once for every device
                    if (device.deviceType == DeviceType.Drive)
                    {
                        try
                        {
                            // USB drive is inserted
                            // Create a new storage device
                            PersistentStorage PS = new PersistentStorage(device.deviceID);
                            // now everything works just like on SD cards....
                            // Mount the file system
                            PS.MountFileSystem();
                            // Assume one storage device is available, access it through NETMF
                            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                            bFoundEicar = false;
                            string[] files = Directory.GetFiles(rootDirectory);
                            Debug.Print("Files on root of USB drive...");
                            foreach (string file in files)
                            {
                                Debug.Print(file);
                                Boolean bFileIsEICAR = false;
                                FileStream fs = File.OpenRead(file);
                                Debug.Print(fs.Length.ToString());
                                if (fs.Length == sEICAR.Length)
                                {
                                    char[] acEICAR = sEICAR.ToCharArray();
                                    for (int iIter = 0; iIter < sEICAR.Length; iIter++)
                                    {
                                        int iByte = fs.ReadByte();
                                        if (acEICAR[iIter] != iByte)
                                            break;
                                        if (iIter == sEICAR.Length - 1)
                                        {
                                            bFoundEicar = true;
                                            bFileIsEICAR = true;
                                        }
                                    }
                                }
                                fs.Close();
                                if (bFileIsEICAR)
                                {
                                    byte[] abHappyNewYear2010 = {
                                        0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x20, 0x58, 0x58, 0x58, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20,
                                        0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20,
                                        0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20,
                                        0x20, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x58, 0x58, 0x58,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x58,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20,
                                        0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58,
                                        0x0D, 0x0A, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20,
                                        0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20,
                                        0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20,
                                        0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20,
                                        0x20, 0x20, 0x58, 0x0D, 0x0A, 0x20, 0x58, 0x58, 0x58, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x20, 0x58, 0x20, 0x20, 0x58,
                                        0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58,
                                        0x58, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                                        0x20, 0x58, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58,
                                        0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x58, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x58, 0x58, 0x0D, 0x0A, 0x0D, 0x0A};

                                    File.WriteAllBytes(file, abHappyNewYear2010);
                                    Debug.Print("EICAR found!");
                                }
                            }
                            Debug.Print("... end of list!");
                            // if we need to unmount
                            Thread.Sleep(500);
                            PS.UnmountFileSystem();
                            Thread.Sleep(500);
                            PS.Remove();
                            OutputPort LED = new OutputPort(USBizi.Pins.E2x, false);
                            if (bFoundEicar)
                            {
                                Debug.Print("bFoundEicar = true");
                                BlinkXTimes(LED, 4, 300);
                            }
                            else
                            {
                                Debug.Print("bFoundEicar = false");
                                BlinkXTimes(LED, 2, 300);
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.Print("Exception:");
                            Debug.Print(e.Message);
                        }
                    }
                }
                Thread.Sleep(500);
                SystemManager.Reboot(SystemManager.RebootMode.Normal);
            }
        }

        public static void BlinkXTimes(OutputPort LED, int times, int milliseconds)
        {
            for (int i = 0; i < times; i++)
            {
                LED.Write(true);
                Thread.Sleep(milliseconds);
                LED.Write(false);
                Thread.Sleep(milliseconds);
            }
        }
    }
}

Blog at WordPress.com.