Write-up to Firejail

Write-up to Firejail #

Introduction #

According to the developers. Firejail is a SUID security sandbox based on Linux namespaces and seccomp-bpf There is unique about Firejail, as it essentially uses some kernel security technologies that are that are nested on top of each other. The advantage with this is that complexity for the user is reduced. They also offer preconfigured security profiles for many programs. programs.

Kernel technologies #

The kernel technologies are divided into 3 groups.

Front-end sandboxing technologies:

  • Mount namespace
  • PID namespace
  • Network namespace
  • Optional: chroot, overlayfs, netfilter

Back-end sandboxing technologies

  • seccomp-bpf
  • Linux capabilities
  • Optional: noroot user namespace, AppArmor

Kernel config technologies:

  • SUID

The back-end technologies take a support role and prevent the attacker from becoming root.

SUID should not normally be set, as then the program would run with the rights of the file owner and not with the rights of the user. However, in this case, the kernel must be configured and only then does the program drop root privileges. The SUID risk can be further minimized if the binary is assigned to a certain group and only a few users have access to it.

Firejail is designed for single-user systems, not for servers used by multiple users via SSH.

Usage #

Start #

Basically you always have to prefix the command with Firejail first and this works without any problems for common programs because the profiles are already available. Otherwise, a default profile is used.

Basically you always have to prepend Firejail to the command first and this works without any problems for common programs because the profiles are already available. Otherwise, a default profile is used.

firejail firefox

Configuration #

If all programs should run automatically in a Firejail, the command helps out:

sudo firecfg

This reads the /usr/share/application/*.desktop and copies it customized to $HOME/.local/share/applications/*.desktop, if the files contain absolute paths to the binary (e.g. with Chromium). Then it makes a symbolic link from /usr/local/bin/firefox to /usr/bin/firejail, so that console calls also run via firejail.

Monitoring #

With firejail --list and firejail --top you can see the running firejail programs. With firejail --tree the processes in each sandbox can be displayed.

Security Profiles #

The security profiles can be customized to e.g. share folders.

The provided profiles are located under /etc/firejail and customizations should be done under ~/.config/firejail. An include can then be added to the original file with include /etc/firejail/[...] if you do not want to redo everything. should be done.

The customization of the profiles requires some practice and is in some places like in Creating overrides, Building Custom Profiles and Creating Profiles.

There is blacklisting and whitelisting. Note that with whitelisting a temporary filesystem is bind-mounted, so the changes are discarded when the sandbox is closed unless the folder already existed.

The rule is like this:

  • blacklist: everything allowed except explicitly forbidden.
  • noblacklist: Ignore all following blacklists that affect the same path.
  • whitelist: forbid everything except path
  • nowhitelist: Ignore all following whitelists that affect the same path.

For new programs, profiles can also be created semi-automatically. But this does not work for example Chromium, because it increases the user permissions and so strace would not work.

firejail --build profile-file myprogram

Examples #

With a whitelisting, a noblacklist is often added as well to make it more persistent.

noblacklist ~/MyPictures
whitelist ~/MyPictures

Same with blacklisting:

nowhitelist ~/MyPictures
blacklist ~/MyPictures

There are many other settings that are useful.

ignore nou2f ## dadurch können U2F devices verwendet werden (z.B. im Browser)
ignore net ## aktiviert den Internet Zugriff, wenn er verboten war

Oft gemachte Fehler #

  • blacklist PATH
    PATH is still visible but not accessible. With whitelist they do not exist.

  • noblacklist ~/Documents/presentations blacklist ~/Documents
    does not work because noblacklist prevents it.

  • whitelisting in profiles for text editor.
    Does not work, because these are then discarded after the termination (Tmpfs on top of the original filesystem)

Testing firejail profiles #

cd ~
touch test

firejail --whitelist=~/test bash
## oder
firejail --profile=~/mySecurityProfile bash

echo "asdf" > test

Firejail audit #

Firejail also provides an audit facility. This can be done with a custom audit program or by default with faudit.

firejail --audit chromium

Firejail - Own IP stack #

firejail --net=eth0 firefox

This results in a new interface being created, and the jail now communicates via this interface (own network namespace). This interface also has its own MAC address and could have its own firewall.

DNS Rebinding und CNAME Cloaking #

By Cisco 91% of malware uses DNS for its attacks. So it is obvious to monitor and protect them.

Analogous to the instructions of Firejail, a DNS rebinding and CNAME cloaking protection should be implemented.

FDNS Setup #

sudo fdns --daemonize 
fdns --monitor 
firejail --dns=127.1.1.1 firefox &

FDNS Testing #

The domain local.learningplatform.ch points to localhost and can be used. Furthermore, some ad-heavy websites can be visited and it should say something like 1x tracker xxx, dropped should be displayed.

CNAME Cloaking #

A CNAME (Canonical Name) record in the Domain Name System (DNS) maps one domain name to another. This approach allows multiple services such as an FTP server and a web server, each running on different ports, to run from a single IP address.

Ad companies ask their customers to use a subdomain for data collection and tracking and to associate it with an external server via the CNAME DNS record.

A DNS server can detect CNAME cloaking by resolving the CNAME, then moving to another DNS record, which then points to an IP address. Firefox includes a stub DNS server that adblockers can target, Chrome does not provide a similar API.

DNS Rebinding #

The idea behind this is that an attacker has a DNS entry with a very short TTL. This can then be used to point to the victim’s local network or other content. Also, through clever timing, it would be possible to answer multiple DNS queries to the same domain, with different IPs. With the same domain, the SOP does not take effect.

The DNS server fdns prevents DNS entries that point to local IPs. Timing attacks are difficult to prevent because minimum TTL or IP pinning does not always work.

Thought ahead #

How can fdns be used to make IPv4 over DNS communication more difficult? The tool iodine can be used for testing.

Exercise - Hacking the developers #

The browser usually downloads an HTML file, which references many other sources to download, for example, library code. What would happen if this HTML requests localhost? This is the subject of the article by Bouke. E-Bay had scanned the user’s computer for security reasons. The details can be found on the website of Nullsweep.

The SOP prevents the reading of information from an origin “good” to the origin “bad”. Therefore, the attacker cannot read anything. However, sending is possible.

If the Firejail user opens a website that does not implement strict CSP (e.g. example.com), he can insert this JS code there and test if the request is sent to the local web server, which is to be started in the next step. Alternatively, the test can also be performed with curl.

fetch('http://localhost/movies.json')
  .then(response => response.json())
  .then(data => console.log(data));
async function postData(url = '', data = {}) {
  const response = await fetch(url, {
    method: 'POST', 
    headers: {
      'Content-Type': 'text/plain'
    },
    body: data
  });
  return response;
}

postData('http://localhost:8080', "42")
  .then(data => {
    console.log(data);
  });

The one-liner python3 -m http.server unfortunately does not support a post request.

Therefore another small server from Miel Donkers:

##!/usr/bin/env python3
"""
Very simple HTTP server in python for logging requests
Usage::
    ./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging

class S(BaseHTTPRequestHandler):
    def _set_response(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), 
                     str(self.headers))
        self._set_response()
        self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))

    def do_POST(self):
        content_length = int(self.headers['Content-Length']) ## <--- Gets the size of data
        post_data = self.rfile.read(content_length) ## <--- Gets the data itself
        logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
                str(self.path), str(self.headers), post_data.decode('utf-8'))

        self._set_response()
        self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))

def run(server_class=HTTPServer, handler_class=S, port=8080):
    logging.basicConfig(level=logging.INFO)
    server_address = ('', port)
    httpd = server_class(server_address, handler_class)
    logging.info('Starting httpd...\n')
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    logging.info('Stopping httpd...\n')

if __name__ == '__main__':
    from sys import argv

    if len(argv) == 2:
        run(port=int(argv[1]))
    else:
        run()

If the code is stored in the file server.py, the server can be started with python server.py 8080.

Test configuration #

curl http://localhost:8080/ ## funktioniert und wird geloggt
firejail --net=wlp2s0 curl https://www.google.ch/ ## funktioniert und gibt Ergebnis
firejail --net=wlp2s0 curl http://localhost:8080/ ## connection refused
firejail --net=wlp2s0 firefox ## und localhost ansurfen -> connection refused

Thought ahead #

Are other browser technologies also subject to the SOP? If not, would an exfiltration of the developer’s files (e.g. ssh keys, api secrets) possible? If the browser has no bugs no, because the file access is controlled by the user via a browser popup. Only after confirmation the access via JavaScript is possible. In 2015 according to a statement of Mozilla it was possible to read files.

Exercise - Firejail and a vulnerable program #

There was a PDF.js exploit in Firefox that could be used to read files. The exploit is available in Metasploit.

First the firefox downloaded and unpack it. Then the browser can be started with a double click on firefox.

Now another exploit, which is already integrated into Metasploit.

msfconsole
use auxiliary/gather/firefox_pdfjs_file_theft

options ## default: stiehlt passwd u. shadow, listen to world auf Port 8080

set FILES ...

RUN

A URL is now generated and displayed in the output e.g. http://0.0.0.0:8080/A3uJQWEdSha, which should be called in the vulnerable browser (e.g. http://localhost:8080/A3uJQWEdSha).

As you can now see in msfconsole, the files have been extracted.

Now firejail is to be installed with:

apt update
apt install firejail

Subsequently, the browser can be started:

cd firefox ## wechsle in den firefox Ordner
firejail --private-home=/home/hacker/firefox bash ## mache ein privates Home mit dem firefox Ordner 
firejail ./firefox 

This is so awkward because we have a browser in the PATH, and otherwise it would start. What happens if this is started anyway and file:/// is navigated to? Which files should be seen?

Now the exploit should be executed again. What was extracted? Nothing.

Calendar August 22, 2023