Finding out What’s Next at BarCampMel 2012 with Drizzle, SQL, JavaScript and a web browser

Just for the pure insane fun of it, I accepted the challenge of “what can you do with the text format of the schedule?” for BarCampMel. I’m a database guy, so I wanted to load it into a database (which would be Drizzle), and I wanted it to be easy to keep it up to date (this is an unconference after all).

So… the text file itself isn’t in any standard format, so I’d have to parse it. I’m lazy and didn’t want to leave the comfort of the database. Luckily, inside Drizzle, we have a js plugin that lets you execute arbitrary JavaScript. Parsing solved. I needed to get the program and luckily we have the http_functions plugin that uses libcurl to allow us to perform HTTP GET requests. I also wanted it in a table so I could query it when not online, so I needed to load the data. Luckily, in Drizzle we have the built in EXECUTE functionality, so I could just use the JavaScript to parse the response from the HTTP GET request and construct SQL to load the data into a table to then query.

So, grab your Drizzle server with “plugin-add=js” and “plugin-add=http_functions” in the config file or as options to drizzled (prefixed with –) and….

This simple one liner pulls the current schedule and puts it into a table called ‘schedule’:

SELECT EXECUTE(JS("function sql_quote(s) {return s ? '\"'+ s.replace('\"', '\\\"') + '\"' : 'NULL'} function DrizzleDateString(d) { function pad(n) { return n<10 ? '0'+n : n } return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate())+' '+pad(d.getHours())+':'+pad(d.getMinutes())+':'+pad(d.getSeconds()) } var sql = 'COMMIT;CREATE TABLE IF NOT EXISTS schedule (start_time datetime, stage varchar(1000), mr2 varchar(1000), mr1 varchar(1000), duration int); begin; delete from schedule;' ; var time= new Date;var input= arguments[0].split(\"\\n\"); var entry = new Array(); var stage, mr2, mr1; for(var i=0; i < input.length; i++) { var p= input[i].match('^(.*?) (.*)$'); if(p) {if(p[1]=='Time') { time=new Date(Date.parse(p[2]));} if(p[1]=='Duration') { sql+='INSERT INTO schedule (start_time,stage,mr2,mr1,duration) VALUES (\"' + DrizzleDateString(time) + '\", ' + sql_quote(stage) + ', ' + sql_quote(mr2) + ',' + sql_quote(mr1) + ',' + p[2] + '); '; time= new Date(time.getTime()+p[2]*60*1000); stage= mr2= mr1= ''; } if(p[1]=='stage') {stage=p[2]} if (p[1]=='mr2') {mr2=p[2]} if (p[1]=='mr1') {mr1=p[2]} }}; sql+='COMMIT;'; sql", (select http_get(''))));

Which you can then find out “what’s on now and coming up” with this query:

select * from schedule where start_time > DATE_ADD(now(), INTERVAL 9 HOUR) ORDER BY start_time limit 2\G
But it’s totally not fun having to jump to the command line all the time, and you may want it in JSON format for consuming with some web thing…. so you can load the json_server plugin and browse to the port that it’s running on (default 8086) and type the SQL in there and get a JSON response, or just look at the pretty table there.

Friendly exploits

If you happen to be friends with me on Facebook you will have seen a bunch of rather strange updates from me last night. This all started with a tweet (that was also sent to Facebook) by a friend who joked about doing something with the <MARQUEE> tag (see for an example of it and similar things). I saw the joke, as I was reading it through Gwibber or the Facebook website. However…. Leah saw text scrolling over the screen… just like the <MARQUEE> tag actually did.

She was looking at it on her iPad using an app called Friendly.

So I immediately posted a status update: “<script lang=”javascript”>alert(“pwned”);</script>”. This is a nice standard little test to see if you’ve managed to inject code into a web site. If this pops up a dialog box, you’ve made it.

It didn’t work. It didn’t display anything… as if it was just not running the script tag. Disappointing. I soooo wanted it to break here.

I did manage to do all sorts of other things in the Live Feed view though. I could use just about any other HTML tag… including forms. I couldn’t get a HTTP request to my server out of a HTML form in the Live Feed view… but once we did manage to crash Friendly (enough that it had to be force quit on the iPad).

I posted a photo of me holding up the iPad to my laptop web cam to show off the basics:

And then one of what happened when I tried a HTML form (this wasn’t reproducible though… so kind of disappointing):

What we did notice however was that HTML tags were parsed in comments on images too…. which made me wonder… It’s pretty easy to make a HTML form button that will do something… so I posted the same image again with a button that would say “Next” but would take you to a web page on one of my servers instead. It worked! I got a HTTP request! Neat! I could then present a HTML page that looked legit and do the standard things that one does to steal off you.

But I wonder if scripts would work…. so I posted:

Photos are proving more exploitable.... <script lang="javascript">alert("pwned");</script>

and then clicked on the image on the iPad……


I could from here do anything I wanted.

Next… I should probably report this to the developers…. or steal from my friends and make them post things to facebook implying improper relationships and general things that would get you fired.

I went with the former… but the latter would have been fairly easy as the Facebook page for the app nicely tells me which of my friends use it. I could even target my attack!

So I sent a warning message to friends (the 18 of them who use the Friendly app), sent a “contact the developer” message to the developers, sent out a warning on Twitter and went to bed.

Got an email overnight back from the developer: “We just pushed a server update that solves this issue.”

Now… in my tcpdump while trying some of the earlier things I was just seeing https requests to facebook API servers from the iPad, but I don’t thing I looked too closely at images. I have no idea if they’ve actually fixed the holes and I don’t have an iPad to test it on. If you do, go try it.