Sunday, December 26, 2010

Christmas Advertising Adventure

A few years back I ran a small advertising campaign on Facebook and in an attempt to recover my business Facebook graciously gifted me USD50 of advertising credit. Unfortunately I didn't have any goods or services that I wanted to advertise just then so I figured that I'd have to get creative.

Unsurprisingly Facebook advertisements are boldly commercial and quite direct in what you will get out of clicking on them, part of this is inherent in commercial advertising but a large part of it is the Facebook Ads style guidelines and approval processes which help to minimise misleading adverts and the most egregious punctuation and spelling offences. For example looking at Facebook right now I see an advert that starts "Hair removal for MEN" and besides from the capitalisation problem the advert is well formed. It contains three more or less well structured sentences telling me what the product is, what it does and why I need it. This is a clear and direct message that probably works quite well. This advert is emblematic of the Facebook advertisement I see and they lead to easy to understand but blunt advertisements.

I was wondering what I could offer up that might be of use, interesting or at least amusing. I thought for a while and came up with a sort of mild anti-commercial. An advert that refuses to market at the viewer and does not event request any action from them. Perhaps something different enough that people will notice it and it give them pause, a respite from the marketing that bombards a modern consumer day and night.

This is what I came up with:
The title "This in not an advert" is a bit of a reference to RenĂ© Magritte's The Treachery of Images chosen because my advertisement is not really an advertisement but merely an image of one. The rest of the copy I just bashed out in an attempt to intrigue the reader and convince them that I was not selling anything. The link if you click on it takes you to http://arkem.org/ad.html which is basically the same thing. The advert was primarily designed to amuse me rather than to actually be a communication tool or even art and I think it has succeeded quite nicely.

When I submitted the advert I was briefly worried that it would not get approved but my worry was unfounded. The approval process is there to weed out the most egregious style violations as well as misleading and offensive material and so I was fine. The ad went live about an hour after submission and has been on it's merry way. I targeted the advert at people over 18 years of old that are in the country that I am currently living in (for an interesting comparison I'm going to remove that targeting after I post this) and I asked to be billed per impression rather than per click since I was not actively encouraging people to click on the advert. As I understand it, if you pay per click your click through rate becomes an active component of how often your ad is displayed. I chose the upper bounds of the recommended bid and set a maximum of USD1.04 for 1,000 views and a maximum of USD45 for the entire campaign (my voucher got diminished somewhat by taxes). After 10 days the advert has been viewed almost 80,000 times and clicked on 10 times for a total cost of USD25.83 and an average cost per 1000 impressions (CPM) of USD0.33.


Now I'm going to fiddle with the settings a little bit and see how that effects performance.

Update 4th January 2011: US$45 purchased 120,247 impressions and 30 clicks over about 17 days. CPM was USD0.37 and CPC was USD1.50. The CPC would probably be lower (and clicks higher) if the advert invited the user to click.  

Friday, December 24, 2010

Happy Birthday Meme Over!

This blog has made it to 1 year old and while it's been quiet of late there'll be some new content coming soon.

Posts to look forward to:

  • The latest on my Xbox 360 Forensics research
  • A very simple password generator that can talk to random.org for entropy
  • My Christmas advertising adventure
  • For the first time my 5 and a half year old undergraduate research will see the light of day
  • Facebook Puzzles!
  • Other random thoughts as I have them

Monday, July 26, 2010

Updates: The Middleman and Talk Like Warren are now secure-ish!

To bring @FakeMiddleman and @TalkLikeWarren in line with upcoming Twitter API Changes that will disable basic auth support and require people use OAuth to authenticate to the API.

Unfortunately the version of Mike Verdone's Twitter Tools I have doesn't support OAuth so I ended up switching to Tweepy which is a bit more heavy duty. Along with OAuth support Tweepy supports the Twitter Streaming API which allows you to get real time timeline updates. OAuth is more complicated than Basic Auth but is way more secure. Twitter has provided a nice document explaining the basic concepts behind OAuth and how to transition away from Basic Auth.

Let me segue and present the 30 second Tweepy and OAuth tutorial:

  1. Go to http://twitter.com/apps and fill in the form
  2. Choose 'Client', 'Read & Write' and 'Yes, use Twitter for login'
  3. Take note of the Consumer key and Consumer secret
  4. easy_install tweepy
  5. wget https://raw.github.com/tweepy/examples/master/oauth/getaccesstoken.py
  6. python getaccesstoken.py
  7. Take note of the Key and Secret value
Now here's a helloworld OAuth app with tweepy:

import tweepy
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(TOKEN_KEY, TOKEN_SECRET)
api = tweepy.API(auth)
api.update_status("I CAN HAZ OAUTH")


The new Twitter dev site is cool http://dev.twitter.com it has various bits and pieces including Twitter API Status which gives you the status of various API calls, their performance and uptime as well as service announcements. Even cooler is the Twitter API Console which is a nice simple place to give the Twitter API a test drive.

For those interested here is the updated code for @FakeMiddleman and @TalkLikeWarren

Thursday, June 17, 2010

Published!

Just a quick note to say that my paper "Twitter as a Vector for Disinformation" was published in the Journal of Information Warfare last month. This is my first academic publication and I'm very excited about it. The paper is also available right from this very blog!

Wednesday, June 16, 2010

The Origin of the Species


I finished Dinosaur Island managing to exceed the score required to 'win'. Silliosaurus, most majestic of the Imbecephalosaurians thrived on Dinoisland unperturbed by the predators and rocks and only occasionally abandoning their herbivorous tendencies to engage in cannibalism (5th on the high score chart with 315,000 points). This success lead to overpopulation which created an evolutionary pressure that spawned Crazyodon which rose to a level of glory only seen by 3 previous species (4th on the high score chart with 895,750 points).

The breakthrough came when I realised that you could not convert a column, row coordinate system to an (x, y) without first accounting for the fact that in a column row system the direction 'UP' or 'NORTH' corresponds to the negative direction rather than the positive. This wasn't an easy mistake to spot because the column part worked flawlessly and my interface was consistent so the only visible symptom was that plants rarely were where Silliosaurus thought. 

After that bug got straightened out Silliosaurus flew past the 100,000 points required to win but managed to show an alarming tendency towards cannibalism. When two Silliosaurs collide one will die and since they are herbivorous the surviving dinosaur would not gain any calories. Since a new born Silliosaur would start adjacent to its parent and they shared the same path finding algorithm they often collided while hunting the same piece of food. My first attempts at fixing the problem didn't help all that much, I introduced a factor into the decision making code that would make food regions that contained another Silliosaur or that another Silliosaur was moving into less attractive. This factor was just a negative weighting that subtracted a value from the expected profit calculation that I hoped would encourage Silliosaurs to spread out. It did help but not a lot and increasing the weighting over and over didn't improve things a lot. This is when Silliosaurus plateaued at around 300,000.

I decided that I'd need some drastic changes to head off this problem and forked Silliosaurus to create Crazyodon. Crazyodon uses a prescriptive model where there is a strict set of criteria that a plant has to pass before even being considered for its food value. A Crazydon will mark its favourite unclaimed plant and all the plants within a given radius of it off limits to other Crazydon. This had a much more dramatic effect leading to a diverging behaviour where two Crazydons would often go in completely opposite directions. This didn't fix the problem entirely because only destinations were being considered rather than paths so two Crazyodons would still sometimes collide on their way to different regions. This didn't faze me too much as Crazyodon far exceeded my performance expectations and would even lead me to revising my graphical interface.

Crazyodons were so fecund and so good at roaming that they would often leave my (admittedly small) display area. I tried a few automated routines that would progressively zoom out the view when objects were detected outside the bounds. This actually was quite easy to do with pygame but I couldn't find a solution that I was happy with. In the end I implemented proper keyboard event handling to allow the user to pan the screen as well as zoom in and out. Very fancy.

Right now I think I'm dinosaured out for the moment but I hope in a few weeks I might get enthused about creating a carnivorous dino. In the mean time I'm turning my attention back to Xbox 360 forensics.

P.S The Crazyodon run I did to generate the above screenshot ended up scoring 827,000 points and took as long to run as writing this blog post did. Full screenshot here.

Sunday, June 13, 2010

Dinoisland and pygame

Facebook has a series of puzzles they use to evaluate potential engineering employees or for the enjoyment of anyone curious. I've worked through quite a few of them and in the process learnt that I really need to brush up on my algorithms.

At the moment I'm working through Dinosaur Island which is an AI exercise which surprisingly is about dinosaurs on an island. You need to create an AI that pilots a species of dinosaur to prosperity on the island, either a herbivore dodging nasty carnivores to get at tasty foliage or a species of carnivores hunting down everything that moves. The environment is persistent and multiplayer so it's almost like a little Dino-MMO.

Interactions with the server are done via the Apache Thrift RPC framework, where each action that your dinosaur can take is an RPC method. Your dinosaur has a limited life span so after avoiding predators and starvation your dinosaur needs to reproduce (apparently asexually) to prolong the species. The species itself has a limited life expectancy after which an extinction event kills all your remaining dinosaurs ('rocks fall everybody dies'). Every action that your dinosaur takes costs calories (move, look, grow, reproduce) and takes a turn, you get calories by eating ('moving into') stuff. This is important because it means that during a turn your dinosaur can either look in a direction OR move in a direction.

I'm currently working on a species of herbivore I call 'Silliosaurus' which fairly naively hunts out the densest areas of foliage to eat while only spending a cursory amount of time avoiding predators. To 'win' your species needs to score 100,000 points (which I think you accumulate mostly by eating stuff) and there's a leaderboard. Currently Silliosaurus is averaging less than 10,000 point a run with a current best of 25,000 points or so. The main flaw seems to be that Silliosaurii move into a square expecting to eat something only to find it empty and sometimes expects to move into empty space and accidentally acquires a cornucopia of vegetation. This makes me think that there's a problem with how I process and store sight information but I haven't tracked it down yet.

In the process of debugging Silliosaurus I wanted to build a graphical representation of Dinoisland to help me visualise the behaviour of each Silliosaur. I ended up using pygame which is a python game development library the wraps SDL. Pygame is total overkill for my needs but turns out to be dead simple to use. In fact below is a slightly simplified sample of what it takes to draw the screen visible in the attached screenshot:

import pygame


pygame.init()
screen = pygame.display.set_mode((800, 800))
pygame.display('Dinoisland: Silliosaurus')
plant = pygame.Surface((10,10))
dino = pygame.Surface((10,10))
bg = pygame.Surface((self.screen.get_size()))
plant.fill((0, 255, 0))
dino.fill((0, 0, 255))


screen.blit(bg, (0, 0))
for location in plantlist:
    screen.blit(plant, location)
for location in dinolist:
    screen.blit(dino, location)
pygame.display.flip()


So while Silliosaurus still wanders about lost and confused, occasionally starving to death or eaten by a Daisyysaurus, I have learnt a valuable lesson about how to create quick and easy graphics.


P.S Here's a link to the full sized screenshot

Thursday, May 27, 2010

Capture the Pequod

Last weekend I distracted myself from my university work by competing in ddtek's Defcon CTF quals. It was a bunch of fun and I recommend that everyone gives it a go. A good place to start if you're not sure what I'm talking about is over at wikipedia: Capture the Flag. Defcon CTF is played by teams of 5-6 people who spend the weekend trying to solve puzzles ranging from binary reverse engineering, exploit development, disk forensics, cryptanalysis to random trivia. Since I was playing on a team of 1 I mostly stuck to the "Pursuits Trivial" category which is a grab bag of trivia based puzzles. This worked out well since I managed solved all but the hardest one which I was working on when time expired.

Here's a quick run down of the problems that I faced:

Pursuits Trivial 100
This was very straight forward, the question was "What linux command was mentioned in the Spiderman movie". I didn't know the answer off hand so I googled it and it turns out someone had set up a StackOverflow.com question and someone had posted the answer: "sudo". Well that was an easy start, pity it wouldn't continue.

Pursuits Trivial 200
The 'question' was "sheep@pwn21.ddtek.biz:6000 sheep go baaAaaA"

This was a bit cryptic but not too terrible as you'd discover if you try and ssh to sheep@pwn21.ddtek.biz:6000. The next step was to figure out the password which wasn't much of a stretch either "baaAaaA" being the first thing you're likely to try. This is where it gets tricky however, you find yourself at a blank screen and typing doesn't seem to do much. I must admit that I quickly grew bored of this question and moved on to the next one but later I came back. Due to some lucky keyboard mashing I ended up hitting 'i' and then some other characters and saw that my cursor moved, after that I tried it again with a ttyrecorder in place and found out that when you press 'i' you get the text "INSERT MODE" back just not legibly. So we were inside vim but with the colours messed up, a bit of Googling turns up the command "hl clear" that reset the colours back to normal. Unfortunately you can't quit vim and it didn't look like you could write files anywhere and you couldn't shell out to regular commands. What you could do is to open a directory (I used the 'open ../' command) and start navigating the file system. From there you quickly find /home/sheep/key and find the passphrase you need to score 200 points. Wasn't that fun?

Pursuits Trivial 300
Question "Vulcan needs more friends" and a link to a site that asks you for a Facebook username, a Flickr account and a Twitter account. Vulcan is the name of one of the organisers at ddtek and it looks like you need to hunt him down on some social networks. This wasn't actually too hard, it took a little bit of creativity at times as often there was an account called "ddtek" but it wasn't a user but a group and you have to look around to see if someone called Vulcan had friended the "ddtek" group. The hardest part was convincing the script that you actually had found Vulcan, the twitter part was especially finicky.

Pursuits Trivial 400
This one was great fun. The question is something like "Rank these hackers" with a link to a file. The file turns out to be a java app that when run shows you two photos of hackers and asks you to pick one (first time I got Halvar Flake and The Dark Tangent) and if you choose correctly it will show you two more faces but if you choose incorrectly the program exits. Since I didn't recognise most of the faces and there was no way to know the ranking system I figured I would have to find some other advantage. At first I started pulling apart the network traffic to see if any hints were being sent over the wire, there weren't any that I could see but the protocol itself looked pretty straight forward. The client says "illogical\n" to start and then receives two jpegs each XORed with a different constant and then if the client wants to pick left it sends 0x00 and if it chooses right send 0x01 (I didn't look into figuring out how the server tells the client which constant to use, I figured I could just brute forced it). If the client guesses wrong a 4 byte error code is sent and the socket closes.

I figured that this was all simple enough and wrote my own client f400.py (named f400 because I for some reason was confused with the forensic problems). My client would slowly accumulate knowledge about which hackers were superior to which by playing the game over and over. I also would dump a copy of the images sent as well as the entire network exchange to disk for later analysis. Once that was working I left it to run overnight (it didn't need to run nearly that long but it was late and I need sleep) and in the morning I had a pickle file with a list of images in order and wrote another script (f400_sort.py) that would give me a nice set of jpegs named in numerical order from 001.jpg out to 080.jpg or so. I then played the game manually consulting my list to make the choices. After 64 correct choices the game did something different, it asked me to tell it what path I took in the format of "LRLRLRRRRLRLRR...". At this point I was a little over the problem and instead of coding the solution just ran through it a second time recording my decisions manually.

Looking back at the problem there are several improvements that I could have made. Firstly I could have reversed the java application so that I didn't have to guess at the protocol, I could have either derived it from the code or skipped writing my own client and just modifying the existing one. Secondly my network code was a bit naive and used sleeps and assumed that all the data would be ready to read (perhaps one part of the protocol I didn't analyse was a length field?) and I ended up with an occasional malformed file which I just lived with. I should have used PIL  or similar to detect broken or truncated images. Finally I shouldn't have wimped out and I should have had my client play complete games rather than not knowing what to do after 64 correct guesses.

T400 was a blast but that brings us to T500

Pursuits Trivial 500
Time was called while I was working on this problem and I was mostly just poking around rather than actually trying to solve it. The question was "Tell me about your appendage" and there was a file. The file turned out to be an APE format lossless audio file that I had no idea how to play. I eventually decoded it to wav and listened to it. A bit of Googling on lyrics later made realise that it was a modified version of Captain Ahab's song Ride. I won't go any further, I'll instead direct you to this excellent write up of the puzzle by Scott Wolchok http://scott.wolchok.org/t500.html. First though I insist you listen to the song yourself by playing the youtube video below. It has unicorns.

Tuesday, May 25, 2010

Xbox 360 Forensics

Lately my blogging energies have been redirected into my study, namely a communications plan and a research proposal.

The communication plan was for a persuasive communications class and the aim was to be able to devise a plan that could realistically alter the attitudes (and hopefully the behaviour) of an audience, it was a fascinating exercise that I don't plan on repeating any time soon. It turns out that I'm not much of a public relations hand and while I think I grasped the theory writing up a viable strategy for a hypothetical situation was harder than I expected.

More relevantly the research proposal is for my upcoming final project (dissertation?) and it involves creating a tool to automate the extraction of useful information from an Xbox 360. Seriously I didn't come up with the topic —my supervisor suggested it— isn't that awesome? So I've been spending a lot of my time reading xbox modding forums and reading the few bits and pieces in academia on the topic.

Things that I learnt:

  • The xbox 360 is easier to access than the original due to a lack of ATA security lock down
  • There is an xbox file system that is mostly just a clean up of FAT
  • The xbox 360 uses a big-endian version of this operating system due to its PowerPC architecture
  • People go to great lengths to install homebrew operating systems and play pirated games
  • There is a lot of information that might be accessible via someone's xbox
  • Most Windows users use a defunct program called Xplorer360 to read/write to xbox 360 file systems
  • For Linux the choices are a BSD example implementation uxtaf.c or x360 a GPLv3 FUSE driver
  • Actually there's a kernel driver available too if you're into that kind of thing
So next semester I'm going to be messing around with a whole bunch of xboxes, it's amazing what you can do and still get course credit. I'll keep you all updated as it unfolds.

In the mean time, watch this Google Tech talk about the Xbox and Xbox 360 security systems:

Wednesday, April 28, 2010

Boring Admin Post

At some point in this blogs history I started thinking of it as "Meme Over" rather than "Meme Overload". To reflect that I've moved the blog to memeover.arkem.org. I've pointed memeoverload.arkem.org at an apache server I control and serving up permanent redirects for your convenience. This means you can completely ignore the change if you'd prefer. This may not be the last time I mess with the site on a whim but I will always attempt to maintain transparent backwards compatibility.

Sunday, April 25, 2010

Destroying community in MMORPGs

I came across a very interesting paper this morning, Destroying community in MMORPGs: How groups are undermined by Barnes it discusses the nature of MMORPG guilds/communities and how they react to attack. The paper proposes that all the members of the community are connected together by at weak bonds but that certain subsets of the community are connected together by strong bonds. When attacked the communities will fracture into the component cliques that have developed strong bonds. The paper is online as part of Curtin University School of Internet Studies' Online Conference on Networks and Communities along with a whole lot of other interesting stuff. Incidentally the Barnes paper cites my Information Operations in and around EVE Online paper which is exciting, especially since I haven't published that paper anywhere except on this blog.


In other news my Twitter as a Vector for Disinformation paper has been accepted for publication in the Journal of Information Warfare's next issue. Once it's released I'll replace the draft that's available here with the final copy. 

Monday, March 15, 2010

The Middleman knows your name!

I modified @fakemiddleman so that some quotes can contain place holders to be filled in while running. The only one that I've implemented is a name token that gets replaced with the screen name of someone who follows @fakemiddleman. The code for creating a list of all the users that follow you was new to me and I thought I'd post a version of it here as an example. The function returns a random follower and rebuilds the list of followers any time the number of followers that the user has doesn't match the length of the local list. The list is built by paging through http://api.twitter.com/statuses/followers.json with a cursor. The cursor is required for long lists of followers since there's a maximum number of records that will be returned on each request.

import twitter, random

FOLLOWERS = []
def get_name():
    global FOLLOWERS
    api = twitter.Twitter("user", "pass")
    num_followers = api.users.show(\
                      screen_name =\
                      'fakemiddleman')
    if num_followers != len(FOLLOWERS):
        FOLLOWERS = []
        next_cursor = -1
        while next_cursor != 0:
            res = api.statuses.followers(\
                    screen_name='fakemiddleman',\
                    cursor=str(next_cursor))
            for u in res['users']:
                FOLLOWERS.append(u['screen_name'])
            next_cursor = res['next_cursor']
    if len(FOLLOWERS) == 0:
        return "Dubbie"
    return random.choice(FOLLOWERS)


P.S Does anyone know a good way to format code snippets for posting on a blog?

Sunday, March 14, 2010

@fakemiddleman

Just a quick note about my latest twitterbot. I was watching The Middleman and found that the longer I watched the more I started sounding like the Middleman. To preserve the good will and sanity of   my friends I've decided to externalise my quote making by creating @fakemiddleman a twitterbot that every couple of hours will regurgitate a piece of the Middleman's genius.

I won't bother posting the code since it's just a simplified version of @talklikewarren which I discuss the design and provide the code for here. The data source is just a flat text file of quotes grabbed from Wikiquote and some episode transcripts I found on the web.

I'll try and make my next twitterbot more useful or have some other clever characteristic that makes it more worth a blog post. In other news I have about 4 or 5 blog posts worth of material in my notes and they'll be up as soon as I sit down and start writing.

Wednesday, February 3, 2010

Twitter, Code and The TripleJ Hottest 100 of 2010

Australia Day was last week and that means the Triple J Hottest 100. Not being in Australia at the moment I was hoping to listen to the Internet stream but after some initial success ran into some problems. I suspect that the unprecedented interest in the voting for the hottest 100 translated into unprecedented traffic.

This was an emergency, how could I celebrate Australia Day with out the hottest 100?

Clearly, this called for some hackery. Time was running out, we were already 10 songs in.

I noticed that the list was being tweeted via @triplej and I remembered that youtube has everything. Inspiration! I picked up some code I had lying around — my various twitter projects and some code from a friend that would pipe youtube audio tracks into mplayer — and started copy, pasting and hacking. Another 5 songs passed and I started debugging, 5 more songs and I had it working. The result would check Twitter every 30 seconds or so looking for new songs, next a youtube search for the new song's title and then open a new browser tab with the highest ranked search result.

The pros:
- The hottest 100 as a music video marathon!
- No interruptions, no stopping for phone calls to drunken Australia Day parties

The cons:
- Occasional silence between songs while the DJs talk
- A new browser tab for each song (having to close them all kind of sucked)
- In one case the song wasn't in the top page of results "Friend in the Field" by Art vs. Science.
- Not a general solution, only worked during the hottest 100.

If I didn't pull this together over 30 minutes or so I would have done it differently, maybe as a bit of javascript that messed around with the src of an iframe (or embed tag) based on the output of an AJAX query to the twitter components.

A link for anyone who's curious as to how the hottest 100 turned out.

Saturday, January 16, 2010

Talk Like Warren Ellis (@talklikewarren)

I am a fan of author Warren Ellis. He writes comics like Doktor Sleepless (see left) which has some interesting information warfare themes along with mad science and you should all check it out. Doktor Sleepless incidentally, is where I stole the cool warning signs that grace my first couple of entries here. Warren Ellis is a strange, strange man. He has a very popular twitter account (over 300,000 followers) where he does the usual twitter things but in addition he makes exclamations like "Good morning lovemaggots" and "ATTENTION SCUM: You’re obviously all terrible people".

Scott Vandehey and Miles Johnson were so thrilled by these exclamations they decided to see if they could recreate Warren Ellis like sayings programmatically. Thus talklikewarrenellis.com was born, it's a nice simple web site that will give you a Warren Ellisesque exclamation every time you visit, it'll even give you a link to a screen reading service that will pronounce it for you. The magic that powers this is a Warren Ellis grammar that was created using an inverse parser on a large set of Warren Ellis' exclamations. To the right is a graph for an Extended Backus-Naur Format grammar. The whole thing is really interesting and you should go to Miles' blog and read about it here.

I was so impressed that I decided that I wanted a mechanism that would occasionally show me one of the generated exclamations. I decided that twitter would be a good vehicle and wrote a little script that would scrape an exclamation and post it to @talklikewarren. Here's the code:

#!/usr/bin/env python
import twitter, urllib2, time, re, random
random.seed()

while (True):
    try:
        page = urllib2.urlopen('http://talklikewarrenellis.com/').read()
        post = re.search("<h1>(.*)</h1>", page, re.M).group(1)
        print post
        api = twitter.Twitter("USERNAME", "PASSWORD")
        api.statuses.update(status = post)
        print "success"
    except Exception:
        pass
    sleepinterval = random.randrange(30,6*60)
    print "Sleeping for %d minutes" % sleepinterval
    time.sleep(60 * sleepinterval)
 
Obviously this snippet isn't ground breaking but I wanted to post another example of using Mike Verdon’s Python Twitter Tools.

Wednesday, January 13, 2010

Google and China



Google has had some trouble in China and is reconsidering their operations there.
Google: A new approach to China

Secretary of State Hillary Clinton has commented on the situation.
Statement on Google operations in China

Fascinating stuff. It's especially interesting that Google compares the attacks to the GhostNet incident and refers people to Northrop Grumman's report on the People Republic of China's Cyberwarfare capability.

Yes, this is 24 hours old which in blogosphere time is like a month but I thought to post it anyway.

Sunday, January 10, 2010

twitbot 0.1


Sometimes I end up in conversations with people that leave me with an undeniable urge to prove my point, generally only to myself. Last April I had a conversation along these lines that left me writing a piece of "malware" that communicated via Twitter and since by the time I'd finished the conversation was no longer relevant and so I just let it sit there. Later last year I wrote a paper about Web 2.0 and malware and so I dusted it off and decided to share it with you. Feel free to use the code for whatever, it's a nice basic example of programs passing information to each other via Twitter. Don't use it as is as the authentication/security model is plain bad and this would be perhaps the worst remote administration tool you could think of!

twitbot.py searches twitter for interesting posts and if it finds one it will decrypt and execute it then sleep n seconds.

twitcontrol.py takes a time offset (0 is fine) and a command line, it will encode these and post them to the configured twitter account.

Here's how it works:


Twitbot Main loop:
     Generate tag from tag key
     Search for Twitter posts containing tag
     For first matching post:
          Decrypt payload string with message key
          Execute payload string in shell
     Sleep

Twitcontrol Algorithm:
     Generate tag from tag key
     Encrypt message with message key
     Post message and tag to Twitter

Simple Tag Generation:
     MD5 hash the tag key
     Truncate hash to designated tag length – 1

Dynamic Tag Generation:
     Calculate seconds since 01/01/1970 0000 UTC
     Truncate value to 7 most significant digits
     MD5 hash value and tag key
     Truncate hash to designated tag length – 1

Message Encryption:
     MD5 hash message key to create cipher key
     Encrypt message with RC4 and cipher key


One of the nice things about twitbot is that you don't need to specify an account to post from. Instead a tag is generated (from a key) that is searched for using the twitter search API. This is helpful for the hypothetical bad guy because a single banned account won't ruin his day. The other use of tags is to time stamp the command posts to prevent duplicate execution. I use Mike Verdon’s Python Twitter Tools module which I found the best of the python modules I looked at.


A few months after I wrote twitbot Jose Nazario from Arbor Networks discovered a botnet that was using Twitter as its command and control channel, the botnet would post base64 encoded URLs of executables and the bots would download and execute them. I was surprised that people haven't been doing this for longer. 

Tuesday, January 5, 2010

The first of many lazy link entries


I'm going to throw some links out to the world and pretend that it's a real entry!

The 500 Mile Email Problem
This is an anecdote about debugging an email system. The problem: email will travel no more than 500 miles. It's a fun read.

Geekonomics: The Real Cost of Insecure Software by David Rice
A keynote about crappy software and the problems it causes for everyone. It's a very good presentation and if you can find the 50 minutes or so you should definitely watch it. The presentation is very accessible and is a good introduction to software security issues for non-geeks. I didn't agree with all the things that were said but I think the solution proposed is on the right track. Rice suggests that we need to help consumers discriminate between software products on security rather than features and to do so a software safety rating like those found on cars should be adopted. Also check the presentation out to hear Australia referred to as a socialist nation.

I love virtual economies, I did some work on market dynamics in MMOs as part of my undergraduate studies, I try and read all the EVE Online economic reports that they publish and I love the novel Halting State by Charlie Stross which is partly about a company that manages virtual economies. This presentation focuses more on Farmville style casual games rather than World of Warcraft style MMOs. William Grosso works for a company that seems to provide virtual economy management services. The key things with virtual economies are that virtual money doesn't circulate infinitely, there are money sources and money sinks and that the controllers of the game have perfect information about the economy.