User Namespace

Support HackTricks

Basic Information

Ένα user namespace είναι μια δυνατότητα του πυρήνα Linux που παρέχει απομόνωση των αναγνωριστικών χρηστών και ομάδων, επιτρέποντας σε κάθε user namespace να έχει το δικό του σύνολο αναγνωριστικών χρηστών και ομάδων. Αυτή η απομόνωση επιτρέπει σε διαδικασίες που εκτελούνται σε διαφορετικά user namespaces να έχουν διαφορετικά προνόμια και ιδιοκτησία, ακόμη και αν μοιράζονται τα ίδια αναγνωριστικά χρηστών και ομάδων αριθμητικά.

Τα user namespaces είναι ιδιαίτερα χρήσιμα στην κοντεντοποίηση, όπου κάθε κοντέινερ θα πρέπει να έχει το δικό του ανεξάρτητο σύνολο αναγνωριστικών χρηστών και ομάδων, επιτρέποντας καλύτερη ασφάλεια και απομόνωση μεταξύ των κοντέινερ και του συστήματος φιλοξενίας.

How it works:

  1. Όταν δημιουργείται ένα νέο user namespace, ξεκινά με ένα κενό σύνολο αναγνωριστικών χρηστών και ομάδων. Αυτό σημαίνει ότι οποιαδήποτε διαδικασία εκτελείται στο νέο user namespace θα έχει αρχικά κανένα προνόμιο εκτός του namespace.

  2. Τα αναγνωριστικά μπορούν να καθοριστούν μεταξύ των αναγνωριστικών χρηστών και ομάδων στο νέο namespace και εκείνων στο γονικό (ή κεντρικό) namespace. Αυτό επιτρέπει στις διαδικασίες στο νέο namespace να έχουν προνόμια και ιδιοκτησία που αντιστοιχούν σε αναγνωριστικά χρηστών και ομάδων στο γονικό namespace. Ωστόσο, τα αναγνωριστικά μπορούν να περιοριστούν σε συγκεκριμένα εύρη και υποσύνολα αναγνωριστικών, επιτρέποντας λεπτομερή έλεγχο των προνομίων που χορηγούνται σε διαδικασίες στο νέο namespace.

  3. Μέσα σε ένα user namespace, οι διαδικασίες μπορούν να έχουν πλήρη προνόμια root (UID 0) για λειτουργίες μέσα στο namespace, ενώ εξακολουθούν να έχουν περιορισμένα προνόμια εκτός του namespace. Αυτό επιτρέπει στα κοντέινερ να εκτελούνται με δυνατότητες παρόμοιες με του root μέσα στο δικό τους namespace χωρίς να έχουν πλήρη προνόμια root στο σύστημα φιλοξενίας.

  4. Οι διαδικασίες μπορούν να μετακινηθούν μεταξύ namespaces χρησιμοποιώντας την κλήση συστήματος setns() ή να δημιουργήσουν νέα namespaces χρησιμοποιώντας τις κλήσεις συστήματος unshare() ή clone() με την σημαία CLONE_NEWUSER. Όταν μια διαδικασία μετακινείται σε ένα νέο namespace ή δημιουργεί ένα, θα αρχίσει να χρησιμοποιεί τα αναγνωριστικά χρηστών και ομάδων που σχετίζονται με αυτό το namespace.

Lab:

Create different Namespaces

CLI

sudo unshare -U [--mount-proc] /bin/bash

Με την τοποθέτηση μιας νέας παρουσίας του συστήματος αρχείων /proc αν χρησιμοποιήσετε την παράμετρο --mount-proc, διασφαλίζετε ότι η νέα namespace τοποθέτησης έχει μια ακριβή και απομονωμένη άποψη των πληροφοριών διαδικασίας που είναι συγκεκριμένες για αυτή τη namespace.

Σφάλμα: bash: fork: Cannot allocate memory

Όταν εκτελείται το unshare χωρίς την επιλογή -f, προκύπτει ένα σφάλμα λόγω του τρόπου που το Linux διαχειρίζεται τις νέες namespaces PID (Process ID). Οι βασικές λεπτομέρειες και η λύση περιγράφονται παρακάτω:

  1. Εξήγηση Προβλήματος:

  • Ο πυρήνας του Linux επιτρέπει σε μια διαδικασία να δημιουργήσει νέες namespaces χρησιμοποιώντας την κλήση συστήματος unshare. Ωστόσο, η διαδικασία που ξεκινά τη δημιουργία μιας νέας namespace PID (αναφερόμενη ως η διαδικασία "unshare") δεν εισέρχεται στη νέα namespace; μόνο οι παιδικές της διαδικασίες το κάνουν.

  • Η εκτέλεση %unshare -p /bin/bash% ξεκινά το /bin/bash στην ίδια διαδικασία με το unshare. Ως εκ τούτου, το /bin/bash και οι παιδικές του διαδικασίες βρίσκονται στην αρχική namespace PID.

  • Η πρώτη παιδική διαδικασία του /bin/bash στη νέα namespace γίνεται PID 1. Όταν αυτή η διαδικασία τερματίσει, ενεργοποιεί την καθαριότητα της namespace αν δεν υπάρχουν άλλες διαδικασίες, καθώς το PID 1 έχει τον ειδικό ρόλο της υιοθέτησης ορφανών διαδικασιών. Ο πυρήνας του Linux θα απενεργοποιήσει στη συνέχεια την κατανομή PID σε αυτή τη namespace.

  1. Συνέπεια:

  • Η έξοδος του PID 1 σε μια νέα namespace οδηγεί στον καθαρισμό της σημαίας PIDNS_HASH_ADDING. Αυτό έχει ως αποτέλεσμα τη αποτυχία της συνάρτησης alloc_pid να κατανεμηθεί ένα νέο PID κατά τη δημιουργία μιας νέας διαδικασίας, παράγοντας το σφάλμα "Cannot allocate memory".

  1. Λύση:

  • Το πρόβλημα μπορεί να επιλυθεί χρησιμοποιώντας την επιλογή -f με το unshare. Αυτή η επιλογή κάνει το unshare να δημιουργήσει μια νέα διαδικασία μετά τη δημιουργία της νέας namespace PID.

  • Η εκτέλεση %unshare -fp /bin/bash% διασφαλίζει ότι η εντολή unshare γίνεται PID 1 στη νέα namespace. Το /bin/bash και οι παιδικές του διαδικασίες είναι τότε ασφαλώς περιορισμένες μέσα σε αυτή τη νέα namespace, αποτρέποντας την πρόωρη έξοδο του PID 1 και επιτρέποντας την κανονική κατανομή PID.

Διασφαλίζοντας ότι το unshare εκτελείται με την επιλογή -f, η νέα namespace PID διατηρείται σωστά, επιτρέποντας στο /bin/bash και τις υπο-διαδικασίες του να λειτουργούν χωρίς να αντιμετωπίζουν το σφάλμα κατανομής μνήμης.

Docker

docker run -ti --name ubuntu1 -v /usr:/ubuntu1 ubuntu bash

Για να χρησιμοποιήσετε το user namespace, ο Docker daemon πρέπει να ξεκινήσει με --userns-remap=default (Στο ubuntu 14.04, αυτό μπορεί να γίνει τροποποιώντας το /etc/default/docker και στη συνέχεια εκτελώντας sudo service docker restart)

Ελέγξτε σε ποιο namespace βρίσκεται η διαδικασία σας

ls -l /proc/self/ns/user
lrwxrwxrwx 1 root root 0 Apr  4 20:57 /proc/self/ns/user -> 'user:[4026531837]'

Είναι δυνατόν να ελέγξετε τον χάρτη χρηστών από το κοντέινερ docker με:

cat /proc/self/uid_map
0          0 4294967295  --> Root is root in host
0     231072      65536  --> Root is 231072 userid in host

Ή από τον κεντρικό υπολογιστή με:

cat /proc/<pid>/uid_map

Βρείτε όλα τα User namespaces

sudo find /proc -maxdepth 3 -type l -name user -exec readlink {} \; 2>/dev/null | sort -u
# Find the processes with an specific namespace
sudo find /proc -maxdepth 3 -type l -name user -exec ls -l  {} \; 2>/dev/null | grep <ns-number>

Είσοδος σε ένα User namespace

nsenter -U TARGET_PID --pid /bin/bash

Επίσης, μπορείτε μόνο να εισέλθετε σε άλλο namespace διαδικασίας αν είστε root. Και δεν μπορείτε να εισέλθετε σε άλλο namespace χωρίς έναν περιγραφέα που να δείχνει σε αυτό (όπως το /proc/self/ns/user).

Δημιουργία νέου User namespace (με αντιστοιχίσεις)

unshare -U [--map-user=<uid>|<name>] [--map-group=<gid>|<name>] [--map-root-user] [--map-current-user]
# Container
sudo unshare -U /bin/bash
nobody@ip-172-31-28-169:/home/ubuntu$ #Check how the user is nobody

# From the host
ps -ef | grep bash # The user inside the host is still root, not nobody
root       27756   27755  0 21:11 pts/10   00:00:00 /bin/bash

Ανάκτηση Δυνατοτήτων

Στην περίπτωση των namespaces χρηστών, όταν δημιουργείται ένα νέο namespace χρηστών, η διαδικασία που εισέρχεται στο namespace αποκτά ένα πλήρες σύνολο δυνατοτήτων εντός αυτού του namespace. Αυτές οι δυνατότητες επιτρέπουν στη διαδικασία να εκτελεί προνομιακές λειτουργίες όπως mounting filesystems, δημιουργία συσκευών ή αλλαγή ιδιοκτησίας αρχείων, αλλά μόνο εντός του πλαισίου του namespace χρηστών της.

Για παράδειγμα, όταν έχετε τη δυνατότητα CAP_SYS_ADMIN εντός ενός namespace χρηστών, μπορείτε να εκτελείτε λειτουργίες που συνήθως απαιτούν αυτή τη δυνατότητα, όπως το mounting filesystems, αλλά μόνο εντός του πλαισίου του namespace χρηστών σας. Οποιεσδήποτε λειτουργίες εκτελείτε με αυτή τη δυνατότητα δεν θα επηρεάσουν το σύστημα host ή άλλα namespaces.

Επομένως, ακόμη και αν η απόκτηση μιας νέας διαδικασίας μέσα σε ένα νέο namespace χρηστών θα σας δώσει όλες τις δυνατότητες πίσω (CapEff: 000001ffffffffff), στην πραγματικότητα μπορείτε μόνο να χρησιμοποιήσετε αυτές που σχετίζονται με το namespace (mount για παράδειγμα) αλλά όχι όλες. Έτσι, αυτό από μόνο του δεν είναι αρκετό για να ξεφύγετε από ένα Docker container.

# There are the syscalls that are filtered after changing User namespace with:
unshare -UmCpf  bash

Probando: 0x067 . . . Error
Probando: 0x070 . . . Error
Probando: 0x074 . . . Error
Probando: 0x09b . . . Error
Probando: 0x0a3 . . . Error
Probando: 0x0a4 . . . Error
Probando: 0x0a7 . . . Error
Probando: 0x0a8 . . . Error
Probando: 0x0aa . . . Error
Probando: 0x0ab . . . Error
Probando: 0x0af . . . Error
Probando: 0x0b0 . . . Error
Probando: 0x0f6 . . . Error
Probando: 0x12c . . . Error
Probando: 0x130 . . . Error
Probando: 0x139 . . . Error
Probando: 0x140 . . . Error
Probando: 0x141 . . . Error

<div data-gb-custom-block data-tag="hint" data-style='success'>

Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Support HackTricks</summary>

* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>

</div>

hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</div>

</details>

</div>

</details>

</div>

</details>

</div>

</details>

</div>

</details>

</div>

Last updated