SANS Holiday Hack 2018: Objective 8: Network Traffic Forensics
Objective: Santa has introduced a web-based packet capture and analysis tool at https://packalyzer.kringlecastle.com 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 LACranberry Pi terminal challenge.
Answer: Mary Had A Little Lamb
Analysis of PackAlyzer
Logging into the site specified you get welcomed by a registration/login page, which as normal I analysed, reviewed source, traffic, and attempted injection techniques. But no luck. So I registered an account with some throw-away credentials and gained access to the application:

We start to “SNIFF TRAFFIC” by clicking the button and all the traffic is TCP:443 and appears to be SSL encrypted. Not much more info. In the top right menu it is possible to access captures that have been taken, these can be re-analyzed or downloaded as pcap.
Analysing this page further and using the hint regarding comments from SugarPlum Mary the following was found:
//File upload Function. All extensions and sizes are validated server-side in app.js
This lead to the discovery of the following resource:
https://packalyzer.kringlecastle.com/pub/app.js
Analysing this source code for the back-end Node JS script, which shows a HTTP2 secure instance being created on 443.
const server = http2.createSecureServer(options, app.callback());
server.listen(443);
So I watched the Kringlecon talk on HTTP/2: Decryption and Analysis in Wireshark and then discovered that the server is in dev mode and logging the SSL keys for decryption:
const dev_mode = true;
const key_log_path = ( !dev_mode || __dirname + process.env.DEV + process.env.SSLKEYLOGFILE )
So now we need to work out what this path is by getting the environment variables. Further in the code there is a function that may help us:
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)
}
This code basically makes each environment value available via a url with the lower case environment name i.e. https://packalyzer.kringlecastle.com/pub/<env_key>, so we fetched:
https://packalyzer.kringlecastle.com/sslkeylogfile/
Which returned:
Error: ENOENT: no such file or directory, open ‘/opt/http2packalyzer_clientrandom_ssl.log/’
So the file: /dev/packalyzer_clientrandom_ssl.log will contain the private keys for the HTTP2 encrypted data. So I downloaded:
https://packalyzer.kringlecastle.com/dev/packalyzer_clientrandom_ssl.log
Which returned a file with the keys as expected:
CLIENT_RANDOM C364E2BA4D73384154EE86C31BBD2A36B95A986729D443BD5DE933C2B651E1FF D3B55F94BF1AB64F7DD2E09084258373340E6D06CE217619FC082DB9F59DF367BAF909E3C2D8E253E5B31AB59FB0FFB3 CLIENT_RANDOM C180125CB417D4378B6AF7B478D1B602F9F22FDC14395AE3BAE1983B89CCCD3E 63EB712934CC5B4C09D4486069397032DE3A515291E80DCC919A4C33E7BA29DF9B29C4690C6A4D57B4D2AF3F0076A905 CLIENT_RANDOM AA5817BBD97E716ACFFFB8AFE90B2B48005036F69C36C6491D57F846D3CA27BA 6CB961DA77A75DF5543885DDD8B6E8ECED81C7FF2B5150498810CF782553A8581A93E36C2D73AC704E63BB37B5D50DDA CLIENT_RANDOM 93A9483D98B376A78CAA7D8BED4938A16FFA117FFD5123D9081CC9FF678E7D3F 4685B2A6D4FB866BF129AEA55B5347756A770EAAE83D2D1F17A47690F5376A48E05D9700DBA4777273323879AA0EE168 CLIENT_RANDOM 4B1A9D8D06CA9C24E900FCF7A0D021E1C598A4B1DDC6290A11272F3937EB300A 97B1FD9A090CC1745A87D753DBFD619D05AE97374D56E537F02C0FF3507A0FCE1201CE6C90C9A22BB3C26E19F047EB50 CLIENT_RANDOM DE1E7F2346354A9AF97D99EE4A143A9B60CF908D95FE009D94256DD9ECC98349 B86FB0B58F4FF23ADC4EB6E8694DAFE20A864F02C5FBF37470718605425BD5B4EC2EB5BD53A7E8ABB66ED8D07D52F4E8 CLIENT_RANDOM B3140B6861C5A6AB5061688D9D2D61F0E8B59DF141E86DBA601AEAB915AC1491 1425A677982A8F1DD41888D1E2619B024F08E3AB4092B6439A4F26C8934994715F919C8291061F2F02EF75791062A520 CLIENT_RANDOM 8B1CA484D297DB83FC6BA43F849ED5F99E520F0D2079E0793DAFC3F8344B37DF C609781135716F73D36456FD7566A304C868BA9835CE490C9580F9A222793574B639BD0EBCC9A86F1C0CBCDBCF0048ED
So at this point I did another “SNIFF TRAFFIC” and took a download of the keys so they corresponded to the same time frame. This traffic was downloaded via the Capture menu to my working machine, and using Wireshark with the correct keys, setting the option Edit > Preferences > Protocols > SSL > (Pre)-Master-Secret log filename, we can decrypt the taffic:

We could now vie HTTP2 in the clear and use a filter (http2.header.name==”cookie”) to access headers with cookies set:

This provided a HTTP application session ID within a cookie,:
Header: cookie PASESSION=23558453325328628445498088456223
Using Chrome and the developer tools we changed our Cookie PASESSION to the value above, and reload our packalyzer page, we can hijack the session. (Note: We also got session cookies for other users):

Going to the capture menu we find the following pcap file which we can download:

Opening this pcap file in Wireshark we see the traffic is SMTP and we can follow the stream, to see the following SMTP (E-mail) protocol, luckily it’s not encrypted!!:

Taking the base64 encoded attachment string, I did a base64 decode using CyberChef and saved the output which is a PDF file explaining how keys are arranged on a piano and how to transpose music. At the bottom of this document is the reference to a song:

The song we were looking for is: Mary Had a Little Lamb