SecureArtisan

My Road to Digital Forensics Excellence

Verifying a Wiped Drive

Posted by Paul Bobby on September 23, 2010

I recently had the task of verifying that a 32gig SSD had been successfully bricked by overwriting every single sector with 0xFF. A couple of quick hit approaches came to mind.

  1. Run the consecutive sectors enscript. ETA to complete was approximately 6hours with my hardware. Besides, this enscript is designed to identify patterns to discover if wiping had occurred. I already knew this so perhaps the script was overkill.
  2. Run a keyword search for [^\xFF]. The ETA for this search was 30 minutes. Not bad. The idea here is to find a search hit on anything other than the byte 0xFF.

But is there a better way? Well there’s my way but unfortunately it took the same time as #2 (hey it gave me something to blog about anyway 🙂 )

Here is the basic code block:

    // Script specific variables
    long clusterSize = 4096;
    EntryFileClass ef();
    MemoryFileClass mf();
    long fileSize;
    long filePos;
    // This hard coded value represents an MD5 checksum of 4096 bytes containing the value \xFF.
    HashClass wipeHash("6AE59E64850377EE5470C854761551EA");
    //
    // Script specific code start
    forall (DeviceClass d in c.DeviceRoot()) {
      if (ef.Open(d,0,-1)) {
        ef.SetCodePage(CodePageClass::ANSI);
        ef.Seek(0);
        fileSize = ef.GetSize();
        while (filePos < fileSize) {
          if (mf.Open(clusterSize, FileClass::WRITE)) {
            mf.SetCodePage(CodePageClass::ANSI);
            mf.WriteBuffer(ef,clusterSize);
            mf.Reset(0);
            HashClass mfHash = mf.ComputeHash(-1);
            if (mfHash.Compare(wipeHash) != 0) {
              CLog.Debug("POS: " + filePos + ":"+mfHash);
            }
            mf.Close();
          }
          filePos += clusterSize;
          ef.Seek(filePos);
        }
        filePos = 0;
      }
        else CLog.Fatal("Cannot create EntryFileClass out of "+d.Name());
    }




This code iterates through each attached device and calculates the MD5 hash for each 4096byte read from that device. It makes use of MemoryFileClass to store the 4096bytes that are read, and compares the MD5 hash of this memory file with the hard coded hash in line 8. If the hash value does not match, the file position is displayed in the console.

One of the gotchas of this code is line 20. Without resetting the memory file pointer to the beginning of the MemoryFileClass object I would get incorrect hash results.

The next step is to include a GUI element with this code so that it queries the user for the wiping pattern and generates the MD5 hash value to compare against.

Advertisements

4 Responses to “Verifying a Wiped Drive”

  1. A. Thulin said

    What does the script do if the drive does not contain an even clusterSize? i.e., the number of sectors on the drive is not an even multiple of 8?
    It looks as if it fails to check the last few sectors, and it looks as if that failure also is silent, i.e. the user is not told that all sectors haven’t been checked.

    Is clusterSize the ideal data size to read? Ignoring the md5-checksumming for the moment, would the rest of the code run faster or slower if a larger chunk of bytes were read at a time? (I am assuming that the script is run against a live disk, and not just an acquiry image.)

  2. A. Thulin said

    Added … of course, for a one-shot script that never needs to execute again, running speed is not really important, so perhaps my last comment above was not really to the point.

  3. Paul Bobby said

    For this code snippet the problem did not manifest itself since I was checking for a single byte wiping pattern. Using the variable ‘clustersize’ was actually a misnomer. I wasn’t reading a cluster at all, just 4096bytes at a time.

    I wrote this ‘quickhit’ for a very specific hardware case I had on Friday. I had a 32gig SSD drive that gets bricked through push of a button. 20 seconds later every byte is 0xFF. I had to test that. And it worked. Looking back on it, I guess I was lucky in that 32gigs was evenly divided by 4096.

    The final enscript had to be a bit more polished, for example the enscript actually reads in a sector at a time (from device.getSectorSize).

    The real problem I found is the wiping pattern – a three byte wiping pattern wraps around sector boundarys, throwing off the MD5 checksum if I were only to read one sector at a time. So reading in data (sectorsize * sizeof(WipingPattern)) fixed that.

  4. Manuel said

    Thank you for the example. I change the code to obtain SHA1 of Device.

    This is my code:

    /* Calcula el SHA1 de un dispositivo */
    String SHA1Device(DeviceInfoClass deviceInfoClass)
    {
    // Variables
    EntryFileClass entryFileClass();

    if (entryFileClass.Open(deviceInfoClass, 0, -1))
    {
    SHA1Class sha1Class();
    if ((entryFileClass.ComputeSHA1(sha1Class, -1)) && (sha1Class.IsValid()))return sha1Class.GetString();
    else return "";
    }
    else return "";
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: