enowars5-service-stldoctor

STL-Analyzing A/D Service for ENOWARS5 in 2021
git clone https://git.sinitax.com/sinitax/enowars5-service-stldoctor
Log | Files | Refs | README | LICENSE | sfeed.txt

index.html (15721B)


      1<!doctype html>
      2<html>
      3<head>
      4  <meta charset="utf-8">
      5  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
      6  <title>STLDoctor</title>
      7  <style type="text/css">
      8    body {
      9  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
     10  color: #222;
     11  font-size: 100%;
     12}
     13
     14.slide {
     15  position: absolute;
     16  top: 0; bottom: 0;
     17  left: 0; right: 0;
     18  background-color: #f7f7f7;
     19}
     20
     21.slide-content {
     22  width: 800px;
     23  height: 600px;
     24  overflow: hidden;
     25  margin: 80px auto 0 auto;
     26  padding: 30px;
     27
     28  font-weight: 200;
     29  font-size: 200%;
     30  line-height: 1.375;
     31}
     32
     33.controls {
     34  position: absolute;
     35  bottom: 20px;
     36  left: 20px;
     37}
     38
     39.arrow {
     40  width: 0; height: 0;
     41  border: 30px solid #333;
     42  float: left;
     43  margin-right: 30px;
     44
     45  -webkit-touch-callout: none;
     46  -webkit-user-select: none;
     47  -khtml-user-select: none;
     48  -moz-user-select: none;
     49  -ms-user-select: none;
     50  user-select: none;
     51}
     52
     53.prev {
     54  border-top-color: transparent;
     55  border-bottom-color: transparent;
     56  border-left-color: transparent;
     57
     58  border-left-width: 0;
     59  border-right-width: 50px;
     60}
     61
     62.next {
     63  border-top-color: transparent;
     64  border-bottom-color: transparent;
     65  border-right-color: transparent;
     66
     67  border-left-width: 50px;
     68  border-right-width: 0;
     69}
     70
     71.prev:hover {
     72  border-right-color: #888;
     73  cursor: pointer;
     74}
     75
     76.next:hover {
     77  border-left-color: #888;
     78  cursor: pointer;
     79}
     80
     81h1 {
     82  font-size: 300%;
     83  line-height: 1.2;
     84  text-align: center;
     85  margin: 170px 0 0;
     86}
     87
     88h2 {
     89  font-size: 100%;
     90  line-height: 1.2;
     91  margin: 5px 0;
     92  text-align: center;
     93  font-weight: 200;
     94}
     95
     96h3 {
     97  font-size: 140%;
     98  line-height: 1.2;
     99  border-bottom: 1px solid #aaa;
    100  margin: 0;
    101  padding-bottom: 15px;
    102}
    103
    104ul {
    105  padding: 20px 0 0 60px;
    106  font-weight: 200;
    107  line-height: 1.375;
    108}
    109
    110.author h1 {
    111  font-size: 170%;
    112  font-weight: 200;
    113  text-align: center;
    114  margin-bottom: 30px;
    115}
    116
    117.author h3 {
    118  font-weight: 100;
    119  text-align: center;
    120  font-size: 95%;
    121  border: none;
    122}
    123
    124a {
    125  text-decoration: none;
    126  color: #44a4dd;
    127}
    128
    129a:hover {
    130  color: #66b5ff;
    131}
    132
    133pre {
    134  font-size: 60%;
    135  line-height: 1.3;
    136}
    137
    138.progress {
    139  position: fixed;
    140  top: 0; left: 0; right: 0;
    141  height: 3px;
    142  z-index: 1;
    143}
    144
    145.progress-bar {
    146  width: 0%;
    147  height: 3px;
    148  background-color: #b4b4b4;
    149
    150  -webkit-transition: width 0.05s ease-out;
    151  -moz-transition: width 0.05s ease-out;
    152  -o-transition: width 0.05s ease-out;
    153  transition: width 0.05s ease-out;
    154}
    155
    156.hidden {
    157  display: none;
    158}
    159
    160@media (max-width: 850px) {
    161
    162  body {
    163    font-size: 70%;
    164  }
    165
    166  .slide-content {
    167    width: auto;
    168  }
    169
    170  img {
    171    width: 100%;
    172  }
    173
    174  h1 {
    175    margin-top: 120px;
    176  }
    177
    178  .prev, .prev:hover {
    179    border-right-color: rgba(135, 135, 135, 0.5);
    180  }
    181
    182  .next, .next:hover {
    183    border-left-color: rgba(135, 135, 135, 0.5);
    184  }
    185}
    186
    187@media (max-width: 480px) {
    188  body {
    189    font-size: 50%;
    190    overflow: hidden;
    191  }
    192
    193  .slide-content {
    194    padding: 10px;
    195    margin-top: 10px;
    196    height: 340px;
    197  }
    198
    199  h1 {
    200    margin-top: 50px;
    201  }
    202
    203  ul {
    204    padding-left: 25px;
    205  }
    206}
    207
    208@media print {
    209  * {
    210    -webkit-print-color-adjust: exact;
    211  }
    212
    213  @page {
    214    size: letter;
    215  }
    216
    217  .hidden {
    218    display: inline;
    219  }
    220
    221  html {
    222    width: 100%;
    223    height: 100%;
    224    overflow: visible;
    225  }
    226
    227  body {
    228    margin: 0 auto !important;
    229    border: 0;
    230    padding: 0;
    231    float: none !important;
    232    overflow: visible;
    233    background: none !important;
    234    font-size: 52%;
    235  }
    236
    237  .progress, .controls {
    238    display: none;
    239  }
    240
    241  .slide {
    242    position: static;
    243  }
    244
    245  .slide-content {
    246    border: 1px solid #222;
    247    margin-top: 0;
    248    margin-bottom: 40px;
    249    height: 3.5in;
    250    overflow: visible;
    251  }
    252
    253  .slide:nth-child(even) {
    254    /* 2 slides per page */
    255    page-break-before: always;
    256  }
    257}
    258
    259/*
    260
    261github.com style (c) Vasily Polovnyov <vast@whiteants.net>
    262
    263*/
    264
    265.hljs {
    266  display: block;
    267  overflow-x: auto;
    268  padding: 0.5em;
    269  color: #333;
    270  background: #f8f8f8;
    271}
    272
    273.hljs-comment,
    274.hljs-quote {
    275  color: #998;
    276  font-style: italic;
    277}
    278
    279.hljs-keyword,
    280.hljs-selector-tag,
    281.hljs-subst {
    282  color: #333;
    283  font-weight: bold;
    284}
    285
    286.hljs-number,
    287.hljs-literal,
    288.hljs-variable,
    289.hljs-template-variable,
    290.hljs-tag .hljs-attr {
    291  color: #008080;
    292}
    293
    294.hljs-string,
    295.hljs-doctag {
    296  color: #d14;
    297}
    298
    299.hljs-title,
    300.hljs-section,
    301.hljs-selector-id {
    302  color: #900;
    303  font-weight: bold;
    304}
    305
    306.hljs-subst {
    307  font-weight: normal;
    308}
    309
    310.hljs-type,
    311.hljs-class .hljs-title {
    312  color: #458;
    313  font-weight: bold;
    314}
    315
    316.hljs-tag,
    317.hljs-name,
    318.hljs-attribute {
    319  color: #000080;
    320  font-weight: normal;
    321}
    322
    323.hljs-regexp,
    324.hljs-link {
    325  color: #009926;
    326}
    327
    328.hljs-symbol,
    329.hljs-bullet {
    330  color: #990073;
    331}
    332
    333.hljs-built_in,
    334.hljs-builtin-name {
    335  color: #0086b3;
    336}
    337
    338.hljs-meta {
    339  color: #999;
    340  font-weight: bold;
    341}
    342
    343.hljs-deletion {
    344  background: #fdd;
    345}
    346
    347.hljs-addition {
    348  background: #dfd;
    349}
    350
    351.hljs-emphasis {
    352  font-style: italic;
    353}
    354
    355.hljs-strong {
    356  font-weight: bold;
    357}
    358
    359
    360  </style>
    361    <script async src="http://localhost:35729/livereload.js"></script>
    362</head>
    363<body>
    364    <div class="progress">
    365    <div class="progress-bar"></div>
    366  </div>
    367
    368  <div class="slide" id="slide-1">
    369    <section class="slide-content"><style>
    370
    371.footnote {
    372    font-size: 16pt;
    373    position: absolute;
    374    color: gray;
    375    bottom: 0px;
    376    right: 0px;
    377}
    378
    379.slide-content {
    380    position: relative;
    381}
    382
    383.slide-content > ul >li {
    384    padding: 7px 0px;
    385}
    386
    387.slide-content > p > img {
    388    width: 100%;
    389}
    390
    391</style></section>
    392  </div>
    393  <div class="slide hidden" id="slide-2">
    394    <section class="slide-content"><h1 id="stldoctor-">STLDoctor 💉</h1>
    395</section>
    396  </div>
    397  <div class="slide hidden" id="slide-3">
    398    <section class="slide-content"><h3 id="the-plan-">The Plan 💡</h3>
    399<!-- Familiar with C and wondered about non-standard
    400     buffer-/integer overflow C bugs -->
    401<!-- Plaintext file inspection service -->
    402<!-- Interesting and realisitic bugs -->
    403<!-- Written in C -->
    404<!-- Have to combine 'gadgets' for exploit, but
    405     as a logic bug, not RCE -->
    406<ul>
    407<li>Plaintext service</li>
    408<li>Interesting C bugs</li>
    409<li>Exploit logic bugs, not RCE</li>
    410<li>Learn about the STL format</li>
    411</ul>
    412<p><img style="width: 240px !important; transform: rotate(90deg); height: 240px; position:absolute; top:150px; right:70px;" src="https://upload.wikimedia.org/wikipedia/commons/9/9b/STL_sample_2.png"></p>
    413</section>
    414  </div>
    415  <div class="slide hidden" id="slide-4">
    416    <section class="slide-content"><h3 id="setup-">Setup 🔧</h3>
    417<ul>
    418<li>C binary that communicates via <code>stdin</code> and <code>stdout</code></li>
    419<li>Networking abstracted through hosting with <code>socat</code></li>
    420<li>File system backend with periodic clean up</li>
    421</ul>
    422<p><img src="media/socat.gif" alt="socat"></p>
    423</section>
    424  </div>
    425  <div class="slide hidden" id="slide-5">
    426    <section class="slide-content"><h3 id="functionality-">Functionality 🎮</h3>
    427<!-- file system backend separates user accounts and stl files location for non-guests -->
    428<!-- guest account files can be downloaded by knowing their modelname,
    429     premium account files can only be downloaded by authenticated users -->
    430<ul>
    431<li>Users can upload and search for files</li>
    432<li>Register to upload private files</li>
    433<li>Uploaded files are analyzed and information is returned to the user</li>
    434</ul>
    435</section>
    436  </div>
    437  <div class="slide hidden -" id="slide-6">
    438    <section class="slide-content"><!-- Sample interaction demonstrating how you would retrieve a file you uploaded -->
    439<p><img src="media/search.gif" alt="FileSearch"></p>
    440</section>
    441  </div>
    442  <div class="slide hidden" id="slide-7">
    443    <section class="slide-content"><h3 id="1-vuln-">1. Vuln 💉</h3>
    444<ul>
    445<li>Flags are stored in the solidname of the STL</li>
    446<li>Bug in upload info file parsing allows attacker to retrieve any public file</li>
    447</ul>
    448</section>
    449  </div>
    450  <div class="slide hidden" id="slide-8">
    451    <section class="slide-content"><h3 id="2-vuln-">2. Vuln 💉</h3>
    452<ul>
    453<li>Flags are stored in the solidname of a private file</li>
    454<li>Buffer overflow in hash function allows enumeration of private user hashes</li>
    455<li>Generate preimages of weak hash function to login as users</li>
    456</ul>
    457</section>
    458  </div>
    459  <div class="slide hidden" id="slide-9">
    460    <section class="slide-content"><h3 id="goals-met-">Goals Met 🎉</h3>
    461<!-- dont need to be an expert at fancy exploitation to exploit,
    462     just basic knowledge of C and testing code snippets to see
    463     if they do what you expect them to in different cases -->
    464<p>⭐ Plaintext file inspection service <br>
    465⭐ Interesting and realisitic bugs <br>
    466⭐ Combine different gadgets for exploit <br>
    467⭐ Don&#39;t need to be an expert at fancy ROP <br>
    468⭐ No SLA lost in TestCTF <br>
    469⭐ Written in C</p>
    470</section>
    471  </div>
    472  <div class="slide hidden" id="slide-10">
    473    <section class="slide-content"><h3 id="issues-">Issues 📉</h3>
    474<!-- Currently, the exploits dont require you to understand the
    475    STL file format, however, to make sure that the service
    476    is working correctly, you need to inspect the code -->
    477<!-- Still considering encoding of flags as STL, but want to
    478    avoid -->
    479<p>💥 Exploits not directly related to STL format <br>
    480💥 (Eno)checker has memory leaks</p>
    481</section>
    482  </div>
    483  <div class="slide hidden" id="slide-11">
    484    <section class="slide-content"><h3 id="lesssons-learned">Lesssons Learned</h3>
    485<!-- from the feedback I gathered, that not a lot of people write C code
    486     often, but this also means it is a great opportunity for learning
    487     something new. -->
    488<ul>
    489<li>Many exploits are not suited for A/D ctfs</li>
    490<li>How to write a FSM format parser</li>
    491<li>Be careful with casts in C</li>
    492<li>People just <em>love</em> C services 🤡</li>
    493</ul>
    494</section>
    495  </div>
    496  <div class="slide hidden" id="slide-12">
    497    <section class="slide-content"></section>
    498  </div>
    499  <div class="slide hidden" id="slide-13">
    500    <section class="slide-content"></section>
    501  </div>
    502  <div class="slide hidden" id="slide-14">
    503    <section class="slide-content"><h1 id="exploit-1">Exploit 1</h1>
    504</section>
    505  </div>
    506  <div class="slide hidden" id="slide-15">
    507    <section class="slide-content"><p><img src="media/exploit-1-1.png" alt="exploit-1-1"></p>
    508</section>
    509  </div>
    510  <div class="slide hidden" id="slide-16">
    511    <section class="slide-content"><p><img src="media/exploit-1-2.png" alt="exploit-1-2"></p>
    512</section>
    513  </div>
    514  <div class="slide hidden" id="slide-17">
    515    <section class="slide-content"><p><img src="media/exploit-1-3.png" alt="exploit-1-3"></p>
    516</section>
    517  </div>
    518  <div class="slide hidden" id="slide-18">
    519    <section class="slide-content"><p><img src="media/exploit-1-4.png" alt="exploit-1-4"></p>
    520</section>
    521  </div>
    522  <div class="slide hidden" id="slide-19">
    523    <section class="slide-content"><p><img src="media/exploit-1-5.png" alt="exploit-1-5"></p>
    524</section>
    525  </div>
    526  <div class="slide hidden" id="slide-20">
    527    <section class="slide-content"><h1 id="exploit-2">Exploit 2</h1>
    528</section>
    529  </div>
    530  <div class="slide hidden" id="slide-21">
    531    <section class="slide-content"><p><img src="media/exploit-2-1.png" alt="exploit-2-1"></p>
    532<script>
    533    // var slide_headers = document.querySelectorAll(".slide-content > h3");
    534    // for (var i = 0; i < slide_headers.length; i++) {
    535    //     var img = document.createElement('img')
    536    //     img.src = "logo.png";
    537    //     img.style = "height: 2.4ex; padding-right: 10px; float:right";
    538    //     slide_headers[i].append(img);
    539    // }
    540</script></section>
    541  </div>
    542
    543
    544
    545  <script type="text/javascript">
    546    /**
    547 * Returns the current page number of the presentation.
    548 */
    549function currentPosition() {
    550  return parseInt(document.querySelector('.slide:not(.hidden)').id.slice(6));
    551}
    552
    553
    554/**
    555 * Navigates forward n pages
    556 * If n is negative, we will navigate in reverse
    557 */
    558function navigate(n) {
    559  var position = currentPosition();
    560  var numSlides = document.getElementsByClassName('slide').length;
    561
    562  /* Positions are 1-indexed, so we need to add and subtract 1 */
    563  var nextPosition = (position - 1 + n) % numSlides + 1;
    564
    565  /* Normalize nextPosition in-case of a negative modulo result */
    566  nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1;
    567
    568  document.getElementById('slide-' + position).classList.add('hidden');
    569  document.getElementById('slide-' + nextPosition).classList.remove('hidden');
    570
    571  updateProgress();
    572  updateURL();
    573  updateTabIndex();
    574}
    575
    576
    577/**
    578 * Updates the current URL to include a hashtag of the current page number.
    579 */
    580function updateURL() {
    581  try {
    582    window.history.replaceState({} , null, '#' + currentPosition());
    583  } catch (e) {
    584    window.location.hash = currentPosition();
    585  }
    586}
    587
    588
    589/**
    590 * Sets the progress indicator.
    591 */
    592function updateProgress() {
    593  var progressBar = document.querySelector('.progress-bar');
    594
    595  if (progressBar !== null) {
    596    var numSlides = document.getElementsByClassName('slide').length;
    597    var position = currentPosition() - 1;
    598    var percent = (numSlides === 1) ? 100 : 100 * position / (numSlides - 1);
    599    progressBar.style.width = percent.toString() + '%';
    600  }
    601}
    602
    603
    604/**
    605 * Removes tabindex property from all links on the current slide, sets
    606 * tabindex = -1 for all links on other slides. Prevents slides from appearing
    607 * out of control.
    608 */
    609function updateTabIndex() {
    610  var allLinks = document.querySelectorAll('.slide a');
    611  var position = currentPosition();
    612  var currentPageLinks = document.getElementById('slide-' + position).querySelectorAll('a');
    613  var i;
    614
    615  for (i = 0; i < allLinks.length; i++) {
    616    allLinks[i].setAttribute('tabindex', -1);
    617  }
    618
    619  for (i = 0; i < currentPageLinks.length; i++) {
    620    currentPageLinks[i].removeAttribute('tabindex');
    621  }
    622}
    623
    624/**
    625 * Determines whether or not we are currently in full screen mode
    626 */
    627function isFullScreen() {
    628  return document.fullscreenElement ||
    629         document.mozFullScreenElement ||
    630         document.webkitFullscreenElement ||
    631         document.msFullscreenElement;
    632}
    633
    634/**
    635 * Toggle fullScreen mode on document element.
    636 * Works on chrome (>= 15), firefox (>= 9), ie (>= 11), opera(>= 12.1), safari (>= 5).
    637 */
    638function toggleFullScreen() {
    639  /* Convenient renames */
    640  var docElem = document.documentElement;
    641  var doc = document;
    642
    643  docElem.requestFullscreen =
    644      docElem.requestFullscreen ||
    645      docElem.msRequestFullscreen ||
    646      docElem.mozRequestFullScreen ||
    647      docElem.webkitRequestFullscreen.bind(docElem, Element.ALLOW_KEYBOARD_INPUT);
    648
    649  doc.exitFullscreen =
    650      doc.exitFullscreen ||
    651      doc.msExitFullscreen ||
    652      doc.mozCancelFullScreen ||
    653      doc.webkitExitFullscreen;
    654
    655  isFullScreen() ? doc.exitFullscreen() : docElem.requestFullscreen();
    656}
    657
    658document.addEventListener('DOMContentLoaded', function () {
    659  // Update the tabindex to prevent weird slide transitioning
    660  updateTabIndex();
    661
    662  // If the location hash specifies a page number, go to it.
    663  var page = window.location.hash.slice(1);
    664  if (page) {
    665    navigate(parseInt(page) - 1);
    666  }
    667
    668  document.onkeydown = function (e) {
    669    var kc = e.keyCode;
    670
    671    // left, down, H, J, backspace, PgUp - BACK
    672    // up, right, K, L, space, PgDn - FORWARD
    673    // enter - FULLSCREEN
    674    if (kc === 37 || kc === 40 || kc === 8 || kc === 72 || kc === 74 || kc === 33) {
    675      navigate(-1);
    676    } else if (kc === 38 || kc === 39 || kc === 32 || kc === 75 || kc === 76 || kc === 34) {
    677      navigate(1);
    678    } else if (kc === 13) {
    679      toggleFullScreen();
    680    }
    681  };
    682
    683  if (document.querySelector('.next') && document.querySelector('.prev')) {
    684    document.querySelector('.next').onclick = function (e) {
    685      e.preventDefault();
    686      navigate(1);
    687    };
    688
    689    document.querySelector('.prev').onclick = function (e) {
    690      e.preventDefault();
    691      navigate(-1);
    692    };
    693  }
    694});
    695
    696
    697  </script>
    698</body>
    699</html>