Network Traffic Forensics

Objective #8

Santa has introduced a web-based packet capture and analysis tool at to support the elves and their information security work. Using the system, access and decrypt HTTP/2 network activity. What is the name of the song described in the document sent from Holly Evergreen to Alabaster Snowball?

For hints on achieving this objective, please visit SugarPlum Mary and help her with the Python Escape from LA Cranberry Pi terminal challenge.

SugarPlum Mary

HTTP/2.0 Intro and Decryption hint from SugarPlum Mary
Did you see Chris' & Chris' talk on HTTP/2.0?

Another elf told me that Packalyzer was rushed and deployed with development code sitting in the web root.
Apparently, he found this out by looking at HTML comments left behind and was able to grab the server-side source code.
There was suspicious-looking development code using environment variables to store SSL keys and open up directories.
This elf then told me that manipulating values in the URL gave back weird and descriptive errors.
I'm hoping these errors can't be used to compromise SSL on the website and steal logins.
On a tooootally unrelated note, have you seen the HTTP2 talk at at KringleCon by the Chrises? I never knew HTTP2 was so different!

Packalyzer asks to register.

Packalyzer login

After registering and successful login, traffic can be sniffed and respective .pcap downloaded.
It contains TLSv1.2 traffic. Master secret log file is required to decrypt this traffic.

Going back and looking at HTML source, there is a interesting comment.

//File upload Function. All extensions and sizes are validated server-side in app.js

Manually trying to find real app.js location, e.g., /app.js, /pub/js/app.js, etc., finally, leads to It contains enabled debugging mode (line 26), which can be abused (lines 88, 78-83 and 164) by disclosing environment variable SSLKEYLOGFILE (seen in line 27).

const dev_mode = true;
const key_log_path = ( !dev_mode || __dirname + process.env.DEV + process.env.SSLKEYLOGFILE )
function load_envs() {
  var dirs = []
  var env_keys = Object.keys(process.env)
  for (var i=0; i < env_keys.length; i++) {
    if (typeof process.env[env_keys[i]] === "string" ) {
      dirs.push(( "/"+env_keys[i].toLowerCase()+'/*') )
  return uniqueArray(dirs)
if (dev_mode) {
    //Can set env variable to open up directories during dev
    const env_dirs = load_envs();
} else {
    const env_dirs = ['/pub/','/uploads/'];
//Route for anything in the public folder except index, home and register
router.get(env_dirs,  async (ctx, next) => {
try {
    var Session = await sessionizer(ctx);
    //Splits into an array delimited by /
    let split_path = ctx.path.split('/').clean("");
    //Grabs directory which should be first element in array
    let dir = split_path[0].toUpperCase();
    let filename = "/"+split_path.join('/');
    while (filename.indexOf('..') > -1) {
    filename = filename.replace(/\.\./g,'');
    if (!['index.html','home.html','register.html'].includes(filename)) {
    ctx.set('Content-Type',mime.lookup(__dirname+(process.env[dir] || '/pub/')+filename))
    ctx.body = fs.readFileSync(__dirname+(process.env[dir] || '/pub/')+filename)
    } else {
    ctx.body='Not Found';
} catch (e) {

Browsing to returns an error, which discloses SSLKEYLOGFILE value as packalyzer_clientrandom_ssl.log.

Error: ENOENT: no such file or directory, open '/opt/http2packalyzer_clientrandom_ssl.log/'

Recalling app.js code, key_log_path corresponds to

const key_log_path = ( !dev_mode || __dirname + process.env.DEV + process.env.SSLKEYLOGFILE )

Now traffic in .pcap can be decrypted. To do it with WireShark, open Edit -> Preferences, select Protocols -> SSL and in (Pre)-Master-Secret log filename browse for downloaded packalyzer_clientrandom_ssl.log file.

After decryption, http2 traffic can be analyzed either manually or by using WireShark's filter, i.e.,
There is a packet, which contains JSON data with credentials.

{"username": "alabaster", "password": "Packer-p@re-turntable192"}

Re-login to Packalyzer with alabaster user and within Captures there is super_secret_packet_capture.pcap. It contains plain-text SMTP session where an email with attachment is being sent from Holly Evergreen to Alabaster Snowball.

220 ESMTP Postfix (Ubuntu)
250-SIZE 10240000
250 DSN

250 2.1.0 Ok
250 2.1.5 Ok
354 End data with <CR><LF>.<CR><LF>
Date: Fri, 28 Sep 2018 11:33:17 -0400
Subject: test Fri, 28 Sep 2018 11:33:17 -0400
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_11181"

Content-Type: text/plain

Hey alabaster, 

Santa said you needed help understanding musical notes for accessing the vault. He said your favorite key was D. Anyways, the following attachment should give you all the information you need about transposing music.

Content-Type: application/octet-stream
Content-Transfer-Encoding: BASE64
Content-Disposition: attachment


Attachment is a .pdf file, mail.pdf, which contains information about music sheet transposing, but the most relevant information is name of song.

A piano keyboard gives us easy access to every (western) tone. As we go from left to right, the pitches get higher. Pressing the middle A, for example, would give us a tone of 440 Hertz. Pressing the next A up (to the right) gives us 880 Hz, while the next one down (left) produces 220 Hz. These A tones each sound very similar to us - just higher and lower. Each A is an “octave” apart from the next. Going key by key, we count 12 “half tone” steps between one A and the next - 12 steps in an octave.

As you may have guessed, elf (and human) ears perceive pitches logarithmically. That is, the frequency jump between octaves doubles as we go up the keyboard, and that sounds normal to us. Consequently, the precise frequency of each note other than A can only be cleanly expressed with a log base 12 expression. Ugh! For our purposes though, we can think of note separation in terms of whole and half steps.

Have you noticed the black keys on the keyboard? They represent half steps between the white keys. For example, the black key between C and D is called C# (c-sharp) or Db (d-flat). Going from C to D is a whole step, but either is a half step from C#/Db. Some white keys don’t have black ones between them. B & C and E & F are each only a half step apart. Why? Well, it turns out that our ears like it that way. Try this: press C D E F G A B C on a piano. It sounds natural, right? The “C major” scale you just played matches every other major scale:

If you follow that same pattern (whole whole half whole whole whole half), you can start from any note on the keyboard and play a major scale. So a Bb major scale would be Bb C D Eb F G A Bb. You can get this by counting whole and half steps up from Bb or by taking each note in the C major scale and going down a whole step.

This uniform shifting of tones is called transposition. This is done all the time in music because of differences in how instruments are designed, the sound an arranger wants to achieve, or the comfortable vocal range of a singer. Some elves can do this on the fly without really thinking, but it can always be done manually, looking at a piano keyboard.

To look at it another way, consider a song “written in the key of Bb.” If the musicians don’t like that key, it can be transposed to A with a little thought. First, how far apart are Bb and A? Looking at our piano, we see they are a half step apart. OK, so for each note, we’ll move down one half step. Here’s an original in Bb:
D C Bb C D D D C C C D F F D C Bb C D D D D C C D C Bb

And take everything down one half step for A:
C# B A B C# C# C# B B B C# E E C# B A B C# C# C# C# B B C# B A

We’ve just taken Mary Had a Little Lamb from Bb to A!

Answer to this objective is Mary Had a Little Lamb.