Pursuits Trivial 500

Back to DEFCON CTF quals 2010 writeups



Tell me about your appendage.


Local mirror


That high-frequency noisesignal hurts my ears! :)


I have a big nose


File says this one is "Monkey's Audio compressed format version 3990 with insane compression, stereo, sample rate 44100". Well, everyone's heard of .APE, but Ubuntu has no packages for coping with it, so I used the official decompressor in a Windows VM. Presto, we've got a WAV file, let's listen to it! Turns out the song is "Ride" by Captain Ahab; mars or m3rc gave a YouTube link on IRC a minute or two after I identified it by frantic lyric Googling, so we know that the artist and title are irrelevant.

After listening to the original version once and then the modified version on loop a few times, it's clear that the file has had cows mooing added to it. Also, there's some high-pitched noise in the background, which is pretty suspicious. I might've poked at it with Audacity for a bit before opening in baudline, which shows a really nice spectrogram. However you do it, you'll notice something odd in the spectrogram (this one was generated with sndfile-spectrogram):

Looks like some sort of binary signal above 15000 Hz. I'm sure it's some kind of standard watermark (Update: ddtek says it was created with csound), but I couldn't find any handy tools after Googling for a bit, so I decided to write my own. There are clearly 8 frequency bands used to signal, 250 Hz apart, and bits last 30 milliseconds. Sounds like a job for the Fast Fourier Transform, which I knew existed but had never really worked with before. Through even more Googling, I found out about Python's wave library and numpy's fft capabilities from this Stack Overflow post, and with the linked tutorial in hand, I eventually (read: in 4ish or more hours) arrived at a Python script that will extract the attached file. (By the way, life is much easier if you cut the file down to mono 16-bit PCM; wave gives you both tracks if it's stereo. It's also worth noting that a bunch of FFTs is exactly how spectrograms are generated in the first place, so image processing was certainly possible and might have been a better idea..)

$ hd extracted.out | head
00000000  70 61 71 38 6f 34 20 2d  38 0d 0a 33 35 37 36 31  |paq8o4 -8..35761|
00000010  09 63 0d 0a 1a db 48 0e  83 05 d7 21 53 ae e4 fe  |.c....H....!S...|
00000020  cf 15 14 fc 9e 7c d9 5e  8e 36 71 be c0 cd 57 6f  |.....|.^.6q...Wo|
00000030  8f e6 ba f7 6e b6 67 7a  07 83 d8 89 91 65 ed 8f  |....n.gz.....e..|
00000040  60 98 8c e9 83 98 d6 c6  5e b3 1d 83 a2 03 74 ce  |`.......^.....t.|
00000050  b0 ed f3 06 c6 35 18 3a  c7 28 38 58 d8 59 d3 e6  |.....5.:.(8X.Y..|
00000060  e2 cd 6e 8c 3f e1 d4 9b  f4 72 5c 42 30 1b 5a 93  |..n.?....r\B0.Z.|
00000070  27 10 e8 12 88 a1 87 51  04 de 87 2a be ce 34 68  |'......Q...*..4h|
00000080  2e c8 86 dc 0c 9c f6 2a  e5 12 8f 30 df 14 a1 15  |.......*...0....|
00000090  98 83 01 fc 8c 35 ee 18  fc 8d 86 7b 60 49 4a 1a

Wait, is that ASCII? It's actually a neat little table:

$ head -n 2 extracted.out
paq8o4 -8
35761   c

Can't be a coincidence, so we must be decoding correctly, but what does it mean? Eventually, a teammate tried Bing instead of Google, which points to Power PAQ:

$ mv extracted.out{,paq8o4}
$ paq804 extracted.out.paq8o4
Extracting 1 file(s) from extracted.out.paq8o4 -8
Extracting ./c 35761 -> done        
Time 3.64 sec, used 1712114993 bytes of memory

Close this window or press ENTER to continue...
$ head Nose.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <meta http-equiv="Content-Style-Type" content="text/css" />
                <meta name="generator" content="MediaWiki 1.15alpha" />
                <meta name="keywords" content="Nose,Articles lacking sources from June 2008,Camel,Cetacean,Depolarization,Dog,Elephant,G protein-coupled receptor,Glomeruli,Haplorrhini,Human nose" />
                <link rel="alternate" type="application/x-wiki" title="Edit this page" href="/w/index.php?title=Nose&action=edit" />
                <link rel="edit" title="Edit this page" href="/w/index.php?title=Nose&action=edit" />
                <link rel="apple-touch-icon"
                href="http://en.wikipedia.org/apple-touch-icon.png"                />

It's a snapshot of the Wikipedia page for Nose. Dig through the page and you'll find some slightly obfuscated JavaScript (reproduced here with my commentary and deobfuscation):

var 0x375a=["\x67\x65\x74\x54\x69\x6D\x65","\x73\x65\x74\x54\x69\x6D\x65","\x63\x6F\x6F\x6B\x69\x65","\x3D","\x3B\x65\x78\x70\x69\x72\x65\x73\x3D","\x74\x6F\x47\x4D\x54\x53\x74\x72\x69\x6E\x67","\x73\x6E\x69\x63\x6B\x65\x72\x64\x6F\x6F\x64\x6C\x65","\x58\x51\x41\x41\x41\x41\x4C\x2F\x2F\x2F\x2F\x2F\x2F\x2F\x2F\x2F\x2F\x77\x41\x68\x46\x6F\x6C\x73\x63\x54\x32\x72\x66\x59\x6E\x6D\x50\x45\x48\x4F\x55\x74\x71\x6D\x66\x6F\x50\x64\x77\x46\x51\x34\x71\x45\x4C\x6B\x6A\x6F\x6D\x74\x53\x6A\x6C\x58\x74\x59\x70\x2F\x6A\x54\x6F\x66\x47\x47\x69\x39\x63\x69\x4F\x41\x6E\x35\x6A\x36\x6D\x77\x75\x48\x42\x45\x5A\x4A\x4F\x35\x6F\x47\x47\x58\x39\x6E\x5A\x4D\x46\x65\x79\x31\x69\x4E\x46\x42\x6A\x4B\x65\x37\x31\x30\x5A\x6D\x77\x61\x33\x67\x34\x71\x41\x62\x75\x76\x38\x57\x4A\x65\x31\x59\x59\x78\x55\x72\x52\x4C\x45\x7A\x6F\x30\x43\x48\x30\x77\x6D\x6A\x6A\x4D\x67\x67\x6D\x66\x75\x54\x48\x69\x2F\x42\x2F\x55\x4E\x73\x50\x73\x62\x6A\x36\x44\x57\x57\x43\x6E\x4F\x37\x65\x5A\x45\x6C\x31\x62\x45\x31\x38\x39\x76\x43\x53\x45\x58\x31\x5A\x78\x56\x47\x52\x57\x35\x6E\x65\x2F\x75\x65\x35\x4C\x58\x53\x39\x7A\x69\x34\x73\x43\x32\x67\x58\x76\x6E\x73\x44\x55\x5A\x2B\x63\x32\x6B\x48\x39\x75\x4C\x58\x7A\x5A\x7A\x41\x59\x68\x71\x39\x57\x65\x58\x67\x4D\x42\x56\x57\x6E\x53\x43\x77\x4F\x41\x6F\x6F\x43\x46\x70\x42\x5A\x7A\x33\x36\x44\x35\x5A\x54\x44\x45\x32\x65\x79\x4F\x4F\x34\x75\x49\x57\x42\x4A\x6F\x41\x75\x38\x7A\x69\x70\x6A\x34\x5A\x33\x67\x74\x67\x51\x42\x63\x66\x62\x69\x75\x48\x7A\x70\x6B\x56\x37\x61\x4A\x55\x4A\x52\x42\x35\x37\x4E\x73\x4A\x32\x75\x33\x63\x46\x6B\x4E\x7A\x4A\x65\x38\x73\x51\x46\x52\x52\x32\x62\x35\x34\x55\x61\x66\x49\x4A\x54\x6D\x54\x57\x37\x6A\x39\x6B\x64\x77\x6D\x2F\x58\x4B\x32\x38\x6F\x63\x76\x78\x55\x56\x43\x48\x41\x5A\x34\x66\x37\x34\x58\x62\x46\x4B\x36\x4C\x69\x73\x61\x66\x63\x77\x72\x34\x47\x54\x54\x2F\x2B\x39\x61\x51\x45\x52\x48\x6F\x55\x56\x57\x36\x61\x75\x45\x44\x74\x79\x6D\x75\x44\x50\x66\x6C\x34\x71\x4A\x34\x62\x33\x56\x32\x31\x61\x72\x50\x59\x37\x47\x6B\x67\x31\x59\x4E\x52\x75\x45\x69\x46\x35\x33\x71\x35\x42\x58\x49\x4A\x41\x73\x77\x71\x71\x55\x59\x65\x44\x6F\x64\x35\x36\x56\x6C\x61\x66\x69\x4F\x54\x6F\x78\x6B\x36\x45\x47\x65\x75\x6A\x30\x4B\x32\x79\x4A\x73\x65\x34\x68\x41\x68\x51\x34\x49\x64\x33\x73\x37\x6E\x47\x43\x6A\x63\x70\x34\x34\x2B\x2F\x76\x46\x6B\x66\x33\x6C\x67\x57\x62\x33\x41\x54\x34\x37\x7A\x66\x44\x4C\x49\x38\x52\x4E\x77\x41\x53\x37\x6F\x49\x4E\x72\x64\x6F\x4E\x2F\x4A\x4C\x4B\x46\x67\x4D\x43\x6D\x4C\x72\x72\x75\x75\x77\x4C\x2B\x77\x63\x4F\x54\x56\x30\x48\x2F\x2F\x75\x4A\x67\x41\x41"];

function tp78911(_0x5de8x2,_0x5de8x3,_0x5de8x4) {
  var _0x5de8x5= new Date();var _0x5de8x6= new Date();
  if(_0x5de8x4==null || _0x5de8x4==0x0) {
  /* d2.setTime(d1.getTime + 0x36ee80 * 0x18 * arg3); // msec per day is 0x36ee80 * 0x18 */

  /* document.cookie = arg1 + '=' + escape(arg2) + 'expires=' + d2.toGMTString();*/

  /* tp78911('snickerdoodle', 'XQAAAAL//////////wAhFolscT2rfYnmPEHOUtqmfoPdwFQ4qELkjomtSjlXtYp/jTofGGi9ciOAn5j6mwuHBEZJO5oGGX9nZMFey1iNFBjKe710Zmwa3g4qAbuv8WJe1YYxUrRLEzo0CH0wmjjMggmfuTHi/B/UNsPsbj6DWWCnO7eZEl1bE189vCSEX1ZxVGRW5ne/ue5LXS9zi4sC2gXvnsDUZ+c2kH9uLXzZzAYhq9WeXgMBVWnSCwOAooCFpBZz36D5ZTDE2eyOO4uIWBJoAu8zipj4Z3gtgQBcfbiuHzpkV7aJUJRB57NsJ2u3cFkNzJe8sQFRR2b54UafIJTmTW7j9kdwm/XK28ocvxUVCHAZ4f74XbFK6Lisafcwr4GTT/+9aQERHoUVW6auEDtymuDPfl4qJ4b3V21arPY7Gkg1YNRuEiF53q5BXIJAswqqUYeDod56VlafiOToxk6EGeuj0K2yJse4hAhQ4Id3s7nGCjcp44+/vFkf3lgWb3AT47zfDLI8RNwAS7oINrdoN/JLKFgMCmLrruuwL+wcOTV0H//uJgAA', 0x110f5) */

The value of snickerdoodle is base64 encoded. Decode it, and:

$ hd snickerdoodle
00000000  5d 00 00 00 02 ff ff ff  ff ff ff ff ff 00 21 16  |].............!.|
00000010  89 6c 71 3d ab 7d 89 e6  3c 41 ce 52 da a6 7e 83  |.lq=.}..

I didn't recognize this, but a teammate eventually pointed out that some other file started with XQAAAAL and turned out to be lzma. This one was too, and there was a bz2 file inside, and a gz file inside that, and finally:

ako magkaroon ng isang malaking ilong
buyuk bir burnu var
eu tenho um grande nariz
ho un grande naso
ich habe eine grosse nase
j'ai un grand nez
jeg har en stor naese
mam velky nos
minulla on iso nena
mul on suur nina
tengo una nariz grande
tinc un nas gran
une kam nje hunde te madhe
wah tak shi no hana ga oki des

Teammate immediately translates as "I have a big nose", which is the key.

Back to DEFCON CTF quals 2010 writeups