Dynames Productions

A blog to showcase my creative and technical work. Talk about what I like to talk about.


Leave a comment

USB Security App – Hacking #1

Introduction

Hey everyone, thanks for checking out this post. For those unable to tell from the title, this post is targeted towards my USB Security Application, and hacking it.

Details of activities

Goal: To extract the Encryption/Decryption key from the application.

It should be noted that as this application is for educational purposes, the key itself has been hard-coded into the code. Meaning, extracting it is a goal that will lead to thinking of ways to try and further improve the security of these keys.

Tools Used

  1. Sysinternals Suite (strings.exe): Used to extract strings and study what contents were taken out. The reason for doing this is to see how much of it is bare to someone looking to see the inner workings of the application.
  2. netshrink: A .net packer for executables that obfuscates strings and makes the string extraction mostly pointless as it becomes unreadable at that point. There are some things that can still be determined from an obfuscated executable however.
  3. hiew (Demo version): Used to study the hex dump of the strings and see how different they are from the packed version to the normal one.
  4. ILSpy: A free .net disassembler that is able to disassemble the executable and compile it into C# code for reading. This can help to determine the flow of the program, but also give valuable information about it.

Step 1: Strings and Hex Dump

Using both strings.exe and Hiew, I was able to extract the strings, dump them to a text file as well as view a hex dump of the two executables. One was the normal version, while the other was the packed version. The following photos show the difference.

5

Normal Version

The various functions used by the program can be observed on the right of the screenshot above. The content to the left just after the colons are the hex values of the individual ascii characters defining the strings of various function names, and messages within the program. The values to the left of the colons are virtual memory addresses. The main point here is that the strings can be read in clear text. When using strings.exe, this can be saved to an external text file for an even easier viewing of the strings.

It should be noted, that the actual encryption and decryption key (composed of IV (Initialization Vector) and the key itself), are not found in there.

6

Packed Executable

The difference should stick out as the text from the above screenshot seems nothing more than gurgled nonsense here. The virtual memory addresses are also different from what we see in the original executable. From my understanding, what packing the executable does is that it compresses the original file, but adds in decompression code on top of it while the strings are scrambled in the compression process. What we see as strings in the packed executable are simply what’s read from the file, rather than first it being decompressed and then reading.

The decompression should occur when the file is actually executed, however as we will see later on, that did not exactly happen.

What did doing all of this exactly achieve?

The point was to answer my curiosity of what will be seen between a packed and a non-packed executable file. It was also to determine if I could see the encryption/decryption key.

Step 2: Disassembling the Executables

Normally software like IDA Pro is considered an industry standard. However, I opted to use something more specifically built for .net. This led me to ILSpy. It’s streamlined interface was also very helpful in being able to see how much is exactly extracted from the executables.

First, lets see what happens when I try the packed version:

4

The PEFile properties themselves are not supported. This leads me to believe that the disassembler is not able to decompress it and look into the actual code. It could be that, or it could also ultimately be the fact that it simply was not packed properly, potentially corrupting the PEFile properties.

Lets see what happens when I try the normal version:

1.PNG

As evidenced by the picture, we can see all the functions in the program. These are also accessible, and as I had expected, the code is readable clear as day. In fact, to get the encryption/decryption key, all one would have to do is attach this disassembler to the executable, and they will get all the information they want about the program.

2.PNG

Disappointingly, it indeed was this easy.

That’s how simple it really was. Just take the original executable, and hook it up to the disassembler to see the C# code inside. Now this would be a different story had the packed version been actually disassembled, I doubt we would have seen much information of use. As I mentioned, I did not try IDA Pro on this, it is possible that we could still get some form of assembly out of the packed version, as with the original to, which could help make some sense of what is happening under the hood of the application.

But with this, the goal was accomplished, and quite easily so. This leaves serious concerns for the practices I have employed with the key storage if this were to be an actual production application. However, I do have an idea on how to resolve this which will be covered in the conclusion section.

Executing the Two Files

Before I said in the step 1 section that the packed file did not execute as expected. The following screenshots should shed some light on the matter.

3

Executing the 2 files

When I try to execute the packed version, an error would pop up as shown in the screenshot below. But when I execute the original file, the program works just fine.

7

Executing the packed version

In this error, we are told that we are missing a .dll file. It is very well possible that the packed file is looking for a different run-time version than what is currently available on the machine at the moment.

Doing further research would indicate that to be the case as the dll file “msvcr71d” itself is a C Run-time library. It is also the debug version of msvcr71.dll (the added d to the end after 71 indicates debugging). Downloading and moving this file into the proper location should theoretically resolve this issue. I will make an update to this post should I get the chance to test this idea.

This happens for both the 32 bit and 64 bit versions of the file.

Conclusion(s)

The goal was to figure out the encryption/decryption key as someone without any knowledge about the program. Some techniques that were tried were to see a hex dump and strings extraction of the various executables. One was the original .exe file, while the second was a packed version to see what difference it would make.

While the difference was obvious in the hex dump and the strings, it created for issues when it came to executing the packed version. But the most interesting bit was the disassembler as it was able to extract every bit of code in-tact from the original file. Where as it struggle with the packed version, possibly because it could not decompress it and then peer inside to the C# code, or perhaps the compression was not done well, potentially corrupting the file’s PE properties.

Now, since I was able to get the encryption/decryption key out, it meant that I met the end goal of this particular exercise. The important bit is how can we exactly secure this, so that even if someone were to get a hold of the code, they can’t easily figure out the encryption/decryption key.

Potential Solution:

Change the way encryption/decryption is handled. Rather than having a preset hard-coded key, a key is dynamically generated every time the user asks for one. The key will then be requested of the user any time they want to encrypt or decrypt the contents. Keeping the key safe will be the responsibility of the user.

What this does is that it ensures that even if someone manages to get the password, or brute-force their way into the application, they won’t have access to the key itself which is integral to the whole operation. The only way to obtain the key would be to either social engineer the key holder, obtain any physical or logical file that may store such data, or in a more complicated method, install a keylogger onto the victim’s system and send data to the attacking machine either through a back door or through other means. This dramatically decreases the chances of someone figuring out the possibility of decrypting a user’s data.

The flow of events for this proposed solution would be as follows:

  1. User wants to create an encryption/decryption key.
  2. The user inputs in a password that they selected at the beginning when they first ran the program.
  3. The program then randomly generates an encryption/decryption key that is composed of:
    1. Lower/Upper letters
    2. Numbers
    3. Special Characters
  4. The user will then be asked to input that key in every time they wish to encrypt or decrypt the data. Should they want to change keys periodically, they are free to generate more. BUT, the right keys must be used when decrypting the data. The key that encrypted it must be used to decrypt it as well, otherwise it won’t work as you will have the wrong key to the lock.

How the key is kept safe is up to the user at that point. They can either memorize it, write it down or type it out into a file.

So I suppose the next step would be to actually figure out an algorithm behind the random key generator and implement this process. Then also refine the application further, but at the same time, see how else it can be broken through either the use of process injection, potentially creating/using rootkits (if I’m feeling adventurous) or as I had mentioned before, keyloggers. We can build one in python, and see the type of data come to us through either the creation of a backdoor or sending it over the network via email.

If there are any updates to be made in the future to this post, they will come down here…

Advertisements


Leave a comment

Job Page HTML Parser – Python

Introduction:

Over the past year or so, I started doing some python. Recently using what I know of python,  I created a simple HTML parser to be able to parse through jobs listed on a company’s website. What the parser does is it looks for specific strings within the HTML code that is broken down into a list, and then parses out the necessary content that is requested by the program. That information is then dumped into a CSV file that the user can review at their leisure.

Note: This is the first time I tried the code block feature here on WordPress, so I realize that some things may not come out as expected. I apologize for that in advance if there are any huge mistakes.

Program Details:

  • Language: Python (executed via command line)
  • Objective: To increase the ease of job hunting.
  • Limitations to the program: Since it works based off of HTML, it can only work on the website I programmed it for. Python is essentially a scripting language, now it is possible to create an actual job scrapper using python but is more involved, either that or us an API to make your life easy. Every company’s website will be different in terms of structure and HTML section tags, hence the limitation on my little program to only work exclusively on the one website.
  • Note(s):
    • The main point here is to show how something like this can be achieved as a parsing program, so I won’t be showing the targeted site here.

Program Explanations + Code:

Packages imported:

import sys
import os # Note: Import not used, no longer necessary.
import urllib2
import csv

The “os” package is not necessary, but as I was creating this program before, I had used it for removing a saved html file of the jobs page. But I removed that feature as it was unnecessary and I could directly save the content I get from the urllib2 response read.

sys – Helps to interact with the host system.

urllib2 – Used for network based activities such as sending requests and getting responses from URLs, as well as getting their HTML code.

csv – Contains methods  to help create, write to and save CSV files.

Lists and Dictionary declarations:

provinceDict = {"ON":"Ontario", "QC":"Quebec", "NS":"Nova Scotia", "NB":"New Brunswick", "MB":"Manitoba", "BC":"British Columbia", "PE":"Prince Edward Island", "SK":"Saskatchewan", "AB":"Alberta", "NL":"Newfoundland and Labrador"}
inner_list = ['Job Title', 'City', 'Province', 'Postal Code', 'Job URL']
outer_list = []

outer_list.append(inner_list)
inner_list = ['----------------------------------------------------------------------------------------------------------------------------------------', '-----------------', '-----------------', '-----------------', '----------------------------------------------------------------------------------------------------------------------------------------']
outer_list.append(inner_list)

provinceDict – Province Dictionary for within Canada. The keys are the abbreviated versions of the provinces, where as the values are the actual names that will be written to the CSV files.

inner_list – Defines the rows of the CSV file. This value is reset to blank every time a new row needs to be written.

outer_list – Is a basically 2D List (like 2D Array), where it contains the data for the whole file. So row data from the inner_list gets written here, but the data actually written out to the CSV file comes from this list.

Getting HTML code from job page:

num = 0
loop = 0 # For infinite loop.
while(loop == 0):
    request = urllib2.Request('some_url/%d/' % (num)) # Request for the html page of the specified URL.
    response = urllib2.urlopen(request) # Gets a response in raw data.
    html = response.read() # Reads the HTML out of the response data for us to manipulate for our own benefit.

    # Run a check against the HTML content to make sure we haven't gone into the no job postings territory!
    if(html.find("There are currently no open positions matching this category or location.") != -1):
        break
    else:
        num = num + 25

    content = html.split() # Saves the html content into list for easier parsing.

The operation to create the rows for the CSV takes place within 2 loops (nested loop within a parent loop). This is the beginnings of the first loop. Here is the sequence of operations for the code above:

  1. Create a request to the specified URL.
  2. Ask for a response from the created request sent using urlopen.
  3. Read the HTML code out from the response’s raw data.
  4. Check to see if there is a string within the HTML that seems to indicate that there are no job postings on this page.
    1. If there are none, exit this loop and write out the results to the file.
    2. Otherwise, increment the URL value to the next page and continue with regular operations.
  5. Split the read HTML content for the job page into a list named “content”. That is what will be used for manipulation operations.

In the URL for the request, you may notice that I have a “%d” in there. That is an identifier for an integer number. The reason I have it in there is in-case there are more than one pages of jobs. If there isn’t any, my following find and then if/else statement takes care of that scenario.

Meat of the program:

Setup:

    contentLen = len(content)
    i = 0
    provCount = 0

    while(i <span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0;"></span>")[1]
            title = titleTemp.split("&lt;&quot;)[0]

            # 2 - Strip and extract Province information.
            for provCount in provinceDict:
                provFindRes = title.find(provCount)

                if(provFindRes != -1):
                    jobProv = provinceDict[provCount]

                    # 3 - Get postal codes.
                    postCodeTemp = title.split(provCount + &quot;-&quot;)[1]
                    break

            # 4 - Format Postal Code information.
            postalFind = postCodeTemp.find(&quot;-&quot;)

            if(postalFind != -1):
                # Replaces the dash with a space.
                jobPostalCode = &#039;&#039;
                jobPostalCode = postCodeTemp.replace(&quot;-&quot;, &quot; &quot;)
            else:
                # Put in a space after three characters.
                jobPostalCode = &#039;&#039;
                postCodeInc = 0

                while(postCodeInc &lt; 6):
                    if(postCodeInc == 2):
                        # Input space character, and then the next character in sequence.
                        jobPostalCode = jobPostalCode +  postCodeTemp[postCodeInc]
                        jobPostalCode = jobPostalCode + &quot; &quot;
                    else:
                        jobPostalCode = jobPostalCode + postCodeTemp[postCodeInc]

                    postCodeInc = postCodeInc + 1

This bit of the information can only be extracted if "jobURLTitle" is actually found in the content[position] string. If found:

  1. HTML characters like “” are stripped. This creates a temporary title to store.
  2. Job province information is next extracted:
    1. We loop through the province dictionary with the keys and try to find them in the title
    2. As every posting has the province listed in there, it will find one eventually. Once it does, the value for jobProv is set based on the determined key.
  3. Postal Code is then targeted:
    1. We get the unformatted postal code by splitting the title string apart and taking the right side of the string.
    2. Now we format the postal code. Is there a dash in the extracted temporary postal code value?
      1. If yes: Then we do a simple replace of the “-” character with a blank space into the jobPostalCode variable.
      2. If no: Then there is most likely no space as only those two seemed to be the convention, either a dash or no space between characters. If this is the case, we need to input a space after cycling through the temporary postal code. We need to treat this like an array then. Doing so allows us to loop through the array, after getting to a certain point we can input the space and then continue adding the characters to the jobPostalCode variable.

Getting – City and Job Title Information:

            # 5 - Strip and extract City information.
            jobCity = title.split("-")[0]

            # 6 - Get only the job title out.
            jobTitleTemp = title.split("-")

            l = 1
            k = 0
            jobTitleLen = len(jobTitleTemp)
            jobTitle = ''

            while(l <span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0;"></span>&lt; jobTitleLen):
                if(jobTitleTemp[l] in provinceDict):
                    break
                if(jobTitleTemp[l].find(&quot;%2C&quot;) != -1):
                    jobTitleTemp[l] = jobTitleTemp[l].replace(&quot;%2C&quot;,&quot;,&quot;)
                if(jobTitleTemp[l].find(&quot;%28&quot;) != -1):
                    jobTitleTemp[l] = jobTitleTemp[l].replace(&quot;%28&quot;,&quot;(&quot;)
                if(jobTitleTemp[l].find(&quot;%29&quot;) != -1):
                    jobTitleTemp[l] = jobTitleTemp[l].replace(&quot;%29&quot;,&quot;)&quot;)
                jobTitle = jobTitle + jobTitleTemp[l] + &quot; &quot;
                l = l + 1

To get the city:

  1. It’s not hard as it normally is the first thing in the title divided by a dash character. So all it requires is for us to split the string at the dash and take what is to the left of it.

To get the job title:

  1. Store a the un-formatted title in a temporary variable as a list named “jobTitleTemp”.
  2. Cycle through every element of the list to see if various conditions are met or not.
    1. If the current element is in the province dictionary, we break out of that while loop and stop the operation.
    2. The next couple of if statements check for certain hex values present in the current element of the list. If it is, the hex value is replaced by its proper ASCII character.
  3. The element from the temporary title list is added to the jobTitle variable then every time it loops.

Saving row data:

            inner_list.append(jobTitle)
            inner_list.append(jobCity)
            inner_list.append(jobProv)
            inner_list.append(jobPostalCode)
            inner_list.append(jobURL)

            outer_list.append(inner_list)

            # Check to see if a new grad position is available, then inform the user there is.
            newGradPosFind = jobTitle.find("New Grad")
            newGradPosNum = 1

            if(newGradPosFind != -1):
                print("\n%d - New Grad position found! Check the CSV file for results.\n" % newGradPosNum)
                newGradPosNum = newGradPosNum + 1
        i = i+1

To create row data:

  1. Append every variable into the inner_list in the correct order, otherwise when it gets written out to the CSV file, the data won’t match the headings we set.
  2. Append that inner_list to the outer_list so that a row data is created to be written out.

Checking if new grad positions are avialable:

  1. Simple check method – Do a find for the string “New Grad” in the jobTitle variable. If present, it is printed to the screen.

The nested while loop to obtain position details then loops back around again.

Writing CSV File:

# 7 - Output to a CSV file.
print("Writing output to a CSV file in the directory: " + str(os.getcwd()))
print("\n... ... ...\n")

outCSV_file = open('some_company_jobs.csv', 'w') # Creates a CSV file to write out to.
with outCSV_file:
    writer = csv.writer(outCSV_file) # Creates a CSV Writer that will dump data into the outCSV_file data stream.
    writer.writerows(outer_list) # Writes out the outer_list data to the CSV file.

print("Writing complete!")
print("Please check the CSV file for your results.")

  1. Open a new data stream/file to write to.
  2. Create a writer stream using csv.writer and target the newly created file stream.
  3. Write out the data from the outer_list which contains the row data.

There we have it. It is a lengthy program, not too lengthy though. There probably are better ways of doing this. If there was an API available, this would be immensely easier then perhaps as well, it would definitely cut down on the code.

Limitations of the program:

  • It will only work for the targeted site that I programmed it for. Any other site, unless it’s page HTML code is the same, it won’t work.
  • This is not a true job scrapper program. Normally, a job scrapper program is much more dynamic in nature and adaptable to different circumstances, this is simply a HTML parser.


2 Comments

USB Security – C#

Note: This application is currently on version 1.0
Note 2: Result blog posts on actually hacking the application can be found at the end. There will be link(s) leading to each and every one of them.

Changes made to newest version (Log):

N/A – Program is on version 1 (Base program).

Application Information:

  • Name: USB Security (Temporary name for now)
  • Coded in: C#
  • Development Environment: Visual Studio 2010 (temporarily was also done in 2017)
  • For the following platform(s): Windows

Purpose of the Application:

The purpose of this application is to be lightweight and provide security for any sensitive data that users may put on their storage devices. This is ideal for USBs as that was the intended target, but it can be used with both internal and external HDDs and SSDs.

This console application will allow users to encrypt and decrypt data. It makes use of Rijndael encryption scheme. While encryption is done without any requirements from the user, to decrypt data, a password will be required. If the user fails to provide the correct password 3 times, then the data within the encrypted directory is wiped clean. Password is hashed and stored.

At the moment, the following file formats have been successfully tested with it: GIF, JPG, JPEG, PNG, DOC, DOCX, PDF, RTF, TXT, MP3 and MP4.

Program Functionality:

Step 1: When you open the application, you will be met by the following prompt…

1

The user will put in the drive letter of where the ‘data’ folder is stored. That location also stores the various important files needed for the successful operation of the program.

Step 2: After a drive letter is inputted, the program does a check for a password file and data directory…

2

If successful, the user can simply move on to the main menu screen. Otherwise, the program will automatically create the data directory, and ask the user to create a password they can remember.

Step 3: User is given main menu options…

3

Encryption – ‘E’:

Below is an image of the sole file within the data directory. Take note of the timestamp on the directory, as well as the sole file within that directory. The contents are also shown for reference and comparison for when it is encrypted.

45

Encryption takes place by calling to various functions within the code, that then do the following:

  • Open the file to encrypt.
  • Put it into a buffer stream.
  • Open an encryption stream using Rijndael encryption scheme.
  • What happens under the hood with the encryption scheme (useful link provided in the resources section):
    • Does a sub-byte operation: Takes the contents of the file in bits and through a 16 by 16 matrix table, that contains various hex values, it replaces the original hex values with the new ones.
    • Shifts rows: Think of the hex data of the file in a matrix. So it shifts the hex values over in the various rows. First row maybe left unaffected, second one will see a shift by 1, the one after that will see as shift by 2 and it will only increment.
    • Mix Columns: This step in the encryption works by applying a modulo operation to each individual column in the data matrix. There is a randomized matrix that is used for the operation against the various columns of the data matrix.
    • Add a round key: The algorithm takes an equally large matrix of round key values that are then added to the data matrix and produce new values in the place of the old ones.
    • Note: There are a total of 10 rounds that happen behind the scenes of this process. But on the tenth round, the mix column procedure does not take place.

6

The data is now encrypted and has been put into a new directory named “encryptDataDir” to let the user know to not delete the content in there. Because if they did, then all data will be lost!

Please take note of the timestamps and the now encrypted content of the text file.

78

Decryption – ‘D’:

When the user wants to decrypt, they are given 3 tries to input the correct password. After those 3 tries are up, the encrypted directory is deleted and any data associated in there is wiped.

9

Should they input the correct password, here is the screen they will see next where the actual decryption takes place…

10

Take note of the timestamps and the file content. While the time stamp has changed as it is a file operation we are executing, the contents of the file are back as they once were. Management of the timestamps happens at a system level versus user level. Meaning the normal user has no control over it, and Windows as a OS tends to keep users out of such control.

1112

Help Screen:

13

Program Information Screen:

14

Exit – ‘X’:

To exit, the user will simply type ‘x’. At the moment, the application does not automatically encrypt the data directory before quitting as I have defined it in the project scope, but that is an easy fix. That is something I plan to leave for in the future when I make more improvements to the program. Right now, it simply gives a message and then lets the user exit by pressing the enter key.

15

Conclusion:

This was a good little project that spurned from a practical need. What caused this idea to come about was when I thought I had once lost my USB. It made me wonder, what if I had sensitive data on there and someone else got a hold of it?

It made me also realize just how in-depth the world of encryption is. Of course I don’t know its true depth as encryption has been around for centuries. But one thing I can say with certainty is that if you have the option to use these pre-designed encryption algorithms, use them. Don’t try to fix what ain’t broke. I have in my research online during this project seen some messy  and very confusing code in which people try to create or modify existing encryption algorithms from scratch. It’s not an easy task, nor is it a viable task from a business perspective if you work on a time limit.

One thing to keep in mind, from Windows 7 and up, Microsoft has included an encryption method for its users (BUT only on Professional/Enterprise versions of Windows). Linux has ways to encrypt its home directory as well. I’m confident of Ubuntu, however I can’t vouch for other flavors out there.

Overall, there is room for improvement and there are some things I would definitely like to change (or add on) as outlined in the next section. This was a good fun project.

Also for anyone wondering if I ever found that USB, yes. Now you will get a laugh out of this. I searched everywhere except for that one well hidden pocket in my bag which just so happened to have the USB…there were both feelings of relief and silliness :).

Future Changes planned for future versions:

  • Implement Salt Hashing as opposed to the simple Hashing it is using right now.
    • Salt Hashing makes it more difficult to crack a hash as it makes every hash unique.
  • Implement ways for the program to sweep through multiple levels of folders/directories as opposed to 1 level it has right now.
  • Implement a logging system to keep track of various activities:
    • When a password file is created (Date & Time).
    • When the data was encrypted (Date & Time).
    • When the data was decrypted (Date & Time).
  •  Implement a security ques/ans file:
    • Contains a security question and answer. User will get a pre-selected choice of options for questions, they must type the answer in.

Resources:

Additional Material:

I thought to add this in as I was updating the future improvements list. Below is the flowchart you will find for the program as I was planning this out while working on the algorithm.

programFlow_v1

Hacking it