A Foundation for Buffer Overflow Attacks

Buffer overflows are some of the oldest and most important attacks against computer technology. These types of attacks are commonly associated with low level languages (like C and C++), but are not exclusive to them. Despite the importance of understanding this type of attack, there are still a large number of technical people who still don't fully understand it. Hopefully, this article will give you some basic insight into how buffer overflows work and why they are useful/dangerous. This guide will attempt to give you a very basic understanding on the concepts behind these attacks, but please bare in mind: due to a variety of protection mechanisms that are built into modern systems it is actually much more difficult to exploit modern systems using these attacks than it used to be. (If you are reading this to play The Hacker's Sandbox, then everything here is still applicable.)

So what is a buffer overflow?

Buffer overflows are attacks that allow for an unintentional (by design) change in the logical flow of an application. When information needs to be stored in memory, it will either land in the stack, or (for long-term and dynamic data) the heap. (This article will deal specifically with Stack overflows, though similar concepts will apply to the heap as well.) The stack is a region of memory that gets created on every thread that your application is running on. It works using a Last-In, First Out (LIFO) model, where data is said to be either pushed onto or popped off of the stack. When an application wants to store data into a buffer, it will allocate memory on the stack to be filled for that purpose. It can later be manipulated or moved to the heap as needed. The danger comes in when the application tries to write more data to the stack than has been allocated for the buffer. In this instance, an application can overwrite other important locations in memory, causing the program to corrupt or the logical flow of the program to change.

Examining the stack

To understand this a little better, let's take a look at an abstraction of the stack. You can easily visualize the stack using the following parts:


Image that you have three cards that you want to put down in the buffer. Card A, Card B, and Card C. You can push them down one at a time, first Card A, then Card B, last Card C. You will now have a buffer on the stack that looks like this:

  • Card C
  • Card B
  • Card A

If you wanted to then access Card B, first you would have to pop Card C off of the stack in order to access it. This is the basis for memory management on the stack, and is crucial to understand for understanding buffer overflows. We can take this a step further and see how a real-world function would work with the stack.

I am going to use the mmap() system function exposed by the Linux kernel. Looking at the man pages, you can see the function looks like this:

void *mmap(
 void *addr,
 size_t length,
 int prot,
 int flags,
 int fd,
 off_t offset

If we were to call this function, first we would push the return variable, then we would push each argument onto the stack in reverse order, and finally we would make the call to mmap(). (In this case, the function is void, so no return variable will be pushed.) Abstractly, it would look something like this:

PUSH off_t offset
PUSH int fd,
PUSH int flags,
PUSH int prot,
PUSH size_t length,
PUSH void *addr,
CALL mmap

Once finished, our actual stack will look like this:

void *addr,
size_t length,
int prot,
int flags,
int fd,
off_t offset

Don't worry about the actual data here, the important part is that you understand how the stack works to be able to understand how to exploit it. This is all well and good, but how does it actually help you to control the flow of a program? Well, In addition to holding the buffer, the stack also holds a frame pointer, and the address to return to after a function has finished executing. Let's take another look at that stack:


Did you notice it? The buffer is placed on the stack before the return address. If we could keep pushing data onto to buffer until it overflows into the RETURN_ADDRESS, we would change where the program thinks it should be jumping back to.

A little bith of math

Ok, so now we know the theory behind overflowing buffers, but how do we know how much data we need to actually exploit this? The truth is, that depends on a few factors, such as your architecture. Computers of different architectures will follow this same stack model, but their memory allocation won't always be the same. You see, every machine architecture has a minimum amount of storage it needs to allocate. Think of it in terms of blocks. A system can only reserve 1 block at a time. If your program were to request only half a block worth of data, the system would need to reserve a full block to satiate that request.

On a 32 bit system, this block is going to be 32 bits. On a 64 bit system, each block will be 64 bits.

So if we were to request 1 byte of data (8 bits), on a 32 bit system, we would end up reserving 4 bytes (32 bits), while on a 64 bit system, we would end up reserving 8 bytes (64 bits).

In order to actually change the RETURN_ADDRESS, first we would need to fill our complete buffer (all of the space reserved for us), then we would need to overflow the stack pointer (this will usually be 1 block of space), and finally we would be able to overwrite the RETURN_ADDRESS (also 1 block in size.)

To complicate this matter more, modern compilers will often use padding on the buffers which will depend on various factors (such as data type and size) which will effect the reserved memory size. Often, the easiest way to determine how large your buffer is would be to open your application in a debugger and actually look at the asembly. If you are playing The Hacker's Sandbox, assume that there is no padding from the compiler.

Some practical examples

The following is a small C application (overflow.c) which will have no measures in place to protect it from buffer overflows.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
    char buf[10];
    return 0;

void the_shell()

This program is pretty simple. It takes the first argument into the program and places that into a buffer that is 10 bytes long. Notice that there is also a function called the_shell() which never actually gets called. The code exists inside of it, however, to spawn a shell running as the owner of the program. (The truth is, this would be a pretty useless program in real life, but it suits our demonstration very well.)

We could easily try to compile this into a program called overflow. For the purposes of this demonstration, we will be compiling on a 32 bit architecure:

$ gcc -o overflow overflow.c

Note: This compile would be incomplete on a modern machine. Modern compilers, like gcc, would have multiple mechanisms in place, like a stack guard and NX memory regions, which you would need to disable and/or bypass in order to successfully exploit your binaries.

Now, we can try playing around with this for a bit. If we passed an argument of 10 characters (say 0000000000), we will notice the program does nothing, and simply exists. However, if we pass a much longer argument, of say 30 characters, it will crash. The application crashes because key pieces of data become corrupt (like our return address, which likely now points to a non-existant region of memory), and the logical flow of the program can not continue. So how do we send just enough data to overflow the stack and change the flow of execution without crashing the program? Let's try to fill the stack just enough to trick it into returning to our hidden function the_shell(). Conceptually, we will need to fill the stack so it looks like this on our 32 bit system:

[garbage data] 12 bytes [garbage data] 4 bytes [address of the_shell] 4 bytes

Remember, when the buffer requests 10 bytes, the smallest amount of 32 bit blocks (4 bytes) we can use is 3. Thus, 4 bytes X 3 = 12 bytes.

First, we would fire up our binary in a debugger. We'll use gdb for this example; just launch it against our executable to get an interactive debugging shell:

$ gdb overflow

We know from our source example that we want to try to find the location of the_shell() to fire off our attack. We can simply use gdb's disassembly command to dump out that function, and see what address the begining of the function has been mapped to.

(gdb) disas the_shell
Dump of assembler code for function the_shell:
   0x080484a4 <+0>: push %ebp
   0x080484a5 <+1>: mov %esp,%ebp
   0x080484a7 <+3>: sub $0x18,%esp
   0x080484aa <+6>: movl $0x8048560,(%esp)
   0x080484b1 <+13>:    call 0x8048350 <puts@plt>
   0x080484b6 <+18>:    movl $0x8048567,(%esp)
   0x080484bd <+25>:    call 0x8048360 <system@plt>
   0x080484c2 <+30>:    leave  
   0x080484c3 <+31>:    ret    
End of assembler dump.

Here, we can see that the entry point for the_shell is 0x080484a4. We're almost there! Before we can execute our attack, we need to push the address onto the stack in the correct order. Remember, our input is being placed on the stack by strcpy() 1 byte at a time. As a result, our bytes are going to look reversed in a dump from the way we would expect to see it. Therefore, we are going to need to input the bytes (one at a time) in reverse order: 0xa4 0x84 0x04 0x08

Putting this all together

Finally, we're ready to launch the attack. We'll need to send garbage data to overflow the buffer (12 bytes for the buffer + 4 bytes for the SFP), and then our payload. We can easily just use 0's for our garbage data. Unfortunately, 0x08 and 0x04 are not printable characters, so we will need to find some way to inject these bytes into our program. A lot of hackers tend to like using a C, Perl, or Python program to do this. Personally, I just tend to use the echo command inside my Bash shell (but feel free to use whatever suits you best). Using the -e flag for echo, I can allow escaped sequences in my strings, and -n will suppress appending newline characters.

$ ./overflow 0000000000000000$(echo -ne "xa4x84x04x08")

Success! We've been able to alter the flow of execution in our binary to run the hidden shell code.

Again, if if you trying this on a modern system, there are a few more safe guards that need to be taken into consideration before this will work. For example, you would probably need to disable the NX flag from your binaries (you can use execstack on Linux systems to do this.) But if you are playing The Hacker's Sandbox, you won't need to worry about any of that.

For additional information on running buffer overflows against modern systems, I would recommend reading Smashing the Stack in 2011.

Firefox 31+ and sec_error_ca_cert_invalid

Some Background

In early 2014, the Mozilla foundation released a new library for certificate verification called mozilla::pkix. This library was built to be more robust and maintainable than its predecessors, using techniques such as building multiple trust chains to be used in the verification process. With this new library came some changes to the enforcement of some requirements in Mozilla's CA Certificate Policy. Where the most of users may not necessarily notice any differences, some subset of users have definitely been affected. Most specifically, using self-signed certificates can lead to failed verification of the certificate chain. In such instances, the entire connection itself will be refused, and you will be prompted with the following error:

An error occurred during a connection to example.com.

Issuer certificate is invalid.

(Error code: sec_error_ca_cert_invalid)

It is still currently possible to get around this, however, by disabling support for the new mozilla::pkix library. Be aware, however, that doing so may leave you at slightly higher risk to malicious connections being uncaught by verification. Use this method at your own risk.

Disabling mozilla::pix

  • In your Firefox browser, type about:config into the address bar, and hit enter.
  • Search for security.use_mozillapkix_verification and set it to true (you can double click on it to do so)

Now you should be able to reload the page you were trying to connect to and receive your familiar prompt about the unsafe connection. Simply accept the exception to continue on your way.

Dynamic Linker Voodoo: aka How to LD_PRELOAD

The dynamic linker is one of the most important yet widely overlooked components of a modern Operating System. Its job is to load and link-in executable code from shared libraries into executables at run time. There are many intricate details on how the dynamic linker does what it does, but one of the more interesting is the use of the LD_LIBRARY_PATH and LD_PRELOAD environment variables. When defined, these variables will let you override the default behaviour of the dynamic linker to load specific code into your executables. For example, using LD_PRELOAD, you can override the C standard library functions in libc with your own versions (think printf, puts, getc, etc.)

Let's see this in action! We'll start by making a simple program to test the (now deprecated) gets() function. Here, we will create a file called test.c and put the follow contents inside it:

#include <stdio.h>

int main (void)
  char str[128];
  printf ("Testing gets()...\n");
  return 0;

Note that this code is not safe and should not be used for production, but it makes a simple test scenario.

Next, we can compile the source with gcc. (Since gets() is deprecated, we're going to throw in the -w flag to suppress warning messages. We don't really care for this example.)

$ gcc -w -o test test.c

Finally, we can run the program and examine it's output:

$ ./test 
Testing gets()...

Success! When the executable is run, it links the gets() code from libc into memory and executes that code when we call gets(). Now let's see how we can override libc's implementation with our own. First, we'll write a new version of gets() that we want run. Make a file called mygets.c and enter the following:

char *gets( char *str )
  printf("Error: Stop using deprecated functions!\n");
  return "";

Once finished, we can compile this into our own shared object library:

gcc -w -fPIC -shared -o mygets.so mygets.c

Finally, let's run the test executable again, but this time we will call it with LD_PRELOAD to load our custom shared library before dynamically linking libc:

$ LD_PRELOAD=./mygets.so ./test 
Testing gets()...
Error: Stop using deprecated functions!

As you can see, now our custom code is displaying where we were once being prompted for input. Of course, we could write any code we want to go in here. The only limit is whatever we can think up. This technique could be extremely useful when trying advanced debugging or when trying to replace specific parts of a shared library in your program. You can even take this a step further to create hooks for the original overridden functions.

To illustrate this, let's modify our shared library one more time:

#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>

char *gets( char *str )
  printf("Error: Stop using deprecated functions!\n");
  char *(*original_gets)( char *str );
  original_gets = dlsym(RTLD_NEXT, "gets");
  return (*original_gets)(str);

We've done a few things here. We have now referenced the stdio header and we use dlsym to find the original gets() function. Notice that we use the RTLD_NEXT pseudo-handle with dlsym. In order to use this handle, we must include the _GNU_SOURCE test macro (otherwise RTLD_NEXT will not be found). This finds the next occurrence of gets() after the current library and allows us to map it to original_gets(). We can then use it in this function with the mapped name.

We can compile our library again to test out the new code (this time linking the dl lib):

$ gcc -w -fPIC -shared -o mygets.so mygets.c -ldl

Using this method, we can run our test executable again:

$ LD_PRELOAD=./mygets.so ./test 
Testing gets()...
Error: Stop using deprecated functions!

At this point, you should notice the custom code we provided for gets(), followed by the prompt by the original libc function. Hopefully this dispels a little bit of the voodoo and gives you another valuable tool to stash in your belt.

Google C++ Style Guide

I am a really huge fan of nicely formatted and presented documentation. Sometimes I can get a little too OCD about this. If you haven't reviewed any of Google's coding style guides you should, they have a lot of nice information in there, and their views are worth considering. Lately I've decided to try and conform to their C++ guide a bit, but perusing through their doc was just ugly for offline viewing. It may not matter to most people, but I made a slightly cleaner version of the 3.274 revision of the guide in PDF format.

Download Google's C++ Style Guide in PDF here

Creating RSA public keys from private keys

Generating a public RSA key is a pretty simple task. More often than not, keys will be generated in pairs. But sometimes you will be given an RSA private key and you will need to create your own public key from it. (For example, when using Amazon EC2). Fortunately, you only need to remember a quick one-liner to do so:

$ ssh-keygen -y -f mykey.pem > mykey.pub

The -y flag tells ssh-keygen to create a public key based off of the private key passed to the -f flag. It's really that simple. by default, this will simple print to stdout, so redirecting output to a file (as in the example here) is your quickest way to saving your new key.

Node.js v0.10 Documentation

Anyone who has worked with Node.js and its documentation will know that the docs are pretty much only hosted on the nodejs.org website these days. Unfortunately, that leaves offline browsing of the docs in a particularly poor state. Since I have had the need to refer to these docs often enough without having an Internet connection, I imagine there are of ton of other people who are having the same issue.

In response, I have created a PDF file of the online docs that you can use for offline use. Download the PDF and happy coding!

Configuring a Cisco router as a terminal server

A Cisco terminal server is a router with multiple, low speed, asynchronous ports that are connected to other serial devices. These are often used to provide out-of-band management to those devices. Using this, you can establish a single point of access to the console ports of multiple devices in your infrastructure, and gain administrative access in scenarios of failed network connectivity.

Cisco usually provides a few types of breakout cables (also referred to as octocables) to connect to your router's async ports. The CAB-OCTAL-ASYNC is a 8-port variant popularly used on the 2500 series routers, and will be explained here. (Make sure to read the documentation for your device and find out which cables are appropriate to use for your setup.)

Let's assume you have a 2500 series router you would like to configure into a terminal server, and you have two 2600 series catalyst switches you will be managing. We should be able to quickly get this setup in a matter of minutes for remote access.


Connect your breakout cable to the 2500 router and connect the RJ-45 connectors labeled P0 and P1 to the console ports of your 2600 switches. As long as all of your devices are powered on (and booted up; remember cisco gear can take 5 min or so to fully boot up) you should be ready to continue! (it's that easy.)

Setting your Loopback

You will need to have a loopback device defined in your router to properly administrate your devices on. In IOS, it should be as simple as the following:

Router(config)#interface loop0
Router(config-if)#ip address

Here, we are defining the device "loop0" and assigning the address of to the device. This will be used to connect to your async lines when managing the switches.

Finding your management ports

Cisco gear is a little bit magical here, as they will automatically enumerate ports for your async lines on the loopback device. These ports will be assigned the values of 2000 + P, where P is the label of the breakout cable port number you have plugged in.

For example, we have plugged in P0 and P1 into our test switches, so the enumerated ports will be 2000 and 2001 respectively.

Configure transport access

Telnet is usually defined by default, but it's a good idea (and sometimes necessary) to explicitly define your settings. In order to allow your router to speak out to the switches over the async lines, you must set the transport settings to allow telnet. We can use the following command to do this:

Router(config)#line 0/0/0 0/0/7
Router(config-line)#transport output telnet

This will set the transport output settings on all 8 of your available async lines. Please not that, depending on the hardware you may be using, these lines may be enumerated differently. You can use the show lines command to see your actual available line information and configure accordingly.


Now, you can easily connect from your router to either of the switches using telnet.

Router#telnet 2000

As usual, Ctrl+Shift+6 then x will bring you back to your terminal server.

If you want to make a quick alias to make connecting easier, you can do so using the ip host commands.

ip host switch1 2000
ip host switch2 2001

You can now just type switch1 to log into your switch.

From here, you can get fancy and setup aux connections to the router, say if you needed dial-up access to your gear in case of an ISP outage or something similar. But at the very least, this should be enough to get you up and going.

Exploiting masks in Hashcat for fun and profit

Hopefully you have a basic familiarity with using Hashcat. This guide will assume that you know what Hashcat is, how to load up basic dictionaries and start a job from the command line. If Any of that sounds foreign to you, I recommend you read the precursor A guide to password cracking with Hashcat before continuing.

Terms to be aware of

  • cracking chain The entire set of tools (both hardware and software) used to crack hashes
  • hash A fixed-length output of data that represents a plaintext value after it has been placed through a hash function
  • mask A specific set of rules used to tell your cracking utility which parts of a key space should be used
  • plaintext The input for a hash function. For example, a password.

The power of masks

Dictionaries can be a great tool in your password cracking arsenal, but they can hit some very real limits quickly. For example, in order to use a dictionary, you have to store it, which means you need to store all of the data for all of the different combinations you want to try. Depending on the key space and combinations you are working against, this can add up very quickly. It's also worth noting that there is a very measurable amount of time it takes to load dictionaries into memory, and I/O can become a bottleneck in your cracking chain. This is where using masks come in!

Back in the early days of password cracking, if you didn't use a dictionary, you could pretty much only use a straight brute-force attack. Fortunately, our techniques and tools have come quite a long way since then, and honestly brute-force cracking is all but obsolete these days. By using a mask, you can specify what combinations of characters to run through during your attack. The great thing here is flexibility: If you just wanted to run a straight brute-force, you would wait for your tools to run through every combination in every position until it (eventually) finds the right combination. Obviously that can take an extraordinary amount of time to complete. But what if we knew something about the plaintext itself. Let's say we now that the password is only made with lowercase letters, and ends with two numbers. Even further, let's assume that we know the password is exactly 6 characters long. At this point, it would seem like a waste to go through standard brute-force. that would require running through all combinations from one letter up, and using uppercase and special characters that we know will never match. The biggest problem here is running through bad combinations simply wastes time, and no one wants that.

Hashcat is a very flexible tool. It offers a range of different attack modes to help you out with your various cracking needs. You should reference the help information often, but let's take a quick look at it now to see the list of these modes. Using oclHashcat v1.21, you will see this information:

$ hc --help | grep -A 7 "Attack modes"
* Attack modes:

    0 = Straight
    1 = Combination
    3 = Brute-force
    6 = Hybrid dict + mask
    7 = Hybrid mask + dict

Now, technically we don't see an option for "masks" here, but I will let you in on a tiny secret. Even though Hashcat called mode 3 "Brute-force", it isn't actually your traditional brute-force. This is your mask mode ( in fact, you have to go out of your way to even make hashcat perform a traditional brute-force ). Using a mask, we can simply use the following to skip all of the extra combinations we know will fail:

$ hc -a3 hash.file ?l?l?l?l?d?d

It's a lot easier than it looks, and it's ridiculously powerful. This attack mode is a definite game-changer.

Defining your masks

When using masks, you need to define a minimum of 4 options for hashcat:
hashcat-binary attack-mode hash-file mask

It is crucial that you define each part. That being said, you are free to add in additional options, as long as those 4 exist.

  • hashcat-binary This should be obvious. It's the path to the hashcat binary itself ( in our examples: hc )
  • attack-mode For mask attacks, this will always be -a3
  • hash-file Similar to a dictionary attack, this will be the location of the file with all of your hashes
  • mask The mask can either be the actual mask you want to use, or the location of a file with multiple masks inside of it. Either one is fine, but you must supply one of them ( and only one )

To create your mask, you will simply specify which character set you want to use in which position. By default, Hashcat comes with 5 pre-defined character sets, and allows you to make up to 4 custom character sets. The built-in sets are as follows:

   ?l = abcdefghijklmnopqrstuvwxyz
   ?d = 0123456789
   ?s =  !"#$%&'()*+,-./:;<=>?@[]^_`{|}~
   ?a = ?l?u?d?s

So let's say we wanted to act more like a traditional brute-force and go through all character combinations exactly 3 characters long. To do this, we will use the full "all characters" set, defined as ?a.

$ hc -a3 hash.file ?a?a?a

Easy, isn't is?

Now, what if we wanted to try the first letter uppercase, the next four lowercase, and the last two digits?

$ hc -a3 hash.file ?u?l?l?l?l?d?d

As I mentioned, it's very flexible and powerful.

Custom character sets

Using masks this way covers a lot of ground, but it can still stand to be a little more specific. Sometimes you may only need to search a very specific subset of characters. For example, what if you had a hash where you knew the plaintext was going to be a six character hex value. Obviously, using ?d isn't going to be enough, and using ?a will run through too many combinations that we know will be absolutely wrong. This becomes a good candidate for a custom character set.

Hashcat allows you to define a custom character set in one of four buffers:


When you define a character set, you can then call a new flag with the number of that set to use the character set in your mask. Using the example above, we would first need to define our hex character set to be used with hashcat, and we will place it in buffer 1.

-1  0123456789abcdefABCDEF

If you don't know whether the plaintext will be in uppercase or lowercase hex, this character set should cover both. The only drawback here is that it's a little cumbersome to type. Fortunately, you can shorten this down using built-ins. The following character set is exactly the same:

-1  ?dabcdefABCDEF

I tend to think that typing less is better, but feel free to use whichever method suits you best. At this point, you are ready to use character set 1 in your masks. Continuing our previous example, we can use this mask to run through your six character hex key space:


Now let's put this all together and see how it looks on the command line:

$ hc -a3 hash.file -1 ?dabcdefABCDEF ?1?1?1?1?1?1

It's not quite as daunting as it first seemed, is it? You can, of course, refine this even further and mix in additional character sets if you need to. Let's say we know that the hex plaintext we are looking for starts with "c6" and the second to last position will only be between 0 and 9. We could create the following mask:

$ hc -a3 hash.file -1 ?dabcdefABCDEF c6?1?1?d?1

Differences in versions

It's worth noting that Hashcat and oclHashcat work slightly different here. Hashcat will run through all increments of your mask by default, for example: ?a?a?a will become:


oclHashcat will not do this unless you explicitly declare incremental mode with the -i flag.

Real world practice

Using Hashcat, let's see a quick example of masks you can try from the pre-packaged examples. If you look at the file examples/A3.M0.word (in your hashcat directory), you will notice that all plaintexts for this exercise are lowercase and 5 characters long. We should easily be able to create a simple mask to crack 100% of these hashes.

$ ./hc -a3 examples/A3.M0.hash ?l?l?l?l?l
Initializing hashcat v0.47 by atom with 8 threads and 32mb segment-size...

Added hashes from file examples/A3.M0.hash: 102 (1 salts)

NOTE: press enter for status-screen

Input.Mode: Mask (?l) [1]
Index.....: 0/1 (segment), 26 (words), 0 (bytes)
Recovered.: 0/102 hashes, 0/1 salts
Speed/sec.: - plains, - words
Progress..: 26/26 (100.00%)
Running...: --:--:--:--
Estimated.: --:--:--:--

Input.Mode: Mask (?l?l) [2]
Index.....: 0/1 (segment), 676 (words), 0 (bytes)
Recovered.: 0/102 hashes, 0/1 salts
Speed/sec.: - plains, - words
Progress..: 676/676 (100.00%)
Running...: --:--:--:--
Estimated.: --:--:--:--

Input.Mode: Mask (?l?l?l) [3]
Index.....: 0/1 (segment), 17576 (words), 0 (bytes)
Recovered.: 0/102 hashes, 0/1 salts
Speed/sec.: - plains, - words
Progress..: 17576/17576 (100.00%)
Running...: --:--:--:--
Estimated.: --:--:--:--

Input.Mode: Mask (?l?l?l?l) [4]
Index.....: 0/1 (segment), 456976 (words), 0 (bytes)
Recovered.: 0/102 hashes, 0/1 salts
Speed/sec.: - plains, - words
Progress..: 456976/456976 (100.00%)
Running...: --:--:--:--
Estimated.: --:--:--:--

    --- Output Omitted ---

All hashes have been recovered

Input.Mode: Mask (?l?l?l?l?l) [5]
Index.....: 0/1 (segment), 11881376 (words), 0 (bytes)
Recovered.: 102/102 hashes, 1/1 salts
Speed/sec.: - plains, 19.94M words
Progress..: 11819600/11881376 (99.48%)
Running...: --:--:--:--
Estimated.: --:--:--:--

Started: Fri Jun 27 12:52:04 2014
Stopped: Fri Jun 27 12:52:05 2014

100% recovery; we must be on a roll! :]

Anonymizing network access with random MAC addresses

I've been reading a few articles recently about the need for people to keep their network access anonymous. A seemingly popular method is to change out the MAC address of your interface every X amount of time. It appears to be a reasonable approach; many institutions rely solely on the MAC address for various types of provisioning and tracking. If you change this reported value, all of these mechanisms tracking your access seem to get confused. By no means do I claim this is the "be-all-and-all" of keeping your access anonymous, but it's nonetheless a good trick to keep in your belt.

In response to a few scripts and utilities I've seen floating around offering to adjust your MAC address for you, I figured I'd just write one that was better than the ones I've seen so far.

The tool

cmac.sh is a simple script that can help hide your system's true MAC address. It runs on OSX and Linux, and probably many other POSIX-compliant OSes. By running this script, it will loop through your available network interfaces, and randomly assign a new valid MAC address to any "inactive" interface. You can also specify anonymous mode, where it will loop through the interface every 30 seconds (configurable) by default.

If you want to get courageous, you can even enabled bump mode, which will down an active interface during each cycle so its MAC address can be adjusted. When using this mode, you may want to set the time parameter to something long, like 5 min or so. Unless you don't mind having your active connections bumped every 30 seconds.

Additionally, you can use the -c flag to change the MAC of specific interfaces rather than all of them. For example: cmac.sh -c "en0 en1"

Remember to check out the help information (--help) before running this script.

This hasn't been heavily tested, so if you run into any bugs (or just have general questions) feel free to contact me about them.

About the randomization

This utility is designed to generate MAC-48 addresses. EUI-64 is not supported at this time. When generating the MAC addresses, I chose to embed the current list of assigned OUIs into the script (using base64) so I can keep this all self-contained. The script randomly selects one of the 19k+ OUIs and then (pseudo)random generates the remaining 3 octets for the address.

Why not randomly generate the OUI entirely? Well, there is a very small set of filtering systems out there that will actually verify your OUI against a list of those formally registered through IEEE. If they don't match, the connection will be dropped. I figured it wasn't very much work to add these in there and cover all use-case scenarios if I could. It does mean that the base64 string may need to be updated in the future to keep this list current, but fortunately they don't change often (and even if they did, 19k random OUIs is probably "good enough" for most people).


cmac.sh utility

Remember to chmod a+x this file before trying to run it!

The Art of Creating Good Passwords

No matter who you are, passwords have become a critical component of one's personal life in the modern era. They are the first line of defense against unauthorized access to your personal information and technology. Your computer, your phone, your bank; they all make use of passwords in an effort to protect you from hackers and malicious software. Unfortunately, it's not simply the existence of a password that matters, because ever evolving hardware and hackers constantly discovering new and more advanced techniques to get retrieve user passwords are changing the playing field. Now, you not only need a password, but you need one that will try to withstand the deluge of attacks that could be brought against it in a compromise.

Microsoft Research released a study in 2007 which suggests that the average web user has an average of 25 accounts to maintain. Yet, the same study suggests only approximately 6 unique passwords are used among the different accounts. Unfortunately, there is quite an excess of security breaches one can choose from to see how dangerous password re-use can be. AOL, Sony, Heartland, Zappos, Ebay, and a ton of others have had compromises in recent years, exposing millions of users' passwords to hackers. But it doesn't simply stop there; each time a breach is recognized and this password data is leaked, the same data is tried against other web sites across the web in an attempt for the attackers to steal more of your personal information and assets.

What they can do

The first crucial part of password security is out of the hands of the regular web user. The sites you visit and use must implement proper techniques and algorithms to keep you safe. Too many times now, sites have been caught using old and insufficiently secure methods to store user information. There isn't much the average user can do here, especially considering you often have no way of knowing what goes on behind the scenes. This makes a good case for keeping different unique passwords at each site you use. The industry best practice is to transform your password into a password hash. In it's hashed form, there should be no way for a hash to be mathematically "reversed" into its plaintext form. For your attacker to compromise your password, they will now have to try repeated "guesses" against your hash using the same algorithm, and hope they can get a match. Don't be fooled, however, this is much easier than it sounds.

What you can do

First you need to realize that whatever you do, it's only good until the bad guys catch on. These techniques may work for a while, but they won't last forever. That being said, they should be decent enough to use a a basis for any foreseeable future.

Do not use dictionary words

For a long time, people have used a combination of words from the dictionary and maybe some numbers thrown in to compose their passwords. Maybe something you like and your lucky number (Dragon13), or a person's name and a year (michelle1980), or if the rules are a bit stricter, capitalization may be required (SomePassword123). The problem with this is that the patterns are far too predictable. Anyone can grab a few dictionaries and run some rules against them to come up with these combinations. Don't think that simply making them leetspeak or toggle-cased will fix this either. dR4g0n13 is just as easily cracked using the default rules that come with the Hashcat password cracking software.

Dictionary chaining

A popular web comic one cited "correct horse battery staple" as being an excellent password. The problem here is that hackers are now chaining multiple dictionary words together more frequently, and in a way it actually makes passwords weaker. If we think about it for a moment, when you are only trying dictionary words, each word takes the role of a character position. If you only use 4 words in your password, it's akin to using a 4 character password for those attacks.

Do not use personal information

Personal information should be avoided at all costs. It reveals too much about you to an attacker, and could potentially be too easy to obtain as well. This makes for a very dangerous combination. How easy would it be for someone to look up your facebook page and get personal information about you? Your interests. Your family. your friends. Places you like to go. Shows you like to watch. The internet is a tremendous archive of easily accessible personal information. So don't use it.

Recommendation in the wild

Microsoft makes the case for the following categories to create a strong password:

  • Is at least eight characters long.
  • Does not contain your user name, real name, or company name.
  • Does not contain a complete word.
  • Is significantly different from previous passwords.
  • Contains characters from each of the following four categories:
    • Uppercase letters
    • Lowercase letters
    • Numbers
    • Symbols

These are pretty good suggestions, but these categories on their own don't cut it. Using their example, Hello2U! is a prime example of a poor password. It comes right out of the dictionary, capitalization is at the front, and a symbol/number combination (in this case the exclamation point) is on the end. Now, there are two things two realize here. First, Microsoft makes the point that you should use spaces in your passwords. I am completely for this. The more spaces, the better. It happens to be an EXTREMELY underused character in passwords. However, their recommendation is not so great: H3ll0 2 U!. Unfortunately, this is no better than the first example. The default install of hashcat can add spaces between words and perform "leetspeak" transformations on your text, which still leaves this vulnerable.

Your passwords should definitely be long, and I do like that Microsoft recommends a minimum length, but I personally believe 8 characters to be too small. That can be a little difficult for some users, but the longer the password, the better. I tend to use no less than 20 characters for my own, but if you are using at least 10 or 12, you will be better off (assuming the passwords are being stored decently).

Entropy is your friend

By its definition, entropy is a lack of order or predictability. The greater entropy you have in a password, the harder it is to crack it. In mathematical terms, the entropy of a password is given by H=Llog2N where L is the length of the password and N is the size of the alphabet. Most people won't actually have to know what this means, but you should remember this: Use as many different unique symbols as possible in your password.

If you have a 15 character password, use 15 different characters. Again, this is a hard one for a lot of people, but it really does help. Just remember, a is not the same as A, so it's really not as bad as you might think.

Keyboard walks

Another common practice these days is to use what are called keyboard walk. This is just outright wrong! There are entire dictionaries and rulesets tailored towards these types of passwords. Just don't use them. * qwerasdf * qewradsf * zaqcdexsw123

There are tons of them I could list here, but hopefully you get the point. Keyboard walks = evil = easy = you don't want to use them.

So what makes a good password?

The idea here is to hold out as long as absolutely possible against your attacker's techniques. Nothing is 100% "hack-proof", but we can make them work pretty hard for it (and hope that many will simply give up rather than spend the effort). But keeping in mind the following should help: * It should be long (the longer the better) * It should never contain personal information * It should contain as much entropy as possible * Don't be afraid to use spaces * Avoid dictionary combinations * If you are going to use dictionary words, misspell them! * Do not use "keyboard walks"

The right thing to do is to use a password manager. LastPass, 1Password, RoboForm... there is no shortage of them available. Just google password manager and you will get a ton of information.

In lieu of this, you will need to make your own passwords using these rules, like so:
I c4N zwim f@sTer tHan S0CRAt35 bK+g
36 characters
30 different characters (not awful, I wonder if I could make that better)

It's fairly easy to remember, and although I did use some dictionary words I used a misspelling and some random garbage in there as well.

My recommendation

Use a password manager. Many are free, they are simple to use, and when a breach occurs at your favorite site, you can simply tell it to generate you a new good password. It's really easy.