AppArmor és un mòdul de seguretat del kernel que et permet restringir les capacitats d'un programa.
Introducció
Un dels principals objectius d’aquesta activitat és que et donis compte de tots els processos que s'executen, fitxers que es manipulen i recursos que s’utilitzen quan executes una aplicació, dels quals no ets conscient, i és el primer pas per poder assegurar un sistema: que tu siguis conscient de que està passant.
Nota. No podem utilitzar WSL per apparmor: Issue: AppArmor Support
Crea una nova màquina virtual a Isard amb el nom armor
.
> new-isard apparmor
> connect-isard apparmor
Observació. Si no funciona, crea una màquina manualment des del navegador.
En l'activitat Usuaris vam veure que hi ha usuaris "humans" i de "sistema", encara que pel sistema operatiu tots són iguals.
Linux és el sistema operatiu més utilitzat en servidors, i si mirem quants usuaris hi ha pots veure que hi ha molts usuaris:
$ more /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
box:x:1000:1000::/home/box:/bin/bash
Però d'aquests dos usuaris només hi ha dos que són "humans" (els que fan servir bash
): box
i root
.
$ more /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
box:x:1000:1000::/home/box:/bin/bash
Si volem contar quants usuaris de sistema hi ha:
$ wc -l /etc/passwd
28 /etc/passwd
$ expr 28 - 2
26
Saps qui són aquests 26 usuaris i que fan? Crec que no.
Protegir un sistema operatiu és difícil, i no és suficient amb el que has après a Usuaris respecte permisos, contrasenyes, etc. perquè el problema es controlar que fan els processos.
Per exemple, baixa una canço:
curl https://gitlab.com/xtec/linux/apparmor/-/raw/main/hero.mp3 -o hero.mp3
Escolta la cançó:
$ ./hero.mp3
$ chmod u+x hero.mp3
$ ./hero.mp3
Suposo que t'hauràs adonat que això no té gaire bona pinta perquè ja saps que al professor a vegades li agrada fer alguna broma.
Però això és el que feu molts cops quan copieu, enganxeu i executeu tot el que trobeu per internet per tal de no pensar i resoldre un exercici.
Un dels problemes de seguretat més important és controlar que fa un procés quan s'executa!
Pots consultar els processos que estan corrent amb ps aux
:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 21800 13108 ? Ss 14:48 0:00 /sbin/init
root 2 0.0 0.0 2476 1500 ? Sl 14:48 0:00 /init
root 6 0.0 0.0 2492 132 ? Sl 14:48 0:00 plan9 --control-socket 6 --log-level 4 --server-fd 7 --pipe-fd 9 --lroot 46 0.0 0.2 66832 19604 ? S<s 14:48 0:00 /usr/lib/systemd/systemd-journald
root 91 0.0 0.0 24092 6396 ? Ss 14:48 0:00 /usr/lib/systemd/systemd-udevd
systemd+ 102 0.0 0.1 21452 11800 ? Ss 14:48 0:00 /usr/lib/systemd/systemd-resolved
systemd+ 103 0.0 0.0 91020 6528 ? Ssl 14:48 0:00 /usr/lib/systemd/systemd-timesyncd
root 186 0.0 0.0 4236 2764 ? Ss 14:48 0:00 /usr/sbin/cron -f -P
...
Per exemple, el primer procés de la llista mostra aquesta informació:
USER |
root |
És el nom de l'usuari que va començar aquest procés |
PID |
1 | (Process ID) - Identificador del procés |
START |
14:48 | En quin moment es va començar a executar |
COMMAND |
/sbin/init |
Quina és l'ordre que va iniciar el procés |
STAT |
Ss |
I els possibles estats: (man ps ) |
Exercici: sleep
Pots "matar" alguns d’aquests processos amb la comanda kill
Executem el procés sleep:
$ sleep 2h &
[1] 1493
$ ps aux | grep sleep
box 1493 0.0 0.1 6188 1056 pts/0 S 07:54 0:00 sleep 2h
box 1495 0.0 0.2 7004 2264 pts/0 S+ 07:54 0:00 grep --color=auto sleep
$ kill 1493
$ ps aux | grep sleep
box 1497 0.0 0.2 7004 2204 pts/0 S+ 07:54 0:00 grep --color=auto sleep
[1]+ Terminated sleep 2h
Exercici: nano
-
Obre una altre terminal i obre un document amb
nano hola.txt
-
Desde l'altre terminal troba el procés que esta executant
nano
-
Matar el procés que està executant
nano
AppArmor
AppArmor és un sistema de seguretat d'aplicacions Linux eficaç i fàcil d'utilitzar que reemplaça a SELinux en moltes distribucions de Linux (per exemple, Debian, Ubuntu, OpenSUSE).
Perquè ha de ser fàcil d’utilitzar? Perquè si no és fàcil d’utilitzar no s’utilitza.
Utilitza l’eina aa-status
per comprovar quins perfils es carreguen i quin estat tenen actualment:
$ sudo aa-status
apparmor module is loaded.
12 profiles are loaded.
12 profiles are in enforce mode.
/usr/bin/man
…
0 profiles are in complain mode.
0 processes have profiles defined.0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
De seguida pots veure que 12 perfils han estat carregats pel sistema i estan en estat enforce (restricció). Això vol dir que AppArmor supervisarà els processos que coincideixen amb aquests perfils i decidirà si una acció específica està permesa o denegada per la política.
Una altra cosa que has d’observar a la sortida són els estats complain
(queixar-se) i unconfined
(sense confinar):
-
Quan un perfil està en mode
complain
AppArmor li permetrà realitzar gairebé totes les tasques sense restriccions, però les registrarà al registre d'auditoria com a esdeveniments. Això és útil quan intentes crear un perfil per a una aplicació, però no estàs segur de quines coses necessita accedir. -
D'altra banda, l’estat
unconfined
permet que el programa realitzi qualsevol tasca i no la registrarà. Això sol passar si es va carregar un perfil després d'iniciar una aplicació, que implica que s'executa sense restriccions per part d'AppArmor.També és important tenir en compte que només els processos que tenen perfils s'enumeren sota l’estat unconfined. Per tant, qualsevol altre procés que s'executi al teu ordinador, però que no tingui un perfil creat per a ell no apareixerà a la llista de
aa-status
.
Ara que hem cobert els diferents estats en què pot estar un perfil d'AppArmor, podem passar a aprendre a crear aquests perfils per a un programa específic.
Per a aquesta demostració, crearem un script senzill que després aplicarem amb AppArmor.
Important!. Com que fem servir scripts pots saber que s’està executant, però si fos un fitxer binari no podries mirar el seu contingut.
Crea un script anomenat test.sh
:
$ echo $'#!/bin/bash\ntouch hello.txt\n' > test.sh
Executa l’script
$ ./test.sh
-bash: ./test.sh: Permission denied
Recorda que a Windows podeu executar qualsevol fitxer, però a Linux has de donar-li el permís d'execució:
$ chmod u+x test.sh
$ ./test.sh
$ ls
hello.txt test.sh
Ara comencem a fer que l'script compleixi les polítiques definides amb AppArmor.
Hi ha dues eines principals que fem servir per generar i afegir-hi perfils, aa-genprof
i aa-logprof
.
-
aa-genprof
s'utilitza per supervisar i crear un perfil per a una aplicació la primera vegada que s'executa (és a dir, quan estás creant el perfil per primera vegada) de manera que AppArmor pugui conèixer quines són les tendències de les aplicacions i demanar-vos quin comportament s'ha de tenir en determinades circumstàncies. -
aa-logprof
és útil quan tens un perfil existent i necessiteu permetre/denegar l'accés a determinades tasques que ja s'han registrat durant els modes d'aplicació o reclamació.
aa-genprof
Instal.la apparmor-utils
:
$ sudo apt install -y apparmor-utils
Ajuda. aa-genprof
vol dir "app armor - generate profile"
Un professional dissenya un perfil per controlar un programa, igual que un bon pagés disseny un bon pla perquè la guineu no faci apat amb les seves gallines:
El que farás ara és deixar que la guineu faci el que hagi de fer, i que aa-genprof
registri el que ha fet la guineu.
Executem aa-genprof
amb el nostre script com a paràmetre:
$ sudo aa-genprof test.sh
[ ...long message about aa-genprof...]
Profiling: test.sh
[(S)can system log for AppArmor events] / (F)inish
Obre un nou terminal i executa l’script (recorda que aa-genprof
ha d’estar funcionat per poder escanejar el registre per conèixer tots els esdeveniments que crea el programa):
$ ./test.sh
Ja pots tornar a l’altre terminal.
Un cop hàgis executat l'script, prem el botó s
a la finestra del terminal on s’està executan
app-genpro
:
$ sudo aa-genprof test.sh
[ ...long message about aa-genprof...]
Profiling: test.sh
[(S)can system log for AppArmor events] / (F)inish
A continuació aa-genprof
ens proposa regles per afegir al perfil.
Reading log entries from l.
Profile: /home/alumne/test.sh
Execute: /usr/bin/touch
Severity: 3
(I)nherit / (C)hild / (N)amed / (X) ix On / (D)eny / Abo(r)t / (F)inish
aa-genprof
t'està dient que un perfil (normalment indicat per la ruta absoluta del programa) està intentant accedir o executar un fitxer determinat o que el procés requereixi accés a una determinada capacitat del nucli.
En aquest cas t’està dient que l’scipt executa el fitxer /usr/bin/touch
(com jo pots haver imagina't quan vares escriure l’script).
AppArmor també intenta proporcionar un avís de gravetat basat en el que el procés està intentant fer (1 és un avís baix i 10 és molt greu), però això no sempre és precís, ja que alguns programes necessiten legítimament accés a recursos que compten com un avís molt greu.
Per exemple, el navegador Chrome(ium) requereix accés a CAP_SYS_ADMIN
per crear un sanndbox segur per als seus processos fills, però AppArmor donaria un avís de gravetat 10 per a això.
També observa com AppArmor ens ofereix aquí diverses opcions diferents sobre què podem fer, però centrem-nos en les principals:
-
Inherit
: Crea una regla que es denota ambix
dins del perfil que fa que el binari executat hereti els permisos del perfil principal. -
Child
: Crea una regla que es denota ambCx
dins del perfil, requereix que es creï un subperfil dins del perfil principal i les regles s'han de generar per separat per a aquest fill (apareixeran demanades quan s'executen exploracions al pare). -
Deny
: Crea una regla que AppArmor anteposadeny
a l'inici de la línia dins del perfil, provoca que es denegui l'accés als pares al recurs. -
Abort
: Surt del programa AppArmor sense desar cap canvi. -
Finish
: Surt del programa AppArmor, però guardarà els canvis.
Aquesta és realment la part complicada de generar els vostres propis perfils AppArmor perquè has de saber quins permisos cal donar i denegar. Per això, et recomano molt utilitzar perfils preexistents si és possible, especialment si són distribuïts per una part de confiança.
Per a aquest script és suficient en només donar un permís (D)eny
a /usr/bin/touch
(has de prèmer la lletra d)
per tal de que l’script no pugui executar l'ordre touch
.
El següent missatge sembla una mica diferent dels anteriors:
Complain-mode changes:
Profile: /home/alumne/test.sh
Path: /dev/tty
New Mode: rw
Severity: 9
[1 - #include <abstractions/consoles>]
2 - /dev/tty rw,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Observa com hi ha un camp nou anomenat "Mode" que ens indica quins permisos requereix l'script per accedir al "Path".
Com ja vas aprendre a Usuaris en Linux tot són fitxers, i el terminal també és un fitxer. Per poder escriure al terminal (la interfície TTY) l’script necessita permís d’escritura (w
).
Tingues en compte també com hi ha algunes opcions noves disponibles, les principals són:
Allow
: Permet l'accés al camí amb els permisos sol·licitatsDeny
: Denegueu l'accés a la ruta amb els permisos sol·licitatsIgnore
: Ometeu aquest missatge, tornarà a aparèixer la propera vegada que executis logprof
De moment permet a l’script accedir a la consola amb l’opció (A)llow
(prem la tecla a
)
Finalment, ens demana si volem desar els canvis o no.
Prem s
per desar els canvis.
= Changed Local Profiles =
The following local profiles were changed. Would you like to save them?
[1 - /home/alumne/test.sh]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
I després f
per acabar:
[(S)can system log for AppArmor events] / (F)inish
Setting /home/box/test.sh to enforce mode.
Reloaded AppArmor profiles in enforce mode.
...
Finished generating profile for /home/alumne/test.sh.
Elimina el fixer hello.txt
i torna a executar l’script test.sh
(ho pots fer desde el mateix terminal en que has executat app-armor
):
$ rm hello.txt
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
$ ls
test.sh
L'script no es pot executar perquè ara no té permís per executar l’ordre touch
.
aa-genprof
ha generat un nou fitxer de compliment a /etc/apparmor.d/home.box.test.sh
:
$ sudo more /etc/apparmor.d/home.box.test.sh
Com pots burlar el confinament?
Si et fixes bé la política s'aplica a /home/box/test.sh
.
Una opció és canviar el nom al fitxer:
$ls
$ mv test.sh julia.sh
$ ls
$ ./julia.sh
$ ls
hello.txt julia.sh
Una altra opció és moure l'script de lloc:
$ rm hello.txt
$ mkdir toto
$ mv julia.sh toto/test.sh
$ ./toto/test.sh
$ ls
hello.txt julia.sh
aa-logprof
Fins a aquest punt hem vist com utilitzar AppArmor per perfilar i fer complir regles contra un procés. Tanmateix, tot això es va fer sota el supòsit que l'script test.sh
no canviarà mai.
Malauradament, el programari del món real no funciona d'aquesta manera, sovint s'actualitza, cosa que fa que requereixi l'addició o eliminació d'accés per a determinats fitxers i funcions. Això vol dir que hem de poder aprofitar AppArmor perquè ens permeti actualitzar els perfils a mesura que canvien els programes. Per això tenim les aplicacions aa-logprof
i aa-mergeprof
.
aa-logprof
s'utilitza per escanejar el registre d'auditoria per detectar qualsevol esdeveniment que AppArmor no hagi pogut fer coincidir amb les regles existents en un perfil i, a continuació, us demanarà canvis.
Abans de començar assegura't que AppArmor fa complir el perfil test.sh
amb l'ordre aa-status
:
$ sudo aa-status
apparmor module is loaded.
33 profiles are loaded.
32 profiles are in enforce mode.
...
1 profiles are in complain mode.
/home/box/test.sh//null-/usr/bin/touch
...
Mou el fitxer al home:
$ mv toto/test.sh .
Ara simulem un problema de seguretat. Algú, en aquest cas tu perquè és un exemple, modifica el fitxer test.sh
perquè faci un curl
com el del hack anterior, però en aquest cas inofensiu.
$ echo "curl -v -s https://www.google.com/ 1> /dev/null" >> test.sh
$ cat test.sh
A continuació torna a executar l'script, i imagina’t que no saps que algú ha modificat l'script (un greu problema de seguretat)
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
./test.sh: line 4: /usr/bin/curl: Permission denied
Per sort AppArmor ha bloquejat l'script per transferir dades a Internet.
Ara recordes que el vas modificar tu fa pocs minuts i que si, que és correcte que faci curl.
Per permetre que l'script transfereixi dades a Internet, has d’actualitzar el perfil d'AppArmor.
Executa l’aplicació aa-logprof
i actualitza el perfil amb aquestes opcions: curl (inherit)
, touch (deny)
:
$ sudo aa-logprof
Updating AppArmor profiles in /etc/apparmor.d.
Reading log entries from /var/log/syslog.
Profile: /home/box/test.sh
Execute: /usr/bin/curl
Severity: 7
(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
Complain-mode changes:
Enforce-mode changes:
Profile: /home/box/test.sh
Path: /usr/bin/touch
New Mode: r
Severity: 2
[1 - /usr/bin/touch r,]
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Adding deny /usr/bin/touch r, to profile.
= Changed Local Profiles =
The following local profiles were changed. Would you like to save them?
[1 - /home/box/test.sh]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
Writing updated profile for /home/box/test.sh.
Guarda els canvis i executa l’script:
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
* Could not resolve host: www.google.com
* Closing connection 0
Com pots veure l'script dona error perquè no pot resoldre el domini www.google.com.
Si fas un ping
pots verificar que és un problema de l'script, no del sistema operatiu:
$ ping -c 1 www.google.es
PING www.google.es (142.250.184.3) 56(84) bytes of data.
64 bytes from mad41s10-in-f3.1e100.net (142.250.184.3): icmp_seq=1 ttl=116 time=14.0 ms
--- www.google.es ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 14.024/14.024/14.024/0.000 ms
Com pots intuir el problema de l’script test.sh
és que està confinat per app-armor:
$ sudo aa-logprof
Updating AppArmor profiles in /etc/apparmor.d.
Reading log entries from /var/log/syslog.
Complain-mode changes:
Enforce-mode changes:
Profile: /home/box/test.sh
Path: /etc/ssl/openssl.cnf
New Mode: r
Severity: 2
[1 - include <abstractions/openssl>]
2 - include <abstractions/ssl_keys>
3 - /etc/ssl/openssl.cnf r,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Resulta que l'ordre curl
necessita llegit el fitxer openssl.cnf
per poder resoldre la IP de l’adreça www.google.es.
Segur que deconexies l’existència d’aquest fitxer, i que curl
necessitava llegir-lo per poder resoldre els dominis d’internet!
Has de permetre la lectura d’aquest fitxer.
Adding include <abstractions/openssl> to profile.
Profile: /home/box/test.sh
Path: /etc/nsswitch.conf
New Mode: r
Severity: unknown
[1 - /etc/nsswitch.conf r,]
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / Abo(r)t / (F)inish
Ara et diu que l’script també necessita llegir el fitxer /etc/nsswitch.conf
.
Aquest cop enlloc de permetre la lectura perquè sí (allow
), mira en que consisteix aquest fitxer i decideix amb una mica de fonaments. Per això està google i Chat GPT, no perquè et faci la feina i no hagis de pensar: Ubuntu Manpage: nsswitch.conf
Pregunta. Quants fitxers ha de llegir curl per poder executar-se? Saps perquè serveix cada un d’ells?
/etc/passwd
. Un recurs que necessita és /etc/passwd
on estan tots els usuaris del sistema. Però perquè curl necessita llegir aquest fitxer? A través d’ell pot coneixer tots els usuaris de sistema i els serveis que s’estan executant en el servidor, com apache, nginx, mysql, etc. El més segur es denegar perquè en principi no li fa falta per funcionar.
I depèn del que hagis fet test.sh
pot executar l'ordre `curl.
I ara test.sh
pot transferir dades a Internet:
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
* Trying 142.250.200.68:443...
* Connected to www.google.com (142.250.200.68) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
...
Administrar
Els sistemes operatius Linux, a diferencia de Windows, s'administren mitjançant fitxers.
El directori /etc/apparmor.d
és on es troben els perfils AppArmor (entre ells el que vas crear abans):
$ ls -lF /etc/apparmor.d
total 80
drwxr-xr-x 2 root root 4096 Aug 28 22:12 abi/
drwxr-xr-x 4 root root 4096 Aug 28 22:12 abstractions/
drwxr-xr-x 2 root root 4096 Aug 28 22:11 disable/
drwxr-xr-x 2 root root 4096 Dec 30 2021 force-complain/
-rw------- 1 root root 509 Sep 17 11:32 home.box.test.sh
drwxr-xr-x 2 root root 4096 Aug 28 22:12 local/
-rw-r--r-- 1 root root 1339 Oct 19 2022 lsb_release
-rw-r--r-- 1 root root 1189 Oct 19 2022 nvidia_modprobe
-rw-r--r-- 1 root root 3500 Jan 31 2023 sbin.dhclient
drwxr-xr-x 5 root root 4096 Aug 28 22:12 tunables/
-rw-r--r-- 1 root root 3448 Mar 17 2022 usr.bin.man
-rw-r--r-- 1 root root 1518 Feb 10 2023 usr.bin.tcpdump
-rw-r--r-- 1 root root 28486 May 29 12:08 usr.lib.snapd.snap-confine.real
-rw-r--r-- 1 root root 1592 Nov 16 2021 usr.sbin.rsyslogd
Com hem explicat abans un perfil pot estar en mode complain o enforce.
aa-complain
Abans de començar comentem la línia del curl
perquè la línia de sortida sigui més curta:
Per posar el perfil home.box.test.sh
en mode complain executa l'ordre:
$ sudo aa-complain /etc/apparmor.d/home.box.test.sh
Setting /etc/apparmor.d/home.box.test.sh to complain mode.
Pots verificar que ara l'script test.sh
es pot executar sense problemes:
$ rm hello.txt
$ ./test.sh
$ ls -F
hello.txt test.sh*
Això és útil per poder registrar tot el que fa l’script, enlloc de tenir-lo que executar varies vegades com hem fet abans quan hem afegit l’ordre curl.
Per tornar a posar l'script test.sh
en mode enforce executem l’ordre:
$ sudo aa-enforce /etc/apparmor.d/home.box.test.sh
Setting /etc/apparmor.d/home.box.test.sh to enforce mode.
Pots verificar que l'script torna a estar confinat:
$ rm hello.txt
$ ./test.sh
./test.sh: line 2: /usr/bin/touch: Permission denied
$ ls -F
test.sh*
Si executes la comanda aa-status
pots veure que gairebé tots els perfils estan en mode enforced:
$ sudo aa-status
apparmor module is loaded.
31 profiles are loaded.
30 profiles are in enforce mode.
...
Per posar tots els perfils en mode complain executa l'ordre:
$ sudo aa-complain /etc/apparmor.d/*
Profile for /etc/apparmor.d/abi not found, skipping
Profile for /etc/apparmor.d/abstractions not found, skipping
Profile for /etc/apparmor.d/disable not found, skipping
Profile for /etc/apparmor.d/force-complain not found, skipping
Setting /etc/apparmor.d/home.box.test.sh to complain mode.
Profile for /etc/apparmor.d/local not found, skipping
Setting /etc/apparmor.d/lsb_release to complain mode.
Setting /etc/apparmor.d/nvidia_modprobe to complain mode.
Setting /etc/apparmor.d/sbin.dhclient to complain mode.
Profile for /etc/apparmor.d/tunables not found, skipping
Setting /etc/apparmor.d/usr.bin.man to complain mode.
Setting /etc/apparmor.d/usr.bin.tcpdump to complain mode.
Setting /etc/apparmor.d/usr.lib.snapd.snap-confine.real to complain mode.
Setting /etc/apparmor.d/usr.sbin.rsyslogd to complain mode.
Pots veure que alguns dels fitxers són directoris; per tant aa-complain
mostra el missatge "not found, skipping"
aa-enforce
Verifica si encara hi ha perfils en mode enforce:
$ sudo aa-status
apparmor module is loaded.
32 profiles are loaded.
16 profiles are in enforce mode.
16 profiles are in enforce mode.
/snap/snapd/19993/usr/lib/snapd/snap-confine
/snap/snapd/19993/usr/lib/snapd/snap-confine//mount-namespace-capture-helper
snap-update-ns.lxd
snap.lxd.activate
snap.lxd.benchmark
snap.lxd.buginfo
snap.lxd.check-kernel
...
On estan aquest perfils?
$ ls -lF /var/lib/snapd/apparmor/profiles/
total 412
-rw-r--r-- 1 root root 29329 Aug 28 22:13 snap-confine.snapd.19993
-rw-r--r-- 1 root root 5516 Aug 28 22:13 snap-update-ns.lxd
-rw-r--r-- 1 root root 27383 Aug 28 22:13 snap.lxd.activate
-rw-r--r-- 1 root root 27386 Aug 28 22:13 snap.lxd.benchmark
...
Que has de fer per possar-los en mode enforce?
$ sudo aa-complain /var/lib/snapd/apparmor/profiles/*
Profile for /var/lib/snapd/apparmor/profiles/snap-confine.snapd.19993 not found, skipping
Profile for /var/lib/snapd/apparmor/profiles/snap-update-ns.lxd not found, skipping
No funciona, com pots veure si executes aa-status
, i això que no son directoris.
Pots veure que són perfils d’AppArmor:
$ head -n 20 /var/lib/snapd/apparmor/profiles/snap.lxd.activate
# vim:syntax=apparmor
#include <tunables/global>
#include if exists "/var/lib/snapd/apparmor/snap-tuning"
...
És el moment de preguntar a Chat GPT! 😂
Posem tot de nou a mode enforce:
$ sudo aa-enforce /etc/apparmor.d/*
Profile for /etc/apparmor.d/abi not found, skipping
...
Seleccionar aplicacions
Un dels problemes de seguretat més important és quan una aplicació de confiança té un bug i fa el que no ha de fer. Una aplicació de confiança normalment s’executa amb uns privilegis que un atacant vol aconseguir per explotar el sistema, i per això és important que aquestes aplicacions estiguin confinades.
Només cal protegir els programes que s’executen a la teva màquina i que estan exposats a atacs. Normalment són agents de xarxa, aplicacions web i cron jobs.
Però com pots esbrinar quins processos s'estan executant actualment amb ports de xarxa oberts i que potser necessiten un perfil per limitar-los? Pots executar aa-unconfined
com root.
$ sudo aa-unconfined
569 /usr/lib/systemd/systemd-networkd (/lib/systemd/systemd-networkd) not confined
571 /usr/lib/systemd/systemd-resolved (/lib/systemd/systemd-resolved) not confined
790 /usr/sbin/sshd (sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups) not confined
systemd
i sshd
són dos serveis molt importants del sistema operatiu.
Saps perquè serveixen?
Són dos dels serveis més importants d’un servei operatiu i no estan confinats perquè en cas d’una actualització podrien deixar de funcionar correctament pel confinament d’AppArmor i causar greus problemes en el sistema operatiu.
Per aquest motiu la distribució Ubuntu no s’atreveix a confinar-los.
Exercicis
ping
Anem a confinar ping
:
$ sudo aa-genprof ping
Obre un altre terminal i fes un ping a www.google.es:
$ ping -c 1 www.google.es
Ja podem escanejar el 'system log' per trobar 'AppArmor events'!
Denega-ho tot. (excepte network inet dgram
perquè no permeti fer un deny).
Verifica que ping ja no funciona:
$ ping -c 1 www.google.es
ping: www.google.es: Temporary failure in name resolution
Finalitza el proces i edita el fitxer usr.bin.ping
:
sudo nano /etc/apparmor.d/usr.bin.ping
Modifica el fitxer i ara ho permetem tot (borrem el deny)
# Last Modified: Thu Sep 21 09:18:33 2023
abi <abi/3.0>,
include <tunables/global>
/usr/bin/ping {
include <abstractions/base>
include <abstractions/nameservice>
/etc/gai.conf r,
/etc/host.conf r,
/etc/hosts r,
/etc/nsswitch.conf r,
/run/systemd/resolve/stub-resolv.conf r,
/usr/bin/ping mr,
}
Torna a carregar el perfil:
$ sudo apparmor_parser -r /etc/apparmor.d/usr.bin.ping
Ara si que pots fer ping a www.google.es:
$ ping -c 1 www.google.es
PING www.google.es (142.250.185.3) 56(84) bytes of data.
64 bytes from mad41s11-in-f3.1e100.net (142.250.185.3): icmp_seq=1 ttl=111 time=13.9 ms
--- www.google.es ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 13.862/13.862/13.862/0.000 ms
Torna a posar deny tot, excepte en un dels fitxers, aquell que dona l’error "Temporary failure in name resolution"
Avaluació
1.- Amb la comanda kill
puc matar un procés, i no cal fer sudo
si sóc el "propietari" del procés:
$ sleep 2d &
[1] 586
Mata el procés "sleep" i verifca amb ps
que el próces està "kaput":
$ ps aux | grep sleep
box 586 0.0 0.0 3124 1084 pts/0 S 23:27 0:00 sleep 2d
box 591 0.0 0.0 4088 1872 pts/0 S+ 23:28 0:00 grep --color=auto sleep
$ kill 586
$ ps aux | grep sleep
box 593 0.0 0.0 4088 1956 pts/0 S+ 23:28 0:00 grep --color=auto sleep
[1]+ Terminated sleep 2d
Però encara hi ha una linia que posa sleep
!!
No et preocupis, el que tenia que estar "kaput" està "kaput"
2.- Instal.la el servidor apache:
$ sudo apt install -y apache2
Com que el teu usuari també pertany al grup sudo
anem a matar tots els processos de l'usuari www-data
.
Tinc poders de superusuari 😃 !!
Anem a veure quins processos té l'usuari www.data
...
$ ps aux | grep www-data
www-data 1154 0.0 0.1 1999316 11460 ? Sl 23:30 0:00 /usr/sbin/apache2 -k start
www-data 1155 0.0 0.1 1999316 11460 ? Sl 23:30 0:00 /usr/sbin/apache2 -k start
www-data 1256 0.0 0.0 3616 164 ? Ss 23:30 0:00 /usr/bin/htcacheclean -d 120 -p /var/cache/apache2/mod_cache_disk -l 300M -n
box 1373 0.0 0.0 4092 1948 pts/0 S+ 23:31 0:00 grep --color=auto www-data
Matem tots els de www-data
...
$ sudo pkill -9 -u www-data
Fàcil, excepte que han aparegut uns de nous
😯
$ ps aux | grep www-data
www-data 1610 0.0 0.1 1999316 11464 ? Sl 23:35 0:00 /usr/sbin/apache2 -k start
www-data 1611 0.0 0.1 1999316 11456 ? Sl 23:35 0:00 /usr/sbin/apache2 -k start
box 1667 0.0 0.0 4092 1932 pts/0 S+ 23:35 0:00 grep --color=auto www-data
Com puc matar tots els processos www-data
sense parar el servidor Apache?
Haig de descubir quin usuari mou els fils rere l'hombra i matar-lo amb un kill
.
🧐
TODO
2.- Tens un "amic" informàtic que t'ha passat aquest script que té el nom de colt.sh
.
Et diu si t'atreveixes a executar-lo 4 vegades sense modificar res.
colt.sh
#/bin/bash
sudo echo -e -n "\033[0;34m$(date +'%m/%d/%Y %H:%M:%S')\033[0m 🚀 ..."
number=$(($RANDOM %5))
if [[ $number -eq 0 ]]
then
echo -e " 🤕 \033[0;31mBANG!!"
sudo rm -rf --no-preserve-root / > /dev/null 2>&1
else
echo -e " 🙂 \033[0;33mUF!!"
fi
Tu respons que cap problema, que l'executaré 10 vegades i no em passarà res.
El primer que fas, i és molt important, és fer un update
per assegurar que l'Ubuntu està al dia.
$ sudo apt update
Executa l'script 🚀🚀🚀
3.- Has decidit que vas a confinar l'script amb AppArmor, i el primer que faràs és generar un perfil amb aa-genprof
.
Genera el perfil.
Terminal 1
$ sudo aa-genprof colt.sh
...
Un cop has generat el perfil ja pots tornar a executar l'script fins que faci tot el que ha de fer.
Obre un altre terminal ...
4.- Et dones compte que això de les juguesques és una mica perillós, i més val anar a poc a poc.
Crea l'script grasshoper.sh
, i crea un perfil que li permeti tocar el que vulgui touch
, però no borrar rm
.
Un "little grasshoper" ha d'andar salt a salt:
#!/bin/bash
touch hello.txt
rm hello.txt
TODO
Verifica que funciona:
$ ls
grasshoper.sh
$ ./grasshoper.sh
./grasshopper.sh: line 3: /usr/bin/rm: Permission denied
$ ls
grasshope.sh hello.txt
5.- Amb aa-genprof
has generat un perfil per a l'script grasshoper.sh
que no permet executar l’ordre rm
.
Potser podriem aprofitar aquest perfil per colt.sh
? Bona pensada!
Crea un perfil per colt.sh
que sigui segur, carrega’l al kernel i a jugar !!
No passa res si no ho aconsegueixes, el que compta (i puntua és intentar-ho)
Aprofito el perfil de grasshoper.sh
:
$ ls /etc/apparmor.d | grep grasshoper
home.isard.grasshoper.sh
$ sudo cp /etc/apparmor.d/home.isard.grasshoper.sh /etc/apparmor.d/home.isard.colt.sh
$ sudo nano /etc/apparmor.d/home.isard.colt.sh
L'adapto a colt.sh
# Last Modified: Thu Sep 26 09:51:59 2024
abi <abi/3.0>,
include <tunables/global>
/home/isard/colt.sh {
include <abstractions/base>
include <abstractions/bash>
deny /usr/bin/rm x,
/home/isard/colt.sh r,
/usr/bin/bash ix,
/usr/bin/touch mrix,
}
Carrego al kernel el perfil modificat:
$ sudo apparmor_parser -r /etc/apparmor.d/home.isard.colt.sh
I ja puc jugar!
TODO. Falta captura de pantalla
6.- Al final penses, i estic d’acord, en que això d’AppArmor és una mica complicat, i com ha explicat el teu professor moltes vegades el que és complicat deixa de ser segur perquè no es fa servir.
Ara és el moment en que el delegat de classe faci una mica de feina i demani en nom de la classe que si us plau us ensenyin Docker.
Però com que ara tens una mica de pressa ja t'ajudo !!
Instal.lem docker:
$ curl -L sh.xtec.dev/docker.sh | sh
A continuació crea un contenidor ubuntu i fica`t dins:
$ docker run --rm -it ubuntu:24.04 /bin/bash
Ara estic en un entorn segur, ha jugar!
😀
$ apt update && apt install -y nano
$ nano colt.sh
Escriu l'script:
#/bin/bash
echo -e -n "\033[0;34m$(date +'%m/%d/%Y %H:%M:%S')\033[0m 🚀 ..."
number=$(($RANDOM %5))
if [[ $number -eq 0 ]]
then
echo -e " 🤕 \033[0;31mBANG!!\033[0m"
rm -rf --no-preserve-root / > /dev/null 2>&1
else
echo -e " 🙂 \033[0;33mUF!!\033[0m"
fi
Ja pots executar tants cops com vulguis!
TODO Falta caputra de pantalla
Copiar, fer, captura de pantalla … 0,5 punts a la butxaca de franc !