Wednesday, March 29, 2017

How to use secrets


From time to time you heard about how someone's site has been compromised and customer's personal information has been leaked. For example, Target Got Hacked Hard.

What can you do? Good passwords is a start.

First is understanding how do we choose a password.

If the password can be 10 characters with uppercase, lowercase, digits and symbols it could be (26 + 26 + 10 + 32) to the power of 10 or 5.386151140948997e19 different possible passwords. Even if you could attempt thousands of password attempts a second, it would take you eons to be able to crack this. Most systems will also throttle how many attempts to you can make per minute.

A good hacker won't attempt all possible combinations. They would use a dictionary to restrict the attempts to known password combinations. They might be able to reduce the number of different possible passwords to something they could attempt within a year. So systems will often request you change your password every 90 days.

Additionally, if the system allows for more characters (password length of 20 or 30 characters) just adding a few characters will make it exponentially harder to crack.

So don't use known patterns (dictionary attack), make your password as long as possible, change it every few months. The change should also be significant.

Now maybe you have to type the password into a mobile device and a really long, complicated password is going to be a bother. So you end up shortening it. Also, if you password is something like "CBVcP3Zj/i}3mK,xUL7U", you are never going to remember that. You will be tempted to make it shorter, easy to remember and you won't want to change it too often. So something like "!Passw0rd!" seems like a good password. It has uppercase, lowercase, digit, symbols, it is easy to remember, it is 10 characters long. However, it is easy to guess. A hacker will DEFINITELY have this in their dictionary.

What about changing the password? If your password was "My!S3cr3t!Passw0rd!" and I changed it to "My!S3cr3t!Passw0rd!01", next I used "My!S3cr3t!Passw0rd!02", someone will guess this with a dictionary attack.

Additionally, it used to be that a 6 character password wasn't crackable by brute force. As computers got faster we needed 8 character passwords. Today it seems that companies are recommending 12 character passwords. So if you want to be safe, you should use at least 20 character passwords.

So REALLY the password of "CBVcP3Zj/i}3mK,xUL7U" is what we want to use. That said, I've known security staff walk around the office looking for post-it notes. People will write their password on a post-it note and stick the note to a monitor. A lot of time, systems are hacked because of an insider getting a password which was written down. When I first got into computers, a high school teacher wrote the password to the system on a sheet in his desk. I know this because students would see him looking in his desk then logging in the system. One of the students stole the password from his desk.

What about saving it on a file in the computer. That works even better for some things. I need to log into a website. I open my text file, copy the password, paste it into the website. What happens if someone gets a copy of my text file. Then they have all my passwords.

I can put them in a spreadsheet with a password or a zip file with a password. Is the password to the spreadsheet going to be "CBVcP3Zj/i}3mK,xUL7U"? And I don't write it down? Probably not.

This brings us to dynamic and static storage. If my password is in a variable or the clipboard, I can turn off my computer and it is gone. If it is stored in a text file, someone can make a copy of the file and take days trying to crack it. Hackers will sometimes get encrypted database files then spend weeks trying to crack it. This is where they get common passwords for their dictionary attacks.

What if your files are automatically backed up to iCloud or Google? Then someone might be able to intercept them and take weeks trying to crack them.

Also, how do you think I came up with "CBVcP3Zj/i}3mK,xUL7U"? The answer is a password vault program. There are a few. I use 1Password (because it works on all the devices I use). There are free options like LastPass, KeePass, Dashlane. Have a look at List of password managers for these and other options. Now you just have to pick one good, strong password to secure your vault.

Additionally, if you don't backup your vault to a cloud or let people have access to it, they cannot hack it.

Another bad practice I see people doing is saving passwords in variables. This is less for your personal passwords and more for programmers accessing enterprise sites. I might have a utility which accesses the XYZ system. If variables are set, it never asks me for a password. I might have:

export XYZ_USERNAME='abssass'
export XYZ_USERNAME='2eD$g^^nJk5wHki6Lsst4Gwr'
Now if I run the utility it will see these variable are set and use them to log in. Or I might  have something like: "http://$XYZ_USERNAME:$XYZ_PASSWORD@hostname" and so long as the variables are set, it will automatically log me into the website.

But now we are back to saving passwords in a text file. Things like export statements are saved in ~/.bash_profile on my computer.

For the team they might save the passwords in a team password manager. For example, vault by Hashicorp. To get my secrets I might execute something like:

vault read /secrets/team/storage/xyz
This might return something like:

KeyValue
xyz_usernameabssass
xyz_password2eD$g^^nJk5wHki6Lsst4Gwr

So now I can use my UNIX/Linux skills to parse the username and password out and save them in a variable. For example:

export XYZ_PASSWORD=$(vault read /secrets/team/storage/xyz | grep xyz_password | awk '{print $2}')export XYZ_USERNAME=$(vault read /secrets/team/storage/xyz | grep xyz_username | awk '{print $2}')
This will read the information from the vault, parse out the appropriate information and save it to a variable. When I turn off my computer the variables are gone and the password isn't saved in a text file... not even encrypted.

Tuesday, March 21, 2017

Using Charles from the command line

If you are testing network traffic you are probably familiar with Fiddler. Fiddler is a nice, easy to use tool for monitoring network traffic.

It works very easy. You start up Fiddler and it configures your Internet Settings. Now when you start up a web browser, it automatically routes traffic through Fiddler. As you hit web pages on the browser, the HTTP requests and response show up in Fiddler. It is very easy to read and understand what is going on.

If you are using a macOS computer you will be sad to learn that Fiddler does not exist for macOS. It is a Windows only product. If you check for free options to do the same thing you find Wireshark (formerly Ethereal). But Wireshark's configuration and output assumes you have knowledge of TCP, HTTP, Sockets, packets, etc. You can get the information that you need but it is not as easy as Fiddler.

Additionally, to play back a request with some modifications is a lot harder with Wireshark than with Fiddler.

So what do you do? Charles Proxy. Unfortunately, it is not free but at $50 it is a good investment. If you are working at a company with many people needing it, there are discounts available as well.

Now if you get Charles you will find it automatically starts up and changes the Network Settings on your macOS. So all the browsers and anything which uses Network Settings, will automatically go through Charles. 

What about command line? For example, I have a Docker script which creates a container, deploys a web service and waits for someone to hit it. What if I'm creating automation using Python, Java, bash script, etc.? These do not use the macOS Network Settings. So you will see nothing in Charles.

The solution is to add the necessary information to the shell before you launch your test scripts.

The way Charles works is rather simple. If my machine is using 192.168.0.4 and I want to hit www.google.com (209.52.144.114) it might following the following route:
  • 192.168.0.4
  • 64.114.101.7
  • 209.121.102.146
  • 209.52.144.114
The way Charles works is creating a MITM (Man-In-The-Middle). So if I want Charles to be able to observe the traffic the route might be:
  • 192.168.0.4
  • CharlesProxy
  • 64.114.101.7
  • 209.121.102.146
  • 209.52.144.114
The way it does this is by creating proxy settings in Network Settings. To create proxy settings on the command line you need to set certain variables. For HTTP traffic and HTTPS traffic Charles tells macOS to set it to use IP address 127.0.0.1 and port 8888.

For the command line you want to use:
export http_proxy="http://127.0.0.1:8888"
export https_proxy="http://127.0.0.1:8888"
Additionally, Charles tells the macOS to bypass certain addresses. What I do is go to System Preferences, select Network, select the Advanced... button, to to the Proxies tab.

On this page, assuming you are running Charles, you will see a bunch of addresses in the Bypass proxy settings box. Select all of them, copy them into the clipboard, go back to the command line and enter:
export no_proxy="<paste>"
With these three settings, anything you run from the command line will go through Charles.

However, if you close the shell you lose all the settings. If you want to keep the settings you can add them to your ~/.bash_profile text file. Every time you open a shell it will add the proxy information to the shell. HOWEVER, you don't want this if you are not using Charles. To disable this you need to enter:
unset http_proxy
unset https_proxy
unset no_proxy
So what I do is add the following to my ~/.bash_profile text file:
# Charles shortcuts
function charles_on {
        export http_proxy="http://127.0.0.1:8888"
        export https_proxy="http://127.0.0.1:8888"
        export no_proxy="127.0.0.1:6258, 127.0.0.1:6263, 127.0.0.1:10191, 127.0.0.1:14821, 127.0.0.1:24861, 127.0.0.1:25007, 127.0.0.1:38151, 127.0.0.1:46360, 127.0.0.1:49801, 127.0.0.1:55730, 127.0.0.1:59483"
}
function charles_off {
        unset http_proxy
        unset https_proxy
        unset no_proxy
}
By adding this to my ~/.bash_profile text file I can use:
charles_on
to enable Charles. And I can use:
charles_off
to disable Charles. Whenever Charles is not running I MUST disable Charles on the command line.