Skip to content

Engineers, Stay Agile

Engineers, stay agile.
I became a software engineer for many reasons. I love to code. I love to create. I love solving puzzles. I love exploring different technologies. I love the rewards. I chase the knowledge. I desire to make a difference.
Chances are, you do too.
You may have become a programmer for the very same reasons I did. But allow me to raise a few questions:
Are you really doing what you love? Are you being challenged mentally? Are you chasing the knowledge? Are you truly on your way to making a difference?
If your honest answer is “yes”, I am happy for you. For everyone else, you are not alone.

Doing what you love: code, create, solve problems, explore different technologies

As a software architect, most job opportunities come with a verbal promise of “freedom to build the product the way you want to do it”. Additionally, there will be “many opportunities to explore different technologies as the business expands into this and that”.
The latter is utter BS. The first is a catch-22 type BS. Isn’t it funny how even the CEO knows that the engineer’s dream job is doing R&D and will try to make his/her company appear like one?
Look. I appreciate the “freedom”, but let’s be real. I’m not hired to build the product in that functional programming language I am dying to try out. No. I’m being hired to build it with the technologies I’m most experienced with (and consequently, bored to death of). And IF the company is fortunate enough to “expand”, they will want me to stay right where I am “manning the station” THEY feel most comfortable with. After all, the goal is to build a well-oiled machine while the engineers (and other employees) act like the hamsters spinning the wheels. Before you know it, you’ve spent a good chunk of your life learning nothing and being a tool.

Challenging yourself mentally

Let’s face it. We all interpret “challenging” differently. For an engineer, a challenge would be to figure out how to improve an algorithm’s efficiency by an order of magnitude. A challenge would be to figure out how to scale your architecture to handle enterprise level traffic without going over budget. A challenge would be to write software that can analyze images for an autonomous vehicle.
Your employer on the other hand, thinks you’re being challenged because you are given a deadline of 4 weeks to build a social networking site. They think you’re being challenged because you are expected to work 16 hours a day / 7 days a week.

Chasing the knowledge

You are a curious individual. I know you love to learn new things. So when did you last pick up something new? What was the last book you read? Does your job give you time to study and read? Know this. As engineers, if you don’t keep up with the latest technological trends, your value diminishes. Staying stagnant is the same as moving backwards. Do you know any Pascal or VB6 programmers? Lotus 1-2-3, Quattro Pro, WordPerfect experts? Coldfusion developers? Corel Draw designers? I can brag about being able to redefine your keyboard while performing a dedicated print over a BBS chat room if you load ansi.sys in your config.sys… but who cares? It’s irrelevant now. Yeah. Unless you do something about it, you too will expire.

Making a difference

You’re probably working on something cool. There may be similar products out there but they lack this feature and that feature, right? You’ve perfected your 30 second elevator pitch in case somebody asks you what you’re working on and you generally receive positive feedback. But is your contribution to this product really going to make a difference in this world? While on your deathbed, will you look back and be proud of this thing you built? Or is it just another gimmicky website or iphone app that will likely lose its value in a couple years?

Staying agile…

I understand you need to make a living, but I don’t think any job is worth sacrificing your own growth. I am a workhorse. I have spoiled my employers by pulling the weight of several engineers while being underpaid. I have spoiled my employers by working nights and weekends and forfeiting vacations (while they traveled the world). I have spoiled my employers by taking ownership of my work even though I own nothing but a few insulting stock options. Don’t fall victim to the smooth talking businessman/woman who entices you to make his/her ideas come to life while your own life’s priorities take a back seat. They have glorified the workaholic engineering lifestyle… the redbulls and hackathons…
Ha! Screw hackathons. We don’t throw business people into a little room and reward them with redbulls and T-shirts while they stay up all weekend to make money for us.

Listen. I love working on startups and I’m sure you do too. But get one thing straight: If you’re not the owner of your company, you have a job. Treat it as such. Meanwhile, invest some time into your own life and maintain your worth. Stay agile.
Lateral career movements are sometimes the only way for you to better yourself and keep your work from turning stale.
I prefer sabbaticals. During my occasional sabbaticals, I disappear from the workforce and read books, learn new things, build pet projects, etc.
… and I always return stronger.

Converting Geographical Coordinates to Cartesian Coordinates

I was working on an interesting short term project through Project C for an upcoming movie called Oblivion.

How it works:
Basically, users contribute their favorite memories of Earth via Twitter and/or Instagram hashtagged with #oblivionmemory. If the tweet or photo includes your geolocation, it is automatically placed on a global map. The map at first glance appears cold, dark and desolate, but as user contributions are added, it begins to brighten, state by state, country by country. At the end of the campaign, the map will have transformed into a bright beautiful landscape of the world, as if these precious memories have revived the Earth back to life from Oblivion. (as Matthew Jordan so delicately explains)

This sounds simple enough but it presents a couple challenges. First, after aggregating tweets and photos, how does one convert those geocodes to cartesian coordinates? How do you take the longitude / latitude pairs and find the corresponding pixel on a given map?
In the programming world, given a particular viewport, the origin usually starts in the upper left corner while the x and y values increase as you move towards the bottom right. For this reason, I don’t like the fact that people still call it “cartesian coordinates”. I’m not a mathematician but technically speaking, the correct terminology should be “the absolute value of quadrant IV in the cartesian coordinate system”. Would it not? Anyhow, I’ve accomplished this conversion by performing a few steps:
1) Find the top left and bottom right corners (in pixels) on the map.
2) Find the corresponding geographical coordinates for each of these points.
3) Adjust the longitudes and latitudes (separately) so that their origin is also placed in the upper left corner (using only addition/subtraction and absolute value math).
4) Represent max and min values for both longitude and x values in slope intercept form (y=mx+b)
5) Solve for m and b
6) Repeat steps 4 and 5 for latitude and y values.

Now that I have m and b (slope and y-intercept) for longitude (x) and latitude (y), all I have to do is plug any longitude and latitude into their respective formulas and it will yield the corresponding x and y values.

Now that I can systematically generate xy coordinates for each geocoded post, I need to figure out a way to make the map turn from grayscale to color only in these areas. The way accomplished this was to take a grayscale map and layer it on top of a color map. Next, I would “punch holes” into the top layer exposing pieces of the color map below. These crop circles can be easily generated through GD doing something like this:
imagefilledarc($img, $x, $y, $diameter, $diameter, 0, 360 $transparent, $srcimage, IMG_ARC_PIE);

The rest is easy stuff. :)

The site can be viewed at www.earthisamemory.com (due to moderation, posts will not appear on the map instantly)

Candy Crush Is a Fun Game… Let’s Hack It

I noticed a bunch of my friends were playing a game called “Candy Crush”. I’m not much of a gamer nor do I have time to waste on games, but I had to see what the hype was all about. I mean, this game went viral and I want to know what they did right. So I played it. It certainly is fun. I played it for 6 days and reached level 105. Cool, but there are currently 305 levels and I don’t wish to waste any more time on this game. I got curious, so I started logging tcp packets sent back and forth to king.com through the flash client. I found a few interesting bits of information.

First, when I put my cursor over any of the beaten levels, I get a little popup image of that level. Each time I do this, I see the flash client making a GET request to
https://cc1.midasplayer.com/images/levels/XXX.png
(replacing XXX with the level number). Using wget or your browser, you can preview any level you like. For example,
https://cc1.midasplayer.com/images/levels/320.png
will show you level 320 (which doesn’t even exist yet).

Second thing I noticed, the flash client polls https://candycrush.king.com/api/poll and GETs a JSON encoded string with some interesting data:
{“currentUser”:{“userId”:XXXX,”lives”:1,”timeToNextRegeneration”:1780,”gold”:0,”unlockedBoosters”:[],”soundFx”:true,”soundMusic”:true,”maxLives”:5,”immortal”:false, “mobileConnected”:true}}
This data tells your client who you are, how many lives you have, sound settings, max lives….. and immortal? Woah. It appears the good folks at King have a secret setting called “immortal” (which of course defaults to false). How does one set “immortal” to true? Well, you can get creative. The idea is to deceive your browser and send it phony data. One possible solution is to add an entry to your hosts file or nameserver and point to an alternate server. Another method is to run a MITM attack on yourself and create a custom filter that alters the number of lives, number of max lives, and your immortal status. In case you haven’t noticed, it’s an encrypted request. So how would we bypass that? Well, ettercap can re-sign the packet with its own SSL cert (which would trigger a browser warning) but you can simply add the certificate to your exceptions list. All you need to do is edit /etc/etter.conf and uncomment the appropriate lines for your operating system. Since I am using Linux, I uncomment:

redir_command_on = "iptables -t nat -A PREROUTING -i %iface -p tcp --dport %port -j REDIRECT --to-port %rport"
redir_command_off = "iptables -t nat -D PREROUTING -i %iface -p tcp --dport %port -j REDIRECT --to-port %rport"

and I set:

ec_uid = 0
ec_gid = 0

The third thing I noticed while running a MITM attack on an Ipad was that the mobile app version does not use SSL when calling the API. That makes it even easier to hack than the facebook app.

Finally, the simplest way to hack Candy Crush (or any other Flash based software) is to tamper with the data in memory. There is a nifty little tool that you can use for this: scanmem. On Ubuntu, you can simply run
sudo apt-get install scanmem
to install it. To explain scanmem, it’s a dumbed down version of a hexadecimal editor that allows you to scan/locate/modify areas in memory used by a local process. It reminds me of the 90′s when I used to crack copy protection from video games armed with nothing but a debug and zipzap (or gdb and hexedit on linux). The reason why I say it’s dumbed down is because it does all the difficult tasks for you. I can walk you through the cheating process.
1) get the PID for your browser/flash player. If you use firefox: ps aux |grep flash should return the process ID.
2) run scanmem
sudo scanmem
3) select the process from scanmem’s prompt:
pid [process ID]

4) pinpoint the section of memory that contains the bit of data you are looking for. If you are trying to give yourself more moves on a certain level, take a look at the number of moves you have left, and enter it in the prompt. For example, if you have 30 moves left, enter 30 at the prompt. It will likely find way too many matches to be useful. But that’s okay because scanmem tracks each of these memory locations for you. Make another move on the game so you have 29 moves left. Now return to the scanmem prompt and enter 29. The number of matches will reduce. Repeat the process until it returns 2 matches. Now you’ve pinpointed it!
5) change the value in memory. At the prompt, you type:
set 200
and it will give you 200 lives.

6) reset scanmem. If you’re trying to track a different value or the number of moves on a different level, simply type: reset.

(before running the hack)

(after running the hack… note the number of moves left)

Yes. It’s that simple. Back in the 90′s, I would have a notebook full of addresses that I considered “areas of interest” and use the process of elimination to pinpoint the right value. *sigh. Kids these days have it easy. If you’re planning on hacking candy crush, this might prove useful:
- number of moves: 2 matches
- bomb timers: 2 matches per bomb
- score: 4 matches
- checklists: 1 match (but not the value they show you on the screen. The game shows you the number of matches you have left to pass the level. In memory, it is stored as the number of items you have already destroyed: [Number of items needed to pass]-[Number of items you have left])

Enjoy!

Say Hi To My Instagram Bots


I like Instagram. I can do a hashtag search of “chevy” or “silverado” and stare at trucks all day. The problem is, I don’t have the time. I wish I could be more active on Instagram, but that is a luxury I do not have. If only I could automate my Instagram activity…

If only…

Ha! Are you kidding me? You bet I can automate my Instagram activity!

I want to create a bot that searches specific hashtags and likes each photo. Instagram has a web interface for viewing profiles, liking, and commenting. However, it is limited because it doesn’t allow you to search hashtags. That’s okay though. There are several independent websites that utilize the Instagram API to allow users to browse Instagram photos online; I can just abuse one of those.

First, I needed to choose one of the several Instagram web viewers: web.stagram.com, webstagr.am, ink361.com, statigr.am, etc etc. I picked web.stagram.com because there is minimal ajax and that makes my life easier.

Next, I needed to do some http post/get recon work like I did for the Facebook bots. Firebug proves very useful here.

I decided to write this bot in Python using the pycurl library. It didn’t take very long to build (a couple hours while watching TV?). First I tried running it against these hashtags: “linux”, “silverado”, “chevy”, “z71″. The bot did what I expected and liked all of the photos I would normally like. Nice! But then I started getting a little greedy and wanted to engage a lot more Instagramers (instagrammers?). So I looked for a list of the most popular Instagram hashtags. Here is a snippet of the list:

1. #love (+) 100,106,232 photos
2. #instagood (+) 72,788,208 photos
3. #me (+) 56,885,413 photos
4. #cute (+) 53,136,368 photos
5. #photooftheday (+) 52,173,843 photos
6. #tbt (+) 51,407,782 photos
7. #instamood (+) 48,298,484 photos
8. #iphonesia (+) 40,101,981 photos
9. #picoftheday (+) 39,740,152 photos
10. #igers (+) 39,234,496 photos
11. #girl (+) 38,888,469 photos
12. #beautiful (+) 38,754,532 photos


If I run each of these hashtags through my bot, I can engage a LOT of people! So I did exactly that…

It worked well. A little too well. I took a look at the list of “photos I liked”. With no discretion whatsoever, my bot liked everything! Not only did it like photos of scantily clad women (oops?), but it liked photos of topless men (wth!), and photos of underage girls and boys (Yikes! Why the heck are you kids on Instagram?). Oops… I swear it wasn’t me! It was my bot!

Now I feel like a creep. If I keep running the bot, I suppose I can gain lots of new followers… but at what cost? Looking like a creep. Is it worth it? Maybe.

I invite you to check out the source code if you’re looking to build and study bots. Download from github. Please don’t abuse this bot. The truth is, I like Instagram and I don’t want it to be saturated with spammers.

Update:
Instagram didn’t find my bot too amusing. They disabled my account and removed all my photos. Yes, I have the the direct URI for some of my Instagram photos (on S3) and even those stopped working. So… just a fair warning: If you’re trying to run this bot to get followers, you may end up losing your account. I only ran this bot for a full 2 days (and I was gaining 1-200 followers a day) before my account was disabled.

So my @cranklin account is gone and I’m starting from scratch with @crankerson :(

My Nuclear Facebook Poking Bot





You can’t beat me in a Facebook poke battle. Here’s why…

I have been way too busy and it sucks. It sucks because:

Too much work means no free time
No free time means no time for fun little projects
No fun little projects means I go crazy
Going crazy means I can’t get work done

It’s a vicious cycle.

So what do I do while I suffer from coder’s block? I waste a good amount of time zoning out on Facebook.

The Conception

One of the most annoying Facebook features are the stupid/pointless pokes. After wasting a good 30 minutes on an intense back and forth poke battle, I decided it would be a good idea to make a poke bot. Can you imagine that? I could be drifting away in my swimming pool while my bots win all my poke battles for me!


The lack of enthusiasm only reassured my itch to build a nuclear facebook poke bot.

I have always shied away from making Facebook-related bots because Facebook works hard to prevent bots and I hear that Facebook bots are difficult to make. Oh well. Time to overcome my fears.

Hacking Facebook

First, I look at the Facebook page that gives me the list of all the people that poked me. That would be:
https://www.facebook.com/pokes?notif_t=poke
Next, I examine the “poke back” link. The links aren’t much help to me since Facebook “ajaxifies” the link. So, I fire up Firebug to examine the GET or POST requests my browser makes when I click “poke back”. Firebug reveals that it is a POST request to https://www.facebook.com/ajax/pokes/poke_inline.php with these parameters:


    __a = 1 
    __user = 556970868
    fb_dtsg = AQC_K43G
    nctr[_mod] = pagelet_pokes
    phstamp = 1658167957552517190
    pokeback = 1 
    uid = 1011739365

While logged into Facebook, I open up a new tab with a quick and dirty HTML form that posts to that URL with these parameters as hidden inputs. It works! Cool.

Next, I do the same Firebug probe on the homepage so I can find the necessary POST parameters to log into Facebook. To log into Facebook, Firebug shows me that I need these parameters:


charset_test    €,´,€,´,水,Д,Є
default_persistent  1
email   email
lgnjs   1352019805
lgnrnd  010313_fdAk
locale  en_US
lsd AVq9lE5u
pass    password
persistent  1
timezone    480 

Now, some of these values are dynamically generated, so the bot would first need to scrape and populate the post parameters before it can post. A similar process would be necessary to do the actual poking.

The Build

All I had left was to put it together. Here is the source code:

<?php
// your facebook credentials
$username = "email";
$password = "password";

// access to facebook home page (to get the cookies)
$curl = curl_init ();
curl_setopt ( $curl, CURLOPT_URL, "http://www.facebook.com" );
curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $curl, CURLOPT_ENCODING, "" );
curl_setopt ( $curl, CURLOPT_COOKIEJAR, getcwd () . '/cookies.txt' );
curl_setopt ( $curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)" );
$curlData = curl_exec ( $curl );
curl_close ( $curl );

// do get some parameters for login to facebook
$charsetTest = substr ( $curlData, strpos ( $curlData, "name=\"charset_test\"" ) );
$charsetTest = substr ( $charsetTest, strpos ( $charsetTest, "value=" ) + 7 );
$charsetTest = substr ( $charsetTest, 0, strpos ( $charsetTest, "\"" ) );

$default_persistent = 1;

$lgnjs = time();

$lgnrnd = substr($curlData, strpos($curlData, "name=\"lgnrnd\""));
$lgnrnd = substr($lgnrnd, strpos($lgnrnd, "value=")+7);
$lgnrnd = substr($lgnrnd, 0, strpos($lgnrnd,"\""));

$locale = substr ( $curlData, strpos ( $curlData, "name=\"locale\"" ) );
$locale = substr ( $locale, strpos ( $locale, "value=" ) + 7 );
$locale = substr ( $locale, 0, strpos ( $locale, "\"" ) );

$lsd = substr ( $curlData, strpos ( $curlData, "name=\"locale\"" ) );
$lsd = substr ( $lsd, strpos ( $lsd, "value=" ) + 7 );
$lsd = substr ( $lsd, 0, strpos ( $lsd, "\"" ) );

$persistent = 1;

$timezone = 480;

// login to facebook
$curl = curl_init ();
curl_setopt ( $curl, CURLOPT_URL, "https://login.facebook.com/login.php?login_attempt=1" );
curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $curl, CURLOPT_POST, 1 );
curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt ( $curl, CURLOPT_POSTFIELDS, "charset_test=" . $charsetTest . "&locale=" . $locale . "&email=" . $username . "&pass=" . $password . "&lsd=" . $lsd . "&default_persistent=" . $default_persistent . "&lgnjs=" . $lgnjs . "&lgnrnd=" . $lgnrnd . "&persistent=" . $persistent . "&timezone=" . $timezone);
curl_setopt ( $curl, CURLOPT_ENCODING, "" );
curl_setopt ( $curl, CURLOPT_COOKIEFILE, getcwd () . '/cookies.txt' );
curl_setopt ( $curl, CURLOPT_COOKIEJAR, getcwd () . '/cookies.txt' );
curl_setopt ( $curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)" );
$curlData = curl_exec ( $curl );
//echo $curlData;


// enter infinte poke loop
while(true){
    $curl = curl_init ();
    curl_setopt ( $curl, CURLOPT_URL, "https://www.facebook.com/pokes?notif_t=poke" );
    curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
    curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt ( $curl, CURLOPT_ENCODING, "" );
    curl_setopt ( $curl, CURLOPT_COOKIEFILE, getcwd () . '/cookies.txt' );
    curl_setopt ( $curl, CURLOPT_COOKIEJAR, getcwd () . '/cookies.txt' );
    curl_setopt ( $curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)" );
    $pokeData = curl_exec ( $curl );
    //echo $pokeData;

    preg_match_all("/<div class=\"pokeHeader fsl fwb fcb\"><a href=\"(.*?)\" data-hovercard=\"\/ajax\/hovercard\/user.php\?id
=([0-9]*)\">([^<]*)<\/a> has poked you.<\/div>/",$pokeData,$matches,PREG_SET_ORDER);

    if(sizeOf($matches)){
        $userid = substr ( $pokeData, strpos($pokeData, "\"user\":") + 8);
        $userid = substr ( $userid, 0, strpos($userid, "\""));

        $fb_dtsg = substr ( $pokeData, strpos ( $pokeData, "name=\"fb_dtsg\"" ) );
        $fb_dtsg = substr ( $fb_dtsg, strpos ( $fb_dtsg, "value=" ) + 7 );
        $fb_dtsg = substr ( $fb_dtsg, 0, strpos ( $fb_dtsg, "\"" ) );

        //echo $userid." ".$fb_dtsg;
        
        foreach($matches AS $val){
            //echo $val[0]."\n";
            //echo $val[1]."\n";
            //echo $val[2]."\n";
            $uid = $val[2];
            $curl = curl_init ();
            curl_setopt ( $curl, CURLOPT_URL, "https://www.facebook.com/ajax/pokes/poke_inline.php" );
            curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 );
            curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
            curl_setopt ( $curl, CURLOPT_POST, 1 );
            curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, false );
            curl_setopt ( $curl, CURLOPT_POSTFIELDS, "__a=1&nctr[_mod]=pagelet_pokes&pokeback=1&__user=" . $userid . "&fb_dtsg=" . $fb_dtsg . "&uid=" . $uid);
            curl_setopt ( $curl, CURLOPT_ENCODING, "" );
            curl_setopt ( $curl, CURLOPT_COOKIEFILE, getcwd () . '/cookies.txt' );
            curl_setopt ( $curl, CURLOPT_COOKIEJAR, getcwd () . '/cookies.txt' );
            curl_setopt ( $curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)" );
            $pokeresults = curl_exec ( $curl );
            echo "You poked ".$val[3]."!\n";
            //echo $pokeresults;
        }
    }
    empty($matches);
}
?>

Download my nuclear poke bot from git


Let me tell you, this bot is fast and obnoxious! Unlike the other lame poke bots you may find, this one is fast, it’s standalone, and it runs via command line. It will keep checking your poke notifications page. If somebody pokes you, it will immediately poke them back and notify you of whom you poked. I left it running all day. When I checked my computer and looked at the logs, I was able to see which of my poor friends were tenacious enough to put up a fight.


If you see this, it means you’re screwed.

Looking ahead… A simple alteration will allow me to poke bomb ALL of my friends. I may write a Python version, install it on my raspberry pi, and carry around a portable nuclear poking machine. :)

In the end, was the 2 hours spent on developing this bot a waste of time? No. It was just what I needed to pull me out of this coding slump. Plus, I can now outpoke ANYBODY. :)

Winning!

Hacking Into That Security Camera!

I had the pleasure of working at LaunchPad LA because of Triptrotting. In case you’re unfamiliar with Launchpad LA, it is a startup accelerator and mentorship program founded by Mark Suster.

One day, while I was at Launchpad…
I was staring at code too long, so I leaned back in my chair to rest my eyes. I zoned out for a moment and focused on a wireless DLink IP security cam that Kyle Taylor had set up.



Hmmm…. I wonder if I can hack into that thing.
I glanced over at Shawn Faison and said, “Hey Shawn, wanna race to see who can hack into that security camera first?”
Shawn is a fun guy and he loves a challenge, so naturally, he accepted. I later extended the challenge to Philip Hayes (a talented young programmer). Why am I so fascinated with security cameras at incubators? Lol.

First, I had to find the IP of this camera.
I started with a ‘ping -b’ to the broadcast IP followed by an ‘arp -a’. Yup… this router started listing out all the names of all the devices connected to the network along with the associated IP address. I saw names of peoples’ computers, iphones, ipads…. but no security camera.

Next, I ran a ‘nmap -sP 192.168.1.*’ to see a list of IP’s. With the help of nmap I narrowed down my search to just the IP’s with port 80 or 8080 open.
I tried entering each of these IP’s in my browser to see what showed up…. and there it was. A HTTP AUTH protected webpage that was titled “DLink DCS-932L”. But wait, there were 2 different IP’s that had DLink HTTP AUTH protected pages. I started looking around and noticed a second IP security cam! I never noticed that 2nd one before.

Okay, found the cameras. If by any chance the cameras kept the default passwords, all I would need to do is search online for a manual and try the default credentials. Nope. Didn’t work.

Now, I could technically perform a man-in-the-middle attack on Sam Teller or Kyle Taylor and wait for one of them to log into the camera feed and simply intercept the password…. But that is just plain wrong and against the spirit of this friendly competition. So I wrote a HTTP AUTH brute force cracker script. Believe it or not, I couldn’t actually find one online besides dictionary attack scripts. So here is my contribution to the script kiddies of the world:

Download from github

I let my script run for just a little while before I stopped it. It would take too long and I’m pretty certain Kyle picked a crazy long upper/lowercase alphanumeric + symbol password which I really didn’t want to bother cracking. The whole point of this exercise was to learn and have fun.

So in the end, while I got closest, none of us actually hacked into the Launchpad LA security cams. Important lesson for you readers: USE crazy long upper/lowercase alphanumeric + symbol passwords!

Good job Kyle Taylor. You win this one… you win this one… *evil grin.

My Experimental Doorbell

My doorbell is old… it’s ugly… it’s disconnected… it deserves an upgrade.



(It says “live better electrically”. What is this? The ’60′s?)

So I went on amazon.com to browse through doorbells, but I was a little disappointed. Something bothers me about their selection of doorbells. They’re archaic. Yes. I want to build my own “different” kind of doorbell.

Here are the features I want:

- No buttons. I want it to be fully motion sensored.
- Voice greeting. I want Jarvis to greet the visitor.
- Voice alert. I want Jarvis to notify me (inside the house or wherever I am) that somebody is at my door.
- Logging. I want Jarvis to log and timestamp every time I have a visitor. On top of that, I want Jarvis to store snapshots of the person that’s at my door.

THAT is what I want to see in my doorbell.
So… Let’s make this happen.

First, I need a PIR (passive infrared) motion sensor.

Now take my word for it, this is one of the FEW times where something is actually cheaper at Radio Shack than ebay. No joke. At best, you’ll find the same PIR module at a similar price.

PIR sensors are great for projects that require motion detection. They are great for alarm systems, automatic lights, doors, urinals…. NOT bowl toilets. I repeat, they are terrible for sit-down toilets. I don’t understand why toilet manufacturers STILL use them. It flushes while you’re trying to lay sheets of toilet seat cover, and it doesn’t flush when you want it to.

PIR modules are very easy to use. The latest ones from parallax (the ones they sell at radio shack) output 5v upon movement. This means you can use it to power something small without a microcontroller and/or transistor.
In my case, I want it to activate a voice recording.

Second, I need a way to play back recorded voices.
In my previous projects, I used a piezo transducer to produce sounds… but those are limited to beeps. Making your arduino play recorded sounds, voices, and or music is a bit trickier. The easiest way to accomplish this is to use something like an arduino “wave shield”.

These are sold on ebay for about $20. I just need to plug a speaker into the wave shield so visitors can hear Jarvis’ friendly voice.

The other components I will need include an arduino ethernet shield, a surveillance camera, and Jarvis of course.

This is how my “doorbell” will work:

1) PIR sensor detects motion.
2) Did it already detect motion? If so jump back to 1. Otherwise, go to 3.
3) Trigger pre-recorded voice of Jarvis on wave shield that says “Hello. I am notifying my master that you are here”.
4) Make a call to the doorbell server API and let it know that I have a visitor.
5) Server takes a feed off the front door surveillance cam and creates a snapshot image.
6) Server takes that snapshot image and converts it into a base64 encoded dataurl so we don’t have to store the image as a file.
7) Server logs that data and timestamps it.
8) Meanwhile, Jarvis is polling the doorbell server via ajax requests.
9) Does Jarvis see new visitor data? If so, alert me with “You have a visitor” and show me a snapshot from my front doorstep on my screen.

Piecing it together


I stacked the ethernet shield on top of the arduino, and I stacked the wave shield on top of the ethernet shield.
I only needed 3 wires: +5v, gnd, and digital pin 4. All of which goes to the PIR sensor.

You can view the arduino source code here.

I ran a few tests which proved to be successful.



and a closer look at Jarvis when she alerts me of a visitor:

Here is a video of my prototype doorbell in action:

Cool! All I have to do now is install it! On second thought, I’m probably going to wait for the weather to cool down. Running wire through the baking hot attic in the summertime does NOT sound fun.

Follow

Get every new post delivered to your Inbox.

Join 1,443 other followers