Mobile Device Ownership Verification

Having recently been a participant in a ridiculously annoying and unfortunate set of easily avoidable circumstances involving my own smart phone, I’m of the mind to put together a little guide for use by those in possession of a lost phone and faced with someone claiming it’s theirs, as well as those seeking to reclaim a phone from the person or business currently in possession of it.

YOU ARE IN POSSESSION OF A DEVICE SOMEONE IS CLAIMING

All of the following ideas assume that you are, in fact, of the mind to return the device. If you’re just going to throw it away, or keep it for yourself, then naturally you can ignore this entire post.

Before any of the following steps are taken, ask that the claimant produce a photo ID, and make note of the name for your own records. You might consider asking for additional contact information, such as an alternate phone number and/or email address.

Prior to showing the claimant the device, ask the claimant to describe the carrier, make, and model of the device. Inspect the device for any tell-tale marks, scratches, or unique behaviors (loose keyboards, connections, buttons, etc.) that the device exhibits. Ask the claimant to describe the device, and listen for any description that matches the unique characteristics you noted. Do not volunteer any information about the device.

In each of the following situations, run through at least one of the verification options. Performing all of them might be overkill, but performing none of them is irresponsible.

The Phone Has Power and the Screen is Locked

  • Make the claimant call the phone from another phone. This will, at the very least, prove knowledge of the phone, if not ownership.
  • Make the claimant unlock the phone prior to leaving with it. This will prove a greater degree of knowledge of the phone and owner, if not ownership.
  • In the case of Androids and Blackberry’s, remove the battery and call the carrier. Give them the IMEI and the name of the claimant to confirm the carrier records match the person claiming ownership. Original iPhones have the serial number and IMEI engraved on the back metal case. For the iPhone 3G, iPhone 3GS, iPhone 4 (GSM model), and iPhone 4S, the SIM tray displays the IMEI number.

The Phone Has Power and is Unlocked

  • Make the claimant call the phone from another phone.
  • Make the claimant verify contents of the phone, such as contact names, pictures, home screen icons, installed applications, or any other unique aspect of the phone contents that prove intimate knowledge of the device. This might appear to be a breach of privacy, but if privacy was a real concern on the part of the owner, it would not be allowed to remain unlocked beyond a very short idle period.
  • In the case of Androids and Blackberry’s, remove the battery and call the carrier. Give them the IMEI and the name of the claimant to confirm the carrier records match the person claiming ownership. Older model iPhones do not provide physical access to this, but do provide this information on the About screen. Original iPhones have the serial number and IMEI engraved on the back metal case. For the iPhone 3G, iPhone 3GS, iPhone 4 (GSM model), and iPhone 4S, the SIM tray displays the IMEI number.

The Phone Does Not Have Power

  • If a charger is available, charge the device until such a time as it will boot, then proceed with one of the following methods:
    • Make the claimant call the phone from another phone.
    • Make the claimant unlock the phone prior to leaving with it.
    • Make the claimant verify contents of the phone, such as contact names, pictures, home screen icons, installed applications, or any other unique aspect of the phone contents that prove intimate knowledge of the device. This might appear to be a breach of privacy, but if privacy was a real concern on the part of the owner, it would not be allowed to boot into an unlocked state.
  • In the case of Androids and Blackberry’s, remove the battery and call the carrier. Give them the IMEI and the name of the claimant to confirm the carrier records match the person claiming ownership. Original iPhones have the serial number and IMEI engraved on the back metal case. For the iPhone 3G, iPhone 3GS, iPhone 4 (GSM model), and iPhone 4S, the SIM tray displays the IMEI number.

YOU ARE TRYING TO CLAIM A DEVICE

If you have lost and are claiming a phone, then you should voluntarily offer the following methods to confirm the device is, in fact, yours, rather than someone else’s. This could save you significant inconvenience and will certainly save the real owner significant inconvenience and concern.

  • In all cases, inspect the physical condition of the phone, looking for any tell-tale marks, scratches, or unique behaviors (loose keyboards, connections, buttons, etc.) that you know your device exhibits.

The Phone Has Power, And the Screen is Locked

  • Unlock it. Additionally, in the very unlikely case that you and another owner of the same make and model phone use the same unlock code or pattern, verify the contents of the phone as belonging to you. If the phone has been tampered with, this will also give you the opportunity to identify any issues that might have arisen while it was out of your possession, and follow up with the individual or business who has had possession of the device.

The Phone Has Power, And is Unlocked

  • Confirm the contents of the phone are yours. You know what’s on it. Make sure it’s what you’re expecting. This will also allow you to respond immediately if the phone has been tampered with.

The Phone Does Not Have Power

  • Either bring a charger, or have the person or business call the carrier to verify the IMEI matches what they have on record for your account.

You Send a Friend to Pick it Up

  • If you absolutely must send a friend to pick it up in your stead, provide them with enough identifying information as their trustworthiness allows, whether it be knowledge of the condition of the device, or knowledge of the unlock code or pattern and the contents of the device, so that they are able to answer any questions arising from the above methods and retrieve the correct device.

The above methods, if followed intelligently, will at least provide reasonable assurance that the right device leaves with the right person. No method is fool proof, and a truly determined thief will have done the research to be able to circumvent some of the methods described. But at least you can say you have done what you can to ensure that the device is in the right hands, rather than just giving the device to the first person who walks through the door saying they left behind a black phone with a screen on it.

Consider this a living guide that I will update with any good suggestions left in the comments.

Da plane! Da plane!!

It’s now a lot quicker (if also a lot more expensive) for the parents to come visit us. This is their Comanche on the ground at home base, and then Mom and Dad getting ready to head back to home base from New Century Air Service… a mere four minutes from our front door.

Straight Pool & Equal Offense Scoresheet/Spreadsheet Update

I’ve made some updates to the score sheets.

I’ve uploaded all of them now to GoogleDocs for one. That’s the big change.

Other small changes, currently exclusive to the GoogleDocs versions, are minor formatting changes, formulaic changes to rid the sheets of #DIV/0 errors, and the removal of some extraneous columns to help with formula drag filling.

Furthermore, I’ve shared all the GoogleDocs versions so they’re public for the finding, though I’ve retained exclusive editing rights.

As always, suggestions and tweaks, especially those that stem from trial-by-fire experience, are always welcome.

Straight Pool & Equal Offense Scores and Stats Sheets

Update to Malware Protecting Script

In an attempt to be a little more friendly in terms of bandwidth to the strapped folk over at Malware Domains, I’ve retooled the script I wrote about in the post To Be Protecting Against the Malware.

I’ve added some lines to take advantage of remote zipped files (.zip), which will help them by reducing the number of bits we’re pulling from them.

I’ve added some lines to copy the downloaded malware zones file to other servers behind my firewall, which will help them by not making individual connections from each server to pull the files. I just set up a cron job on each internal “slave” server to bounce named every morning timed for after this process is complete.

Here’s the updated code. It is, as is my wont, rather verbose. It is considerably more verbose than other examples out there that take care of this same problem, but as I said, such is my wont.

The URLS array is filled with fake hosts right now b/c the zipped format is still in testing. When the folk at malwaredomains.com think it’s ready for public consumption, I’ll put the real hosts back in.

Also, it’s relatively untested, and I expect to be tweaking it. Use at your own risk.

On the “master” server, I’m using this…

#!/usr/local/bin/bash

# To know where script is running
HOSTNAME=$( hostname )

# To put file where named can see it
BLACKHOLEDIR=/var/named/etc/namedb/blackhole

# To name file so we know what named seeing
TMPZONEFILE=tmp.malwaredomains.zones
ZONEFILE=malwaredomains.zones
ZONEFILEBACKUP=malwaredomains.zones.bak

# To get updated file from remote server
URLGRABBER=/usr/local/bin/curl
USERAGENT="Malware Domain Grabber ( ${HOSTNAME}; unix; BASH )/0.1"

# To keep quiet while am getting file
URLGRABBEROPTS="-s -f"

# To know where file is hosted
URLS=( host1 host2 host3 host4 )
TIMESTAMPFILE=timestamp

# To know how to decompress the file
UNZIPCMD=/usr/local/bin/unzip
UNZIPOPTS="-o -qq"

# To copy files to other servers so that we are only
# pulling the files once, though we have multiple
# DNS servers in house

HOSTS=( host1 host2 host3 host4 )

# MOUNTCMD: The mount command
MOUNTCMD=/sbin/mount
UMOUNTCMD=/sbin/umount

# FSTYPE: The filesystem type of the mounted partition
FSTYPE=nfs

# MOUNTDIR: The directory that the dumps will be written to
MOUNTDIR=/mnt

# To control bind
NAMEDCMD="/usr/sbin/rndc reload"

#==============================================================

# Get start time so we can know how long this thing runs
START=$( date +%s )

# Make our working directory the location of the blackhole files
cd ${BLACKHOLEDIR}

# Copy the current timestamp file to ${TIMESTAMPFILE}.old so we can
# make a comparison between what we have and what's out there now.
if [ -f ${BLACKHOLEDIR}/${TIMESTAMPFILE} ]; then
	cp ${BLACKHOLEDIR}/${TIMESTAMPFILE} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.old
fi

# Attempt to download the timestamp file and zone file from each mirror.
# Break out of the loop at the first successful download of a zone file,
# otherwise, try each one in turn

# Assume there are no updates available
NEW=0

for URL in "${URLS[@]}"; do
	echo "Attempting to download from ${URL}"
	echo " Checking timestamps..."
	${URLGRABBER} ${URLGRABBEROPTS} -A '${USERAGENT}' -o ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip ${URL}/${TIMESTAMPFILE}.zip

	if [ $? -ne 0 ]; then
	echo "  ... timestamp download from ${URL} failed! Code: $?"
	# Move on to next URL so we keep the timestamp/zonefile pair intact
	continue
	else
	if [ -f ${BLACKHOLEDIR}/${TIMESTAMPFILE} ]; then
		# Unzip the new timestamp file over the old old one
		${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip

		# Do a little cleanup
		rm -f ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip

		OLDTIMESTAMP=$( cat ${BLACKHOLEDIR}/${TIMESTAMPFILE}.old )
		NEWTIMESTAMP=$( cat ${BLACKHOLEDIR}/${TIMESTAMPFILE} )

		if [ ${OLDTIMESTAMP} -ge ${NEWTIMESTAMP} ]; then
			echo " ... no new updates."
			# No new updates on this server... but how well are the various mirrors
			# kept in sync?  Let's try the others. This is a tiny transfer, and it's
			# only once a day, so it's pretty cheap.
			continue
		fi
	else
		# Timestamp file does not exist. Create it.
		${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
		rm ${BLACKHOLEDIR}/${TIMESTAMPFILE}.zip
	fi
	fi

	# Backup and copy file to final location for named to find
	# (via "include" directory in named.conf)
	echo "Backing up zone file"
	cp ${BLACKHOLEDIR}/${ZONEFILE} ${BLACKHOLEDIR}/${ZONEFILEBACKUP}

	echo "Retrieving new zone file from ${URL}..."
	${URLGRABBER} ${URLGRABBEROPTS} -o ${BLACKHOLEDIR}/${ZONEFILE}.zip ${URL}/${ZONEFILE}.zip

	if [ $? -ne 0 ]; then
		echo "  ... zonefile download from ${URL} failed!  Code: $?"
		# Oops.  Try the next server.  If this is the last, then ${NEW} is still
		# set to 0, and we'll be done. Better luck tomorrow...
		continue
	else
		# We have a new timestamp, and were able to download the zone file from
		# the same server we downloaded the timestamp from.  Set ${NEW} to 1 and
		# get out of the loop. No need to check further.

		echo "Unzipping new zone file..."
		if [ -f ${ZONEFILE}.zip ]; then
			${UNZIPCMD} ${UNZIPOPTS} ${BLACKHOLEDIR}/${ZONEFILE}.zip
			rm ${ZONEFILE}.zip
			# Rename the zone file temporarily to allow sed to work on it later, and
			# and in that process, rename it back to the name that named knows.
			mv ${ZONEFILE} ${TMPZONEFILE}
		else
			echo "No new zone file..."
			exit
		fi

		NEW=1
		break
	fi
done

# If ${NEW} hasn't been set, then we either error'd out of all servers, or there are no
# new files. Either way, we're done.
if [ ${NEW} == 0 ]; then
	exit 1
else
	# Disable name checking for only those domains with underscores,
	# so we don't have to turn off name checking globally.

	SEARCH='_'
	FIND='blockeddomain.hosts";};'
	REPLACE='blockeddomain.hosts"; check-names ignore;};'

	# Get a count of the zones from the last update
	OLDZONECOUNT=$( cat ${BLACKHOLEDIR}/${ZONEFILEBACKUP}|grep "^zone"|wc -l )

	echo "Disabling checking on domains with underscores"
	sed "/${SEARCH}/ s/${FIND}/${REPLACE}/g" ${BLACKHOLEDIR}/${TMPZONEFILE} > ${BLACKHOLEDIR}/${ZONEFILE}
	rm -f ${BLACKHOLEDIR}/${TMPZONEFILE}

	# Get a count of the zones from the current update
	NEWZONECOUNT=$( cat ${BLACKHOLEDIR}/${ZONEFILE}|grep "^zone"|wc -l )
	echo "${OLDZONECOUNT} Previous Zones"
	echo "${NEWZONECOUNT} Current Zones"

	echo "Reloading named"
	${NAMEDCMD}

	if [ $? -ne 0 ]; then
		echo "  ... failed! Restoring zone file"
		cp ${BLACKHOLEDIR}/${ZONEFILEBACKUP} ${BLACKHOLEDIR}/${ZONEFILE}

		echo "Reloading old zones in named"
		${NAMEDCMD}

		if [ $? -ne 0 ]; then
			echo "  ... failed again!! You'll want to see to that."
		fi
	fi

	echo "Copying files to other internal network servers..."

	for HOST in "${HOSTS[@]}"; do
	DUMPDEVICE=${HOST}:${BLACKHOLEDIR}
	MOUNTRESULTS=$( ${MOUNTCMD} | grep "${DUMPDEVICE} on ${MOUNTDIR}" )

	if [ "${MOUNTRESULTS}" == "" ]; then
		echo ""
		echo "Mounting ${DUMPDEVICE} on ${MOUNTDIR}"
		${MOUNTCMD} -t ${FSTYPE} ${DUMPDEVICE} ${MOUNTDIR}
		if [ $? = 1 ]; then
			echo " ... failed. Files will not be copied."
			continue
		else
			echo " ... succeeded"
		fi
	else
		echo "${HOSTNAME}:${DUMPDEVICE} already mounted on ${MOUNTDIR}"
	fi

	# Copy the files to ${MOUNTDIR} as a temporary file. On the remote server,
	# we'll manage bouncing named if necessary.
	echo ""
	echo "Copying ${BLACKHOLEDIR}/${ZONEFILE} to ${TMPZONEFILE}"
	cp ${BLACKHOLEDIR}/${ZONEFILE} ${MOUNTDIR}/${TMPZONEFILE}
	if [ $? = 1 ]; then
		echo "... Failed to copy ${ZONEFILE}! You might want to see to that."
	fi
	# Umount the backup filesystem
	echo ""
	echo "Unmounting ${MOUNTDIR}"
	${UMOUNTCMD} ${MOUNTDIR}
	if [ $? = 1 ]; then
		echo " ... failed. You might want to see to that."
	else
		echo " ... succeeded"
	fi
	done

	END=$( date +%s )
	RUNTIME=$(( ${END} - ${START} ))
	H=$(( ${RUNTIME}/3600 ))
	M=$(( ( ${RUNTIME}/60 ) % 60 ))
	S=$(( ${RUNTIME} % 60 ))

	echo "Malware zonefile download on ${HOSTNAME} complete in"
	echo "${H} hrs, ${M} mins and ${S} secs (${RUNTIME} secs)"

	exit
fi

On the “slave” servers, I’m using this…

#!/usr/local/bin/bash

# To put file where named can see it
BLACKHOLEDIR=/var/named/etc/namedb/blackhole
ZONEFILE=malwaredomains.zones
TMPZONEFILE=tmp.malwaredomains.zones

# To control bind
NAMEDCMD="/usr/sbin/rndc reload"

if [ -f ${BLACKHOLEDIR}/${TMPZONEFILE} ]; then
	echo "New zone file exists..."
	# Rename the zone file to back it up
	echo "Backing up current zone file."
	mv ${BLACKHOLEDIR}/${ZONEFILE} ${BLACKHOLEDIR}/${ZONEFILEBACKUP}
	# Rename the tmp file to the name the daemon can find
	echo "Replacing it with the new zone file and removing the temp file."
	mv ${BLACKHOLEDIR}/${TMPZONEFILE} ${BLACKHOLEDIR}/${ZONEFILE}

	# Reload named.
	${NAMEDCMD}

	if [ $? -ne 0 ]; then
		echo "    ... failed! Restoring zone file"
		cp ${BLACKHOLEDIR}/${ZONEFILEBACKUP} ${BLACKHOLEDIR}/${ZONEFILE}

		echo "Reloading old zones in named"
		${NAMEDCMD}

		if [ $? -ne 0 ]; then
				echo "    ... failed again!! You'll want to see to that."
		fi
	fi
else
	echo "No update.  Quitting..."
fi

Moving the Home Network

Part of the packing, cleaning and moving marathon of the last week, which is to continue through the coming weekend, was the move of the family computers and servers. This meant the following very simple steps:

  • the set up of the internet connection at the new place,
  • changing DNS upstream to point to the new IP,
  • shutting down and physically moving the servers,
  • physically reconnecting them,
  • connecting the wireless router to the new cable router,
  • configuring the new cable router to account for the wireless router,
  • configuring the external IP on the wireless router,
  • firing up the servers,
  • enjoy fun website availability and internal DNS goodness.

Every step went well and easy, all the way up until that last step.

Though all the laptops in the house connected just fine to the Comcast cable modem/router, the two FreeBSD servers simply would not. From a logical network topology standpoint, nothing had changed. None of the IP addresses, including the gateway and the subnet, had changed. As far as the server interfaces were concerned, they’d just been turned off and turned back on. Let me emphasize that – from a logical network topology standpoint, nothing had changed.

I had it set up like so:

Net -> Comcast Router -> Servers & Laptops.

But they weren’t working. One worked briefly, but then quit. The other never would work.

If the cat5 cable (any cat5 cable) was plugged in, a ping to the (same as before) gateway would result in “sendto: Host is down”. If the cable wasn’t plugged in, I’d get a “sendto: No route to host”. Clearly there was some awareness going on, and the NIC was functioning at some level, because pinging the assigned IP, localhost, or 127.0.0.1 would all return successful. I couldn’t get any response from the gateway, however, and no other working machines could get responses from the servers. It was weird.

So, I got on the phone with Comcast to ask them about any incompatibilities with the router and FreeBSD. I got some good information about my usable external public IP (unrelated to the problem at hand), and some completely bogus information about having to use static IPs within the DHCP scope on their router (yeah but… what?!). The first level tech support wanted to help, but he just didn’t have the expertise, and so he escalated me to the next level (who is well past their 48 hour self-imposed deadline at the time of this writing). I decided to change things up a bit.

I went to this setup:

Net-> Comcast Router -> Wireless Router -> Servers & Laptops.

Note that this is exactly the same as I had at my old house, with the substitution of the Comcast Router for the Surewest cable modem. Everything from the wireless router on back is identical.

You know what? The laptops all worked (I love knowing even rudimentary networking), but the servers still didn’t work. Having eliminated the router, cables and network configs, the fact that it doesn’t work anymore with the exact same setup as was at the other house tells me it’s a another type of hardware problem.

So I yanked the gigabit NICs right out of the servers and went back to the on-board 100baseTX ports and… get this – it worked just fine.

What I’m concluding is that the D-Link GigaExpress DGE-530T card doesn’t work well with the BIOSTAR N68S3+ and the Diablotek EL Series PSEL400 400W ATX PSU. I base that conclusion in part b/c, in addition to flat out not working anymore, there are times when the machines won’t power on when the DGE-530T is installed without some creative combinations of the case power button and the PSU switch. When those cards aren’t installed, there are no issues. What, I didn’t mention that before? My bad.

Given that when I put these servers together, I did so with as little cash outlay as possible. I’m thinking I’ve been bit by the “get what you pay for” principle. In time, I’ll beef them up a bit with better components. But for now, I’m just happy to be back online enjoying fun website availability and internal DNS goodness.

New Homes are Heavy

The wife and I have been very busy lately. It’s not yet over, but this past weekend was perhaps the busiest, not to mention heaviest, part of the process. That process is moving.

The whole thing started last spring, when we put our two houses on the market. This past spring, a year later almost to the day, her house finally sold and we had the wherewithal to purchase a new house. We packed her house into two POD units and moved them into storage until we had a place to put them. At the same time, we took mine off the market because it hadn’t sold yet, and we didn’t want to take the chance of it selling and us having no place to go. Turns out it wasn’t a concern, because we found the house we wanted to buy within days.

We made an offer, they countered, we met in the middle, and two long months later, we took possession. When that day finally arrived, we couldn’t move in immediately because we had too many other family obligations (Jami’s sister graduated with her doctorate! We couldn’t miss that graduation day…). So, exactly one week after we took possession, I had the two full-to-the-roof POD units filled with more boxes and heavy furniture than any one person has any business owning, delivered for unloading at the new house. With the help of some very friendly neighbors, we started unloading them that night. We continued unloading the next night, and did so until we dropped. We spent our first night in our new home that night. Fortunately, the bed was easily accessible in the POD unit, so we didn’t have to sleep on the floor. By the time we were done, though, it wouldn’t have mattered where we slept… we were too tired to care. Finally, on Saturday, some friends came over to help unload the rest.

By Saturday night, we were absolutely beat. Unfortunately, our work was not yet done. We spent Sunday at the old house, packing up, mowing the yard, and cleaning. Then we devoted that evening at the new home unpacking, straightening up and getting all the computers back online.

Being Memorial Day weekend, we had an extra day which was spent back at the old house for more packing (about 500lbs worth of books – plus lots of this and that) and lots of cleaning. Monday night was given to more unpacking, more cleaning, and more organizing. We did give ourselves a bit of a break for a glass of wine on the front porch before getting back to it.

At the end of the weekend, between the two of us and some very helpful friends and neighbors, we have a pretty good start on a new home.

But our work is not yet done. The POD units were still in the driveway as of Wednesday, to be picked up on Thursday and Friday. Saturday we’ll get a truck to move the rest of the heavy stuff out of my house. Until then, we’ll spend a lot of time at the old house getting as much packed and moved as possible so that the friends who are helping on Saturday only have to help us with the heavy items we can’t move by ourselves. From there, it’s a matter of final cleaning and finishing up a few little details here and thereto get it in tip-top shape to put back on the market. We’re hoping to sell it within the next 2 and a half months. We’ll see…

Back to the Gate

So, I started playing Baldur’s Gate recently. I never finished it back in the day (though I got close), and barely took advantage of the Tales of the Sword Coast expansion. For some reason, with everything going on in our lives right now, and in spite of the fact that I’m arguably busier now than I’ve been since Finals Week in college, I just couldn’t help running through 5 CDs worth of installation and launching some relatively old school gaming (I consider Atari 2600 and the Age of Darkness and the Age of Enlightenment truly Old School – and even that’s too new for some).

It runs a little fast on my m9700, but not too fast to play. The dialog runs together now and again when there is a lengthy challenge/response conversation playing out, but other than that, I’ve noticed no ill effects of the slightly accelerated rate.

I tried using the G3: Widescreen Mod in order to enjoy larger resolutions, but found that I had issues with mouse scrolling around the area at 16:9 resolutions that were less than the native resolution of my monitor (1920 x 1080). Because of the time consuming way the mod is applied, I didn’t try too many resolution options. I also noticed some frame rate issues at the native resolution in spite of the age of the engine (or perhaps, because of it). So I decided to stick with playing it the way it was originally released and patched. I’m not playing for the graphics, after all, but the experience.

I’ve heard rumors that it’s possible to convert BGI to the BGII engine, though. I might look into that. Graphics aren’t everything, but the BGII engine is so much nicer…

I probably won’t have much time in the next couple of months to do more than tinker with it here and there, but after we’re settled in to the new house, and some of my other responsibilities are managed (not the least of which is a FreeBSD build that’s proving difficult due to a troublesome inability to detect the hard drives once in sysinstall), I’ll be able to devote a little more time to it. I may even dive back into Baldur’s Gate II, and the Icewind Dale series.

I wonder how it’ll run on the X79 LGA2011 based machine I plan on building towards the end of the year. If it runs fast on a 6 year old laptop…

DiscoverCard.com & Password Length Restrictions

With all the major breaches in the news lately (RSA, Gawker, PSN, Lastpass, MySQL, Texas Comptroller, etc. – hit the googles with you!), I finally got angry enough to ask a question of DiscoverCard that has been sitting on the back burner for too long. It’s about what I consider to be absurd password length restrictions on their site, and what that might say about how they’re storing those passwords on the back end.

Let’s clear one thing up: On principle, I believe I should be able to use whatever password I want. If I want to use “abc123″, or “puppy1″, or “;a3Wfzu0J|rqVHj%l]x6PZdQHqhpK39vx5?|fSb9NmFdq”, I should be able to. I should have the right to be as smart, stupid, paranoid or legitimately cautious as I want (here’s the thing) so long as my choice doesn’t affect others using the same system. I’m not the only one to think along those lines.

Principles aside, I don’t have a practical problem with complexity enforcement. I understand that repositories of critical and/or sensitive data and services have a need to shore things up a bit with more complex passwords. That doesn’t stop me from thinking there are design issues at hand if my weak web password can compromise someone else’s data. I also can’t help but think the whole mess is, at least in part, driven by a disgusting, ludicrously naive and juvenile expectation that “everything will always be ok, and I’m entitled to it. It’s my right! So there!” and all the litigation that goes along with that childish attitude.

That all said, it’s one thing to require password complexity, it’s another entirely to not allow it past X characters. It raises some questions…

So I asked DiscoverCard about it: (May 05, 02011 09:41 AM)

Can you please explain to me the exact method by which discovercard.com website logon passwords are stored? The length limit greatly concerns me. With the major breaches of late (PSN, Sony, Lastpass, MySQL, Gawker, etc.) it is critical that passwords be stored securely, with adequate encryption, or at the very least, salted hashing. Thank you.

Admittedly not the best in terms of wording and stated concerns. But there you have it. I can’t help but believe DiscoverCard, of all places, is using top-notch methods for storing passwords, but you just never know, do you?

DiscoverCard’s first reply: (May 05, 02011 10:46 AM)

Thank you for your recent message. I understand your concern about online security, and I will be happy to assist you today!

Our emphasis on privacy provisions and improved Internet security has made using our website safer than ever. We use the Secure Socket Layer (SSL) protocol for encrypting communications with our Cardmembers. SSL uses public-key cryptography to scramble the information sent between senders and receivers. In the unlikely event that third parties try to eavesdrop or intercept this message, SSL encryption prevents them from viewing its contents.

We also have Superior Fraud Protection, which means that when you use your Discover Card to shop anywhere on the Internet, you will not be liable for any unauthorized transactions. For more information about our security, please see the following page:

http://www.discovercard.com/customer-service/safety/site-security.html

I appreciate your business and the opportunity to be of service. Thank you for choosing to use Discover Card.
[signature and legalese removed]

Awesome, but no, that’s not what I asked. So, I completed a survey indicating as much and replied… (May 05, 2011 11:06 AM)

Thank you for the prompt reply. I appreciate the information on SSL, however, that doesn’t answer the question I asked. I asked about password storage (at-rest), not information on the wire (in-transit). My question is restated here for your convenience…

“Can you please explain to me the exact method by which discovercard.com website logon passwords are stored? The length limit greatly concerns me. With the major breaches of late (PSN, Sony, Lastpass, MySQL, Gawker, etc.), it is critical that passwords be stored securely, with adequate encryption, or at the very least, salted hashing. Thank you.”

To which they replied… (05/05/2011 12:06 PM)

Thank you for your recent inquiry. In an effort to provide you the best service possible, I have escalated this issue to the appropriate parties in our company for further assistance. We will respond as soon as we have any additional information concerning this matter. Thank you for your patience.

I appreciate your business and the opportunity to be of service. Thank you for choosing to use Discover Card.
[signature and legalese removed]

I don’t expect another reply anytime soon… but I’ll let you know if I do get one, either in the comments, or as a new post depending on the reply.

To Be Protecting Against The Malware

Last night, my wife called me into the office with an alarming “It says it’s infected with malware!” Needless to say (and yet I’m going to say it anyway) I hurried into the room to see what the hullabaloo was all about.

Sure enough, there was a window exclaiming the existence of not one or two, but quite a few malware infections.

It fooled her, and damn if that stupid pop-up didn’t nearly fool me too! Truth be told, it did, if only for a second. Those malware serving fake malware pop-up warnings are clever.

It got me to thinking.

Then Osama bin Laden was shot in the head, and malware peddlers started leveraging our insatiable appetite for news about it (the sick bastards).

That got me thinking more.

It reminded me of the malware peddlers that took advantage of the quake in Japan recently. Now those are some seriously sick bastards.

Those events all in quick succession and all that thinking led me to this.

A little ditty that downloads the bind formatted zone file from MalwareDomains.com, moves it to where Named can see it, and reloads Named zone files if the download is complete. I’d verify the file if they provided an md5 of the zones file. But they don’t. Not that I could find, anyway.

I don’t even begin to hope to eliminate the risk of malware infected sites, but I think this is a positive step towards cutting off malware source domains which might, in turn, help against sites on legitimate domains that happen to be infected. As of today, May 3rd, 2011, there are nearly 10,000 domains in the latest file. That has to be nearly all of them.

Right?

I’ll try it out for a while and see what happens.

BTW, this only works if you’re running your own DNS. If not, you’re at the mercy of your ISP or whatever DNS you choose to use. There are plenty of options out there, and they’re not all horrible.

First, the script, which pulls down the latest malware domains zones file from malwaredomains.com, fixes some problems with underscores in the subdomains, copies the fixed zones file to the named chroot, and reloads the named configs.

#!/usr/local/bin/bash

# To know where script is running
HOSTNAME=$( hostname )

# To put file where named can see it
NAMEDDIR=/var/named/etc/namedb

# To name file so we know what named seeing
ZONEFILE=malwaredomains.zones

# To have a file for sed to work on
TMPZONEFILE=tmp.malwaredomains.zones

# To get updated file from remote server
URLGRABBER=/usr/local/bin/curl

# To keep quiet while am getting file
URLGRABBEROPTS="-s -S"

# To know where file is hosted
#URL=http://www.malwaredomains.com/files/spywaredomains.zones
URL=http://mirror1.malwaredomains.com/files/malwaredomains.zones

# To control bind
NAMEDCMD="/usr/sbin/rndc reload"

#==============================================================

# Get start time so we can know how long
START=$( date +%s )

# Get directory we're running from
SCRIPTDIR=$( dirname $0 )

cd ${SCRIPTDIR}
if [ $? -ne 0 ]; then
    echo "ERROR: Unable to cd to ${SCRIPTDIR}! AbOrTinG!!"
    exit 1
fi

# If we were executed like "./whatever.sh" - set SCRIPTDIR to the pwd
if [ "${SCRIPTDIR}" == "." ]; then
    SCRIPTDIR=$( pwd )
fi

echo "Script is running from ${SCRIPTDIR}"

# Download the zones file in bind format to a temporary location.
# We don't want to overwrite what we already have until we're sure
# the download worked

echo "Downloading file from ${URL}"
${URLGRABBER} ${URLGRABBEROPTS} -o ${SCRIPTDIR}/${ZONEFILE} ${URL}

# Check for errors.  If the file downloaded, then move on, but if not
# we don't want to reload named without the previously updated
# malware domain list

if [ $? -ne 0 ]; then
    echo "    ... download failed! Error: $?"
    exit 1
else
    # Disable name checking for only those domains with underscores,
    # so we don't have to turn off name checking globally.
    SEARCH='_'
    FIND=';};'
    REPLACE='; check-names ignore;};'

    echo "Disabling checking on domains with underscores"
    sed "/${SEARCH}/ s/${FIND}/${REPLACE}/g" ${SCRIPTDIR}/${TMPZONEFILE} > ${SCRIPTDIR}/${ZONEFILE}

    # Get a count of the zones from the last update
    OLDZONECOUNT=$( cat ${NAMEDDIR}/${ZONEFILE}|grep "^zone"|wc -l )

    # Copy file to final location for named to find
    #(via "include" directory in named.conf)
    echo "Copying file from ${SCRIPTDIR} to ${NAMEDDIR}"
    cp ${SCRIPTDIR}/${ZONEFILE} ${NAMEDDIR}

    if [ $? -ne 0 ]; then
        echo "    ... failed! AbOrTinG!!"
        exit 1
    fi

    echo "Reloading zones in named"
    ${NAMEDCMD}

    if [$? -ne 0]; then
        echo "    ... failed! You'll want to see to that."
    fi

    # Get a count of the zones from the current update
    NEWZONECOUNT=$( cat ${NAMEDDIR}/${ZONEFILE}|grep "^zone"|wc -l )
    echo "${OLDZONECOUNT} Previous Zones"
    echo "${NEWZONECOUNT} Current Zones"
fi

END=$( date +%s )
RUNTIME=$(( ${END} - ${START} ))
H=$(( ${RUNTIME}/3600 ))
M=$(( ( ${RUNTIME}/60 ) % 60 ))
S=$(( ${RUNTIME} % 60 ))

echo "Malware zonefile download on ${HOSTNAME} complete in"
echo "${H} hrs, ${M} mins and ${S} secs (${RUNTIME} secs)"
exit 0

Then, the cron job to update the list on a daily basis:

35 0 * * * /root/bin/malwaredomains/malwaredomains.sh 2>&1 | mail -E -s "Malware Domain Named Update" me@here.com

Then, the blackhole host file that all those zones in the malwaredomains.com download refer to. Careful with this one, and you’ll want to replace the domains with something a little more relevant:

$TTL    86400           ;one day
@ IN SOA ns0.example.net. hostmaster.example.net. (
        2011050100  ; serial number YYYYMMDDNN
        28800       ; refresh 8 hours
        7200        ; retry 2 hours
        864000      ; expire 10 days
        86400       ; min ttl 1 day
)
        NS      ns0.example.net.
        NS      ns1.example.net.
        A       127.0.0.1
*   IN  A    127.0.0.1

Finally, the line in the named.conf file (in my case, in the internal view) to call on the recently downloaded zones file:

include /etc/namedb/malwaredomains.zone

That should do it!

This is what I receive in my inbox after every update (daily for me):

Script is running from /root/bin/malwaredomains
Downloading file from http://mirror1.malwaredomains.com/files/malwaredomains.zones
Disabling checking on domains with underscores
Copying file from /root/bin/malwaredomains to /var/named/etc/namedb
Reloading zones in named server
reload successful
   10116 Previous Zones
   10116 Current Zones
Malware zonefile download on [hostname] complete in
0 hrs, 0 mins and 2 secs (2 secs)