commit aca639afe8c435f45ccc1864c42236252646fff9
parent e7b97f2edf17990be192d95ed42b2431b3060249
Author: Louis Burda <quent.burda@gmail.com>
Date: Tue, 15 Jun 2021 19:04:22 +0200
add service overview slides
Diffstat:
12 files changed, 884 insertions(+), 0 deletions(-)
diff --git a/documentation/slides/.gitignore b/documentation/slides/.gitignore
@@ -0,0 +1 @@
+slides
diff --git a/documentation/slides/index.html b/documentation/slides/index.html
@@ -0,0 +1,699 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+ <title>STLDoctor</title>
+ <style type="text/css">
+ body {
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ color: #222;
+ font-size: 100%;
+}
+
+.slide {
+ position: absolute;
+ top: 0; bottom: 0;
+ left: 0; right: 0;
+ background-color: #f7f7f7;
+}
+
+.slide-content {
+ width: 800px;
+ height: 600px;
+ overflow: hidden;
+ margin: 80px auto 0 auto;
+ padding: 30px;
+
+ font-weight: 200;
+ font-size: 200%;
+ line-height: 1.375;
+}
+
+.controls {
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+}
+
+.arrow {
+ width: 0; height: 0;
+ border: 30px solid #333;
+ float: left;
+ margin-right: 30px;
+
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.prev {
+ border-top-color: transparent;
+ border-bottom-color: transparent;
+ border-left-color: transparent;
+
+ border-left-width: 0;
+ border-right-width: 50px;
+}
+
+.next {
+ border-top-color: transparent;
+ border-bottom-color: transparent;
+ border-right-color: transparent;
+
+ border-left-width: 50px;
+ border-right-width: 0;
+}
+
+.prev:hover {
+ border-right-color: #888;
+ cursor: pointer;
+}
+
+.next:hover {
+ border-left-color: #888;
+ cursor: pointer;
+}
+
+h1 {
+ font-size: 300%;
+ line-height: 1.2;
+ text-align: center;
+ margin: 170px 0 0;
+}
+
+h2 {
+ font-size: 100%;
+ line-height: 1.2;
+ margin: 5px 0;
+ text-align: center;
+ font-weight: 200;
+}
+
+h3 {
+ font-size: 140%;
+ line-height: 1.2;
+ border-bottom: 1px solid #aaa;
+ margin: 0;
+ padding-bottom: 15px;
+}
+
+ul {
+ padding: 20px 0 0 60px;
+ font-weight: 200;
+ line-height: 1.375;
+}
+
+.author h1 {
+ font-size: 170%;
+ font-weight: 200;
+ text-align: center;
+ margin-bottom: 30px;
+}
+
+.author h3 {
+ font-weight: 100;
+ text-align: center;
+ font-size: 95%;
+ border: none;
+}
+
+a {
+ text-decoration: none;
+ color: #44a4dd;
+}
+
+a:hover {
+ color: #66b5ff;
+}
+
+pre {
+ font-size: 60%;
+ line-height: 1.3;
+}
+
+.progress {
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ z-index: 1;
+}
+
+.progress-bar {
+ width: 0%;
+ height: 3px;
+ background-color: #b4b4b4;
+
+ -webkit-transition: width 0.05s ease-out;
+ -moz-transition: width 0.05s ease-out;
+ -o-transition: width 0.05s ease-out;
+ transition: width 0.05s ease-out;
+}
+
+.hidden {
+ display: none;
+}
+
+@media (max-width: 850px) {
+
+ body {
+ font-size: 70%;
+ }
+
+ .slide-content {
+ width: auto;
+ }
+
+ img {
+ width: 100%;
+ }
+
+ h1 {
+ margin-top: 120px;
+ }
+
+ .prev, .prev:hover {
+ border-right-color: rgba(135, 135, 135, 0.5);
+ }
+
+ .next, .next:hover {
+ border-left-color: rgba(135, 135, 135, 0.5);
+ }
+}
+
+@media (max-width: 480px) {
+ body {
+ font-size: 50%;
+ overflow: hidden;
+ }
+
+ .slide-content {
+ padding: 10px;
+ margin-top: 10px;
+ height: 340px;
+ }
+
+ h1 {
+ margin-top: 50px;
+ }
+
+ ul {
+ padding-left: 25px;
+ }
+}
+
+@media print {
+ * {
+ -webkit-print-color-adjust: exact;
+ }
+
+ @page {
+ size: letter;
+ }
+
+ .hidden {
+ display: inline;
+ }
+
+ html {
+ width: 100%;
+ height: 100%;
+ overflow: visible;
+ }
+
+ body {
+ margin: 0 auto !important;
+ border: 0;
+ padding: 0;
+ float: none !important;
+ overflow: visible;
+ background: none !important;
+ font-size: 52%;
+ }
+
+ .progress, .controls {
+ display: none;
+ }
+
+ .slide {
+ position: static;
+ }
+
+ .slide-content {
+ border: 1px solid #222;
+ margin-top: 0;
+ margin-bottom: 40px;
+ height: 3.5in;
+ overflow: visible;
+ }
+
+ .slide:nth-child(even) {
+ /* 2 slides per page */
+ page-break-before: always;
+ }
+}
+
+/*
+
+github.com style (c) Vasily Polovnyov <vast@whiteants.net>
+
+*/
+
+.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 0.5em;
+ color: #333;
+ background: #f8f8f8;
+}
+
+.hljs-comment,
+.hljs-quote {
+ color: #998;
+ font-style: italic;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-subst {
+ color: #333;
+ font-weight: bold;
+}
+
+.hljs-number,
+.hljs-literal,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-tag .hljs-attr {
+ color: #008080;
+}
+
+.hljs-string,
+.hljs-doctag {
+ color: #d14;
+}
+
+.hljs-title,
+.hljs-section,
+.hljs-selector-id {
+ color: #900;
+ font-weight: bold;
+}
+
+.hljs-subst {
+ font-weight: normal;
+}
+
+.hljs-type,
+.hljs-class .hljs-title {
+ color: #458;
+ font-weight: bold;
+}
+
+.hljs-tag,
+.hljs-name,
+.hljs-attribute {
+ color: #000080;
+ font-weight: normal;
+}
+
+.hljs-regexp,
+.hljs-link {
+ color: #009926;
+}
+
+.hljs-symbol,
+.hljs-bullet {
+ color: #990073;
+}
+
+.hljs-built_in,
+.hljs-builtin-name {
+ color: #0086b3;
+}
+
+.hljs-meta {
+ color: #999;
+ font-weight: bold;
+}
+
+.hljs-deletion {
+ background: #fdd;
+}
+
+.hljs-addition {
+ background: #dfd;
+}
+
+.hljs-emphasis {
+ font-style: italic;
+}
+
+.hljs-strong {
+ font-weight: bold;
+}
+
+
+ </style>
+ <script async src="http://localhost:35729/livereload.js"></script>
+</head>
+<body>
+ <div class="progress">
+ <div class="progress-bar"></div>
+ </div>
+
+ <div class="slide" id="slide-1">
+ <section class="slide-content"><style>
+
+.footnote {
+ font-size: 16pt;
+ position: absolute;
+ color: gray;
+ bottom: 0px;
+ right: 0px;
+}
+
+.slide-content {
+ position: relative;
+}
+
+.slide-content > ul >li {
+ padding: 7px 0px;
+}
+
+.slide-content > p > img {
+ width: 100%;
+}
+
+</style></section>
+ </div>
+ <div class="slide hidden" id="slide-2">
+ <section class="slide-content"><h1 id="stldoctor-">STLDoctor 💉</h1>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-3">
+ <section class="slide-content"><h3 id="the-plan-">The Plan 💡</h3>
+<!-- Familiar with C and wondered about non-standard
+ buffer-/integer overflow C bugs -->
+<!-- Plaintext file inspection service -->
+<!-- Interesting and realisitic bugs -->
+<!-- Written in C -->
+<!-- Have to combine 'gadgets' for exploit, but
+ as a logic bug, not RCE -->
+<ul>
+<li>Plaintext service</li>
+<li>Interesting C bugs</li>
+<li>Exploit logic bugs, not RCE</li>
+<li>Learn about the STL format</li>
+</ul>
+<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>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-4">
+ <section class="slide-content"><h3 id="setup-">Setup 🔧</h3>
+<ul>
+<li>C binary that communicates via <code>stdin</code> and <code>stdout</code></li>
+<li>Networking abstracted through hosting with <code>socat</code></li>
+<li>File system backend with periodic clean up</li>
+</ul>
+<p><img src="media/socat.gif" alt="socat"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-5">
+ <section class="slide-content"><h3 id="functionality-">Functionality 🎮</h3>
+<!-- file system backend separates user accounts and stl files location for non-guests -->
+<!-- guest account files can be downloaded by knowing their modelname,
+ premium account files can only be downloaded by authenticated users -->
+<ul>
+<li>Users can upload and search for files</li>
+<li>Register to upload private files</li>
+<li>Uploaded files are analyzed and information is returned to the user</li>
+</ul>
+</section>
+ </div>
+ <div class="slide hidden -" id="slide-6">
+ <section class="slide-content"><!-- Sample interaction demonstrating how you would retrieve a file you uploaded -->
+<p><img src="media/search.gif" alt="FileSearch"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-7">
+ <section class="slide-content"><h3 id="1-vuln-">1. Vuln 💉</h3>
+<ul>
+<li>Flags are stored in the solidname of the STL</li>
+<li>Bug in upload info file parsing allows attacker to retrieve any public file</li>
+</ul>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-8">
+ <section class="slide-content"><h3 id="2-vuln-">2. Vuln 💉</h3>
+<ul>
+<li>Flags are stored in the solidname of a private file</li>
+<li>Buffer overflow in hash function allows enumeration of private user hashes</li>
+<li>Generate preimages of weak hash function to login as users</li>
+</ul>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-9">
+ <section class="slide-content"><h3 id="goals-met-">Goals Met 🎉</h3>
+<!-- dont need to be an expert at fancy exploitation to exploit,
+ just basic knowledge of C and testing code snippets to see
+ if they do what you expect them to in different cases -->
+<p>⭐ Plaintext file inspection service <br>
+⭐ Interesting and realisitic bugs <br>
+⭐ Combine different gadgets for exploit <br>
+⭐ Don't need to be an expert at fancy ROP <br>
+⭐ No SLA lost in TestCTF <br>
+⭐ Written in C</p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-10">
+ <section class="slide-content"><h3 id="issues-">Issues 📉</h3>
+<!-- Currently, the exploits dont require you to understand the
+ STL file format, however, to make sure that the service
+ is working correctly, you need to inspect the code -->
+<!-- Still considering encoding of flags as STL, but want to
+ avoid -->
+<p>💥 Exploits not directly related to STL format <br>
+💥 (Eno)checker has memory leaks</p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-11">
+ <section class="slide-content"><h3 id="lesssons-learned">Lesssons Learned</h3>
+<!-- from the feedback I gathered, that not a lot of people write C code
+ often, but this also means it is a great opportunity for learning
+ something new. -->
+<ul>
+<li>Many exploits are not suited for A/D ctfs</li>
+<li>How to write a FSM format parser</li>
+<li>Be careful with casts in C</li>
+<li>People just <em>love</em> C services 🤡</li>
+</ul>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-12">
+ <section class="slide-content"></section>
+ </div>
+ <div class="slide hidden" id="slide-13">
+ <section class="slide-content"></section>
+ </div>
+ <div class="slide hidden" id="slide-14">
+ <section class="slide-content"><h1 id="exploit-1">Exploit 1</h1>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-15">
+ <section class="slide-content"><p><img src="media/exploit-1-1.png" alt="exploit-1-1"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-16">
+ <section class="slide-content"><p><img src="media/exploit-1-2.png" alt="exploit-1-2"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-17">
+ <section class="slide-content"><p><img src="media/exploit-1-3.png" alt="exploit-1-3"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-18">
+ <section class="slide-content"><p><img src="media/exploit-1-4.png" alt="exploit-1-4"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-19">
+ <section class="slide-content"><p><img src="media/exploit-1-5.png" alt="exploit-1-5"></p>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-20">
+ <section class="slide-content"><h1 id="exploit-2">Exploit 2</h1>
+</section>
+ </div>
+ <div class="slide hidden" id="slide-21">
+ <section class="slide-content"><p><img src="media/exploit-2-1.png" alt="exploit-2-1"></p>
+<script>
+ // var slide_headers = document.querySelectorAll(".slide-content > h3");
+ // for (var i = 0; i < slide_headers.length; i++) {
+ // var img = document.createElement('img')
+ // img.src = "logo.png";
+ // img.style = "height: 2.4ex; padding-right: 10px; float:right";
+ // slide_headers[i].append(img);
+ // }
+</script></section>
+ </div>
+
+
+
+ <script type="text/javascript">
+ /**
+ * Returns the current page number of the presentation.
+ */
+function currentPosition() {
+ return parseInt(document.querySelector('.slide:not(.hidden)').id.slice(6));
+}
+
+
+/**
+ * Navigates forward n pages
+ * If n is negative, we will navigate in reverse
+ */
+function navigate(n) {
+ var position = currentPosition();
+ var numSlides = document.getElementsByClassName('slide').length;
+
+ /* Positions are 1-indexed, so we need to add and subtract 1 */
+ var nextPosition = (position - 1 + n) % numSlides + 1;
+
+ /* Normalize nextPosition in-case of a negative modulo result */
+ nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1;
+
+ document.getElementById('slide-' + position).classList.add('hidden');
+ document.getElementById('slide-' + nextPosition).classList.remove('hidden');
+
+ updateProgress();
+ updateURL();
+ updateTabIndex();
+}
+
+
+/**
+ * Updates the current URL to include a hashtag of the current page number.
+ */
+function updateURL() {
+ try {
+ window.history.replaceState({} , null, '#' + currentPosition());
+ } catch (e) {
+ window.location.hash = currentPosition();
+ }
+}
+
+
+/**
+ * Sets the progress indicator.
+ */
+function updateProgress() {
+ var progressBar = document.querySelector('.progress-bar');
+
+ if (progressBar !== null) {
+ var numSlides = document.getElementsByClassName('slide').length;
+ var position = currentPosition() - 1;
+ var percent = (numSlides === 1) ? 100 : 100 * position / (numSlides - 1);
+ progressBar.style.width = percent.toString() + '%';
+ }
+}
+
+
+/**
+ * Removes tabindex property from all links on the current slide, sets
+ * tabindex = -1 for all links on other slides. Prevents slides from appearing
+ * out of control.
+ */
+function updateTabIndex() {
+ var allLinks = document.querySelectorAll('.slide a');
+ var position = currentPosition();
+ var currentPageLinks = document.getElementById('slide-' + position).querySelectorAll('a');
+ var i;
+
+ for (i = 0; i < allLinks.length; i++) {
+ allLinks[i].setAttribute('tabindex', -1);
+ }
+
+ for (i = 0; i < currentPageLinks.length; i++) {
+ currentPageLinks[i].removeAttribute('tabindex');
+ }
+}
+
+/**
+ * Determines whether or not we are currently in full screen mode
+ */
+function isFullScreen() {
+ return document.fullscreenElement ||
+ document.mozFullScreenElement ||
+ document.webkitFullscreenElement ||
+ document.msFullscreenElement;
+}
+
+/**
+ * Toggle fullScreen mode on document element.
+ * Works on chrome (>= 15), firefox (>= 9), ie (>= 11), opera(>= 12.1), safari (>= 5).
+ */
+function toggleFullScreen() {
+ /* Convenient renames */
+ var docElem = document.documentElement;
+ var doc = document;
+
+ docElem.requestFullscreen =
+ docElem.requestFullscreen ||
+ docElem.msRequestFullscreen ||
+ docElem.mozRequestFullScreen ||
+ docElem.webkitRequestFullscreen.bind(docElem, Element.ALLOW_KEYBOARD_INPUT);
+
+ doc.exitFullscreen =
+ doc.exitFullscreen ||
+ doc.msExitFullscreen ||
+ doc.mozCancelFullScreen ||
+ doc.webkitExitFullscreen;
+
+ isFullScreen() ? doc.exitFullscreen() : docElem.requestFullscreen();
+}
+
+document.addEventListener('DOMContentLoaded', function () {
+ // Update the tabindex to prevent weird slide transitioning
+ updateTabIndex();
+
+ // If the location hash specifies a page number, go to it.
+ var page = window.location.hash.slice(1);
+ if (page) {
+ navigate(parseInt(page) - 1);
+ }
+
+ document.onkeydown = function (e) {
+ var kc = e.keyCode;
+
+ // left, down, H, J, backspace, PgUp - BACK
+ // up, right, K, L, space, PgDn - FORWARD
+ // enter - FULLSCREEN
+ if (kc === 37 || kc === 40 || kc === 8 || kc === 72 || kc === 74 || kc === 33) {
+ navigate(-1);
+ } else if (kc === 38 || kc === 39 || kc === 32 || kc === 75 || kc === 76 || kc === 34) {
+ navigate(1);
+ } else if (kc === 13) {
+ toggleFullScreen();
+ }
+ };
+
+ if (document.querySelector('.next') && document.querySelector('.prev')) {
+ document.querySelector('.next').onclick = function (e) {
+ e.preventDefault();
+ navigate(1);
+ };
+
+ document.querySelector('.prev').onclick = function (e) {
+ e.preventDefault();
+ navigate(-1);
+ };
+ }
+});
+
+
+ </script>
+</body>
+</html>
diff --git a/documentation/slides/media/exploit-1-1.png b/documentation/slides/media/exploit-1-1.png
Binary files differ.
diff --git a/documentation/slides/media/exploit-1-2.png b/documentation/slides/media/exploit-1-2.png
Binary files differ.
diff --git a/documentation/slides/media/exploit-1-3.png b/documentation/slides/media/exploit-1-3.png
Binary files differ.
diff --git a/documentation/slides/media/exploit-1-4.png b/documentation/slides/media/exploit-1-4.png
Binary files differ.
diff --git a/documentation/slides/media/exploit-1-5.png b/documentation/slides/media/exploit-1-5.png
Binary files differ.
diff --git a/documentation/slides/media/exploit-2-1.png b/documentation/slides/media/exploit-2-1.png
Binary files differ.
diff --git a/documentation/slides/media/search.gif b/documentation/slides/media/search.gif
Binary files differ.
diff --git a/documentation/slides/media/socat.gif b/documentation/slides/media/socat.gif
Binary files differ.
diff --git a/documentation/slides/slides.md b/documentation/slides/slides.md
@@ -0,0 +1,184 @@
+title: STLDoctor
+output: index.html
+controls: false
+
+--
+
+<style>
+
+.footnote {
+ font-size: 16pt;
+ position: absolute;
+ color: gray;
+ bottom: 0px;
+ right: 0px;
+}
+
+.slide-content {
+ position: relative;
+}
+
+.slide-content > ul >li {
+ padding: 7px 0px;
+}
+
+.slide-content > p > img {
+ width: 100%;
+}
+
+</style>
+
+--
+
+# STLDoctor 💉
+
+--
+
+### The Plan 💡
+
+<!-- Familiar with C and wondered about non-standard
+ buffer-/integer overflow C bugs -->
+<!-- Plaintext file inspection service -->
+<!-- Interesting and realisitic bugs -->
+<!-- Written in C -->
+<!-- Have to combine 'gadgets' for exploit, but
+ as a logic bug, not RCE -->
+- Plaintext service
+- Interesting C bugs
+- Exploit logic bugs, not RCE
+- Learn about the STL format
+
+<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">
+
+--
+
+### Setup 🔧
+
+- C binary that communicates via `stdin` and `stdout`
+- Networking abstracted through hosting with `socat`
+- File system backend with periodic clean up
+
+
+
+--
+
+### Functionality 🎮
+
+<!-- file system backend separates user accounts and stl files location for non-guests -->
+<!-- guest account files can be downloaded by knowing their modelname,
+ premium account files can only be downloaded by authenticated users -->
+
+- Users can upload and search for files
+- Register to upload private files
+- Uploaded files are analyzed and information is returned to the user
+
+---
+
+<!-- Sample interaction demonstrating how you would retrieve a file you uploaded -->
+
+
+
+--
+
+### 1. Vuln 💉
+
+- Flags are stored in the solidname of the STL
+- Bug in upload info file parsing allows attacker to retrieve any public file
+
+--
+
+### 2. Vuln 💉
+
+- Flags are stored in the solidname of a private file
+- Buffer overflow in hash function allows enumeration of private user hashes
+- Generate preimages of weak hash function to login as users
+
+--
+
+### Goals Met 🎉
+
+<!-- dont need to be an expert at fancy exploitation to exploit,
+ just basic knowledge of C and testing code snippets to see
+ if they do what you expect them to in different cases -->
+
+⭐ Plaintext file inspection service <br>
+⭐ Interesting and realisitic bugs <br>
+⭐ Combine different gadgets for exploit <br>
+⭐ Don't need to be an expert at fancy ROP <br>
+⭐ No SLA lost in TestCTF <br>
+⭐ Written in C
+
+--
+
+### Issues 📉
+
+<!-- Currently, the exploits dont require you to understand the
+ STL file format, however, to make sure that the service
+ is working correctly, you need to inspect the code -->
+
+<!-- Still considering encoding of flags as STL, but want to
+ avoid -->
+
+💥 Exploits not directly related to STL format <br>
+💥 (Eno)checker has memory leaks
+
+--
+
+### Lesssons Learned
+
+<!-- from the feedback I gathered, that not a lot of people write C code
+ often, but this also means it is a great opportunity for learning
+ something new. -->
+
+- Many exploits are not suited for A/D ctfs
+- How to write a FSM format parser
+- Be careful with casts in C
+- People just *love* C services 🤡
+
+--
+
+--
+
+--
+
+# Exploit 1
+
+--
+
+
+
+--
+
+
+
+--
+
+
+
+--
+
+
+
+--
+
+
+
+--
+
+# Exploit 2
+
+--
+
+
+
+
+
+<script>
+ // var slide_headers = document.querySelectorAll(".slide-content > h3");
+ // for (var i = 0; i < slide_headers.length; i++) {
+ // var img = document.createElement('img')
+ // img.src = "logo.png";
+ // img.style = "height: 2.4ex; padding-right: 10px; float:right";
+ // slide_headers[i].append(img);
+ // }
+</script>
diff --git a/documentation/slides/stldoctor.pdf b/documentation/slides/stldoctor.pdf
Binary files differ.