Tim Mattison

Hardcore tech

Use Git to Figure Out What You Did Yesterday

| Comments

Are you a developer? Do you have trouble remembering what you did yesterday when it is time for your daily standup? Do you use git? Do you commit regularly? If you answered yes to those questions you can now quickly figure out what you did yesterday with the help of gitrdun.

gitrdun simply looks for git repos in your home directory, lists all of the commits in those repos from yesterday, and then prints that on the screen. The current iteration is the “5 minute version”. It literally took 5 minutes to write. The “5 hour version” may make the formatting a bit nicer and add some features but don’t hold your breath for that to come out.

Don’t want to fork the repo? No problem, it’s just a one liner anyway. Use this alias…

1
alias gitrdun="clear ; PAGER=\"cat\" find ~ -name \".git\" -type d -exec sh -c \"cd '{}' ; echo '{}'; git log --all --since='yesterday'\" \; | less"

This clears the screen, uses “cat” as the pager so that the pager doesn’t clear the screen between repo checks, finds all git repos, goes into their directory that is under version control, and then lists all commits on all branches from yesterday.

Enjoy!

Octal and Hexadecimal IP Addresses With Ping

| Comments

Have you ever seen a system print out an IP address like this?

1
Disconnected from 010.000.001.133

If you try to ping this IP address you’ll get quite interesting results. What the IP address should be is 10.0.1.133 but what ping reports that it is if you run the command with those leading zeroes included looks very odd.

1
2
3
timmattison$ ping 010.000.001.133
PING 010.000.001.133 (8.0.1.133): 56 data bytes
Request timeout for icmp_seq 0

See that 8.0.1.133 IP address that it is trying to reach? It turns out that if you put leading zeroes into an IP address that you pass to ping, and possibly other network tools, it treats those numbers as octal. Octal isn’t something most end-users deal with unless they’re reminiscing about their old Compuserve addresses.

In any case, if you find yourself trying to ping a machine with an IP address that has leading zeroes make sure you remove them!

This got me wondering what other weird things ping might do with IP addresses so I played around a bit and saw that it actually allows you to enter them in hex as well. This is useful for IPv6 but really strange for IPv4. Try it out and try to ping the above address with the first octet in hex:

1
2
timmattison$ ping 0xa.0.1.133
PING 0xa.0.1.133 (10.0.1.133): 56 data bytes

Sure enough it converts 0xa into 10. I’m not sure I’ll ever use that feature but its good to know what ping does to its input in the even that some other weird situation pops up.

My Problem With ‘the Problem With Altcoins’

| Comments

TL;DR – The author’s strongest argument is that some altcoins are junk. This unfortunately then morphs into saying that all altcoins are junk and none of them can ever be good. In my opinion that is going too far.

On the Google Plus Bitcoin community someone posted a link to The Problem with Altcoins. I think this article is complete link bait based on the fact that the first paragraph is titled “Why no altcoin can succeed” but nevertheless I’d like to address a few of the things in it because they could be confusing to people new to the cryptocurrency space.

I’ll preface this post by saying that I hold a few Bitcoins, some Litecoins, and some Feathercoins. I bought most of them to play around with and not as a serious investment so I’m not here to tell you that any of these things are a solid investment. If you are like me you want to get into cryptocurrencies because they’re interesting and understanding them gives me new ways to approach problems that I see in software development.

Issue #1:

Quite simply, a medium of exchange that is more widely accepted on the market is more useful than one which is not. This is known as the network effect. Thus, an initial imbalance between two nearly equal media of exchange will benefit whichever is more widely accepted until a single one overwhelms the rest.

This paragraph does quite a good job of shooting itself down unknowingly. I agree with the statement “a medium of exchange that is more widely accepted on the market is more useful than one that is not”. The leap that it then goes to make isn’t very well thought out. Just because something is better does not mean that eventually it will be the only thing. If that was the case then why are there so many different brands of any product you can think of?

The end of this paragraph is its complete downfall. It states “until a single one overwhelms the rest”. There is no example of this happening as far as I know. Is there only one currency in the world? You might think the world currency is the US Dollar but I can assure you it isn’t. Admittedly it does say it will “overwhelm” the rest and not “extinguish” the rest but I believe overwhelm here was meant to imply that the others would disappear.

My stance: There is room for more than one physical currency. There is room for more than one digital currency.

Issue #2:

Furthermore, a truly great innovation would much better serve people by being incorporated into future versions of Bitcoin rather than by requiring them to switch to something else

This makes the assumption that just because a feature benefits someone that it will be incorporated. Since the interests of each individual are different you could have features that benefit some (shorter confirmation times, lower transaction fees, anonymity, etc) that do not benefit others. In fact, one of these features mentioned later is Zerocoin which provides anonymous transactions. Some would argue that if this was incorporated into Bitcoin that it would set it back a few years as the media picked it up again as the anonymous currency used by drug dealers and terrorists.

Other kinds of transactions like creating “dust” to sign arbitrary bits of data to use the block chain as a kind of digital notary are probably best implemented in a different system altogether.

My stance: Not all features should be incorporated into Bitcoin. Blockchain bloat is already a bit of a problem and I think we need to minimize it.

Issue #3:

Can anyone really expect to create something of value by rereleasing Bitcoin under a new name and with a few tiny changes to its source code?

Actually, I’m in total agreement here. There are altcoins that are just knockoffs that don’t add any value. Don’t translate my issue with the statement “Why no altcoin can succeed” into “All altcoins should succeed”. I think the market is the place to decide that.

My stance: Some altcoins are useful and interesting. Some altcoins are not. I doubt Dogecoin will survive as long as Litecoin.

Issue #4:

What is a cryptocurrency actually for? I say that its purpose is to become money. It is obvious that creating altcoins impedes that purpose. Altcoins can only be explained if we believe the purpose of cryptocurrencies is to make money rather than to become money.

(Premining)[https://bitcointalk.org/index.php?topic=194023.0] has rightly tainted people’s views of altcoins. If you premine your new cryptocurrency then you are probably just in it for the money. Granted maybe not enough people knew about your coin when it started but with a public announcement and some planning you can avoid this. Going back to my previous point I don’t understand why Bitcoin gets a pass on this. What if the original motivation was exactly the same as the altcoins that are guilty of premining? We can’t know if that was or was not the case until we know the true identity of Satoshi Nakamoto.

A lot of the time when people tell me something is “obvious” it’s because they’re trying to glaze over the fact that their explanation and understanding of the concept is lacking. I prefer proof rather than assertions.

My stance: Same as issue #3. Some altcoins are junk, some altcoins are not. The market will decide which ones are the winners. The author references the Wikipedia page for “motivated reasoning. Indeed either side of the argument could say the other is doing this especially when they assert the obviousness of the fact that they are right.

Issue #5:

If you try to compete with the best currency with another one that’s exactly the same, that makes yours the worse currency, so you really should not have bothered.

Another partial agreement here so this is a quick one. If your currency is exactly the same as Bitcoin then you shouldn’t have bothered. There are people who are trying to differentiate and that’s the kind of competition we should welcome. Starting a new altcoin gives you the freedom to try out these new ideas and see if they stick. Getting a feature into Bitcoin takes a lot of work and an altcoin can be a proving ground for that work.

My stance: Altcoins that don’t innovate are junk. If you’re going to create an altcoin it better have a few differentiators to be taken seriously.

Issue #6:

Scrypt was designed to be a memory hog and is consequently unsuited to mining with a machine consisting almost entirely of ASIC chips, like those used for Bitcoin, and it was assumed that Scrypt-coin mining would therefore always remain in the hands of the GPU owners. This, by the way, is false. If it ever became profitable enough, an ASIC machine could be produced with a shared memory, and it would make GPUs obsolete for Scrypt-mining too.

I have another post that touches this topic and explains why all proof of work algorithms need to use memory bound functions.

Why Proof of Work Algorithms Need to Use Memory Bound Functions

| Comments

Recently I read an article called “The Problem with Altcoins” and the author states this about Litecoin:

Scrypt was designed to be a memory hog and is consequently unsuited to mining with a machine consisting almost entirely of ASIC chips, like those used for Bitcoin, and it was assumed that Scrypt-coin mining would therefore always remain in the hands of the GPU owners. This, by the way, is false. If it ever became profitable enough, an ASIC machine could be produced with a shared memory, and it would make GPUs obsolete for Scrypt-mining too.

This is something that I hear a lot and it needs to be cleared up. There are some things ASICs are not good at. Where ASICs really shine are problems where you can design a pipeline that the data goes through in a mostly fixed order. SHA256 is perfect for ASICs. Each step of the algorithm requires very little storage. If I’m counting correctly you need 64 32-bit words, 16 16-bit words, and somewhere around 22 32-bit registers.

We’re talking about a really small amount of storage here. ((64 * 4) + (16 * 2) + (22 * 4)) == 376 bytes

Even if we bump it up to 512 bytes it is still a miniscule amount of storage in the grand scheme of all of the kinds of storage that we use today (registers, L1 cache, L2 cache, L3 cache, RAM, and hard drive space). Because of this it is cheap to make it very, very fast to read and write this data. Physically it occupies little space so you can put the components for this storage exactly where it needs to go on the chip.

Litecoin, and several other cryptocurrencies, use scrypt instead of SHA256. This algorithm was supposed to make mining only feasibly on CPUs. Modern GPUs though were found to have a bit of an edge over CPUs and the memory requirements weren’t high enough to really take GPUs out of the running.

Now there is X11, and CryptoNight which are even harder to implement on ASICs…

But anyway what I really want to address is this particular section of the statement:

an ASIC machine could be produced with a shared memory

This is a fundamental misunderstanding of computer architecture. An ASIC is super fast because it doesn’t have a pool of shared memory. The memory is exactly where it needs to be for each stage.

Do you know what the technical term for “ASICs with shared memory” is? A general purpose CPU. :) Yes, an ASIC with a pool of memory like this would still have some advantage but not the orders of magnitude we see now. This is because it would be bound to the same limits a CPU is bound to which is the relatively slow access time of RAM versus the CPU’s clock speed.

What can we do to make sure mining stays CPU bound? We should be using memory bound functions which are sometimes also called memory hard problems. These memory bound functions should require enormous amounts of memory. More than a Raspberry Pi has, more than a BeagleBone Black, more than a GPU. I mean ridiculous gobs of memory. Why not? If the proof of work function can be adjusted, and it has to be to keep up with Moore’s law, we can adjust the work to be easy in the sense that it requires few iterations but tons of memory. As CPUs and memory get faster and people join the network we just adjust it as we always have.

X11 and CryptoNight seem like a good start but there are still problems with them. It turns out there is one big benefit from algorithms that are not profitable on CPUs and that is that bot net operators are much less likely to waste their bot net time on mining those currencies. I have a feeling that X11 and CryptoNight are very profitable to mine on bot nets right now.

Is there a solution to level the playing field? Considering the bot net angle what does that even mean? I believe that there is a solution that would allow people to participate with CPUs, not require GPU and ASIC investments, and would prevent bot net operators from profiting on mining. I’ve been thinking about this for over a year and I’m getting very close to having what I think is a workable solution. There still is one hole in it but I think that it may be better than what is out there. Stay tuned and when I’m ready I’ll post it on my blog.

BTW, I started this blog post on 2014-01-10 and just finished it on 2014-06-17 so it may be a while before I release something. Be patient!

True Remote Debugging With Chrome’s Remote Debugging Feature

| Comments

Have you used Chrome’s remote debugging feature? It is a handy tool for debugging JavaScript in another tab/window.

That’s nice, but have you ever wanted to debug JavaScript that was running on another machine running Chrome? If so, and you’re running on Mac OS, you’ve come to the right place.

The first step in this process is to disable Chrome’s same origin policy. This may not be necessary in your application but I’ve always found I needed to do it in mine.

Now you’ll need to make sure you have socat installed. The easiest way to do this is with Homebrew. Install Homebrew, and then run this command:

1
brew install socat

That will install socat if it isn’t installed already.

Now start Chrome remote debugging on the system that you want to connect to.

Next, get socat to relay traffic from port 9223 to port 9222 using this command:

1
socat tcp-listen:9223,fork tcp:localhost:9222

Finally, try to connect to the remote computer using its IP address, not localhost with a URL like this:

1
http://IP_ADDRESS:9223

You should be connected to the remote system’s debugger using port 9223.

When you are done be sure to do this to stop socat:

1
killall socat

How to: Execute a Command on a Remote Server That Requires You to Su or Sudo

| Comments

Recently I ran into a situation where I had to reboot a ton of machines remotely. I couldn’t ssh as root, and you really shouldn’t do that anyway, so I thought I might be stuck trying to SSH in, “sudo reboot”, enter the password, and go on to the next machine. One snag was that some machines supported sudo and some required me to su.

I didn’t want to have to do this for all of the machines I was working on so I searched around and found Paramiko. Paramiko is an SSH library for Python that lets you tell Python the login password and also gives you direct access to the terminal stream from your SSH session. This means that I can send su or sudo and then send the password without the user doing anything.

Security wise this is an obvious hole in many ways. First of all if you do this for a machine and specify the password on the command-line it is going to end up in your history file. So without going through the exhaustive list of reasons why this is generally a bad idea lets just say that you should use this sparingly.

Set the variable root_command to the command that you want to execute as root, set root_command_result to the expected result of the command. The command needs to have \n on the end of it because it simulates the user pressing enter. Without it the system will never execute the command. Pass these command-line parameters in this order:

  • The IP of the system you want to connect to
  • The username of the user that can su to root
  • The password of the user that can su to root
  • The password required to su to root

This particular version of the script just performs the “su” command. It can be modified to do a “sudo” with just a few tweaks. If there’s demand I’ll post a version that lets you swap between both and does some additional error handling.

And here’s the script… don’t forget to install Paramiko!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/env python

__author__ = 'timmattison'

import paramiko
import sys
import time

root_command = "whoami\n"
root_command_result = "root"

def send_string_and_wait(command, wait_time, should_print):
    # Send the su command
    shell.send(command)

    # Wait a bit, if necessary
    time.sleep(wait_time)

    # Flush the receive buffer
    receive_buffer = shell.recv(1024)

    # Print the receive buffer, if necessary
    if should_print:
        print receive_buffer

def send_string_and_wait_for_string(command, wait_string, should_print):
    # Send the su command
    shell.send(command)

    # Create a new receive buffer
    receive_buffer = ""

    while not wait_string in receive_buffer:
        # Flush the receive buffer
        receive_buffer += shell.recv(1024)

    # Print the receive buffer, if necessary
    if should_print:
        print receive_buffer

# Get the command-line arguments
system_ip = sys.argv[1]
system_username = sys.argv[2]
system_ssh_password = sys.argv[3]
system_su_password = sys.argv[4]

# Create an SSH client
client = paramiko.SSHClient()

# Make sure that we add the remote server's SSH key automatically
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Connect to the client
client.connect(system_ip, username=system_username, password=system_ssh_password)

# Create a raw shell
shell = client.invoke_shell()

# Send the su command
send_string_and_wait("su\n", 1, True)

# Send the client's su password followed by a newline
send_string_and_wait(system_su_password + "\n", 1, True)

# Send the install command followed by a newline and wait for the done string
send_string_and_wait_for_string(root_command, root_command_result, True)

# Close the SSH connection
client.close()

Port 32764 - a Router Backdoor That You Need to Take Seriously

| Comments

TL;DR Several routers have been found to have a backdoor installed on them that is accessible via the LAN and WAN connections by default. If you have Internet access at home or at a client location you care about then you should be testing to see if they are vulnerable with ShieldsUP.

I would recommend running this test ASAP. The list of affected routers includes Netgear, Linksys, and even “real” Cisco hardware. That list is not exhaustive.

If you need to run this test via SSH I’ve whipped up a script that will spit out whether you’re vulnerable or not based on the ShieldsUP results. It was designed to run on Mac OS (because their version of sed is busted) and tested on Mavericks and Debian Linux. Here’s what you can run:

1
2
3
4
5
6
curl -L http://bit.ly/port32764 2>&1 | \
  tr "\n" " " | \
  tr "\r" " " | \
  sed 's/<[^>][^>]*>/ /g' | \
  sed 's/^.*32764/32764/' | \
  sed 's/Unknown.*$//'

The response should look like this:

1
32764 Stealth

Or this:

1
32764 Closed

If you get anything else then you are vulnerable. Even if you run this test I recommend running it in a browser on the connection you’re testing just in case the script has an issue.

If you are vulnerable then the following pieces of information about your connection may have already been compromised:

  • Your wireless key (in the clear, not hashed)
  • Your router admin username and password (in the clear, not hashed)
  • Your router’s SSID and MAC address (this can be used to add your router to a database of access points with passwords)
  • Any custom settings you have on your router (port mapping to interesting devices, tunnels you thought would be hidden on a high port number, etc)

People have written plenty of applications that do scans of the entire Internet in days or even hours. This is being scanned for constantly right now and you cannot hide in the four billion addresses out there.

If you are not vulnerable but you have used the same wireless password on an older router it is probably a good idea to change your password. Nobody knows how long this has been in the wild. It has been in the firmware for a long time.

If you need help post in the comments. Good luck!

Fixing In-Page Analytics With Google Analytics

| Comments

After migrating to Octopress I started getting interested in my site’s analytics again. A co-worker told me about in-page analytics with Google Analytics and how it would show you what people were doing on your site so you could tune your layout. We tried loading it and ran into some problems.

First, we got the “Loading…” spinner for a long time:

Loading...

Then we got the “Still loading…” message that didn’t inspire much confidence:

Still loading...

Finally, we got a popup that said “Problem loading In-Page Analytics”:

Problem loading In-Page Analytics

What the problem was in my case was that I told Google Analytics that I wanted to track timmattison.com but my site redirects to blog.timmattison.com. My two options were to make my site actually be served from timmattison.com or to change my tracking code. I opted to change my tracking code. I’ll walk you through how I did it.

NOTE: You will lose your existing tracking data if you do this! If you want to keep your tracking data you’ll need to find another way. For me it wasn’t a big deal because I just moved my site anyway and my analytics were reset a week or two ago already.

Here are the steps:

  • Log into your analytics account

Log into your analytics account

  • Click the admin button

Click the admin button

  • Click “View Settings”

Click "View Settings"

  • Scroll all the way to the bottom of the page

  • Click “Delete View”

Click "Delete View"

  • Click “Delete View” again. At this point you’ll lose all of your analytics history!

Click "Delete View" again

  • Click the admin button

Click the admin button

  • Click the property drop down and then click “Create new property”

Click the property drop down and then click "Create new property"

  • Re-create your property and make sure you use the site you redirect to. In my case “blog.timmattison.com”, not “timmattison.com”.

  • Put your new tracking code into your site. Don’t forget to do this or tracking won’t work at all!

And that should do it. Let me know if it works for you or if you need some help.

BeagleBone Black and Raspberry Pi SD Card Gotchas on Mac OS

| Comments

If you’re using dd on the command-line to write SD card images in Mac OS then you may have run into a weird issue where the image is starting to write and then dd comes back and says:

1
dd: /dev/diskX: Resource busy

I ran into this multiple times when building Raspberry Pi and BeagleBone Black images. What it turned out to be was that Mac OS needed me to set the block size for some reason. I arbitrarily chose 1 MiB so my command looks like this:

1
sudo dd if=image-file.img of=/dev/disk3 bs=1048576

After specifying the bs parameter it never happened to me again. Let me know if you ran into the same thing and whether or not this fixed it on your system.