Skip to main content
  1. Concetti/

Shell Environment - ambiente shell

·5 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

L'ambiente shell e' l'insieme di informazioni disponibili alla shell e ai processi che lancia. Include variabili d'ambiente (esportate, ereditate dai figli), variabili locali (solo la shell corrente), alias e funzioni. Ogni processo figlio riceve una copia dell'ambiente del padre al momento del lancio.

TL;DR
#

Quando apri un terminale, bash legge i file di startup e costruisce il tuo ambiente. Ogni programma che lanci eredita una copia di quell'ambiente.

file di startup (.bashrc, .profile)
         
         
    shell corrente
    ├── variabili locali     solo qui, non ereditati
    ├── variabili d'ambiente → esportate, ereditate dai figli
    ├── alias               → solo qui, non ereditati
    └── funzioni            → solo qui, non ereditate
         ▼ fork() + exec()
    processo figlio (es. python3, grep, ssh)
    └── riceve COPIA delle variabili d'ambiente
        NON riceve alias, funzioni, variabili locali

Variabili locali vs variabili d'ambiente
#

# Variabile locale — esiste solo nella shell corrente
x=5
echo $x          # 5
bash -c 'echo $x'   # nessun output — il figlio non la vede

# Variabile d'ambiente — esportata, visibile ai figli
export y=10
echo $y          # 10
bash -c 'echo $y'   # 10 — il figlio la vede

La differenza non e' dove viene definita, ma se e' stata marcata con export.


Le variabili d'ambiente principali
#

PATH      # directory dove cercare gli eseguibili, separate da :
HOME      # home directory dell'utente corrente (/home/barno)
USER      # nome utente corrente
SHELL     # shell in uso (/bin/bash o /usr/bin/zsh)
EDITOR    # editor di testo preferito (vim, nano)
LANG      # lingua e codifica (it_IT.UTF-8)
MANWIDTH  # larghezza output di man in caratteri
HISTSIZE  # numero di comandi tenuti in memoria nella sessione
PS1   # prompt principale — quello che vedi prima di ogni comando
PS2   # prompt secondario — continua su riga successiva (il >)
PS3   # prompt del comando select negli script bash. select è un costrutto per menu interattivi — PS3 è la domanda che viene mostrata all'utente.
PS4   # prompt del debug mode. Quando attivi set -x in bash per vedere ogni comando eseguito, PS4 è il prefisso che appare davanti a ogni riga di debug. Default è +.
# PS1 default su Ubuntu:
# barno@hostname:~$

# PS1 con orario — utile su server per correlare azioni con i log
export PS1="[\t] \u@\h:\w\$ "
# [\t] = orario HH:MM:SS
# \u   = username
# \h   = hostname
# \w   = directory corrente
# \$   = $ se utente normale, # se root

# Risultato:
# [07:14:32] barno@barno-server:~$

# PS1 con colori (quello che vedi su zsh/Oh My Zsh)
export PS1="\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ "
# \[\e[32m\] = verde
# \[\e[34m\] = blu
# \[\e[0m\]  = reset colore
Su server di produzione metti sempre l'orario nel PS1 — quando lavori su piu' server in parallelo con tmux, il timestamp nel prompt ti aiuta a correlare le tue azioni con i log di sistema senza dover fare date ogni volta.

Per renderlo permanente

# Aggiungi in ~/.bashrc
echo 'export PS1="[\t] \u@\h:\w\$ "' >> ~/.bashrc
source ~/.bashrc

Come viene costruito l'ambiente — i file di startup
#

L'ambiente non nasce dal nulla: bash legge file di configurazione in ordine preciso all'avvio, a seconda del tipo di sessione.

SHELL DI LOGIN (SSH, console TTY, su -)
─────────────────────────────────────────
/etc/profile          → globale, tutti gli utenti
    
    
~/.bash_profile       → personale, letto se esiste
~/.bash_login         → letto se .bash_profile non esiste
~/.profile            → letto se nessuno dei precedenti esiste
                         (default su Ubuntu  .bash_profile non c'e')
    
     di solito ~/.bash_profile chiama: source ~/.bashrc

SHELL NON-LOGIN (nuovo terminale in GUI, tmux)
───────────────────────────────────────────────
/etc/bash.bashrc      → globale, tutti gli utenti
    
    
~/.bashrc             → personale
Note

Su Ubuntu non esiste ~/.bash_profile di default. La shell di login legge ~/.profile, che a sua volta chiama ~/.bashrc. Tutto converge su ~/.bashrc — e' li' che metti alias e variabili personali.


PATH — come funziona la ricerca degli eseguibili
#

digiti: ls
  shell legge $PATH:
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
         ▼ cerca in ordine
  /usr/local/sbin/ls  → non esiste
  /usr/local/bin/ls   → non esiste
  /usr/sbin/ls        → non esiste
  /usr/bin/ls         → TROVATO → esegui

Se il comando non si trova in nessuna directory del PATH: bash: ls: command not found

# Dove si trova un eseguibile?
which ls        # /usr/bin/ls
which python3   # /usr/bin/python3

# Aggiungi una directory al PATH
export PATH=$PATH:/opt/nuovo-tool/bin

Perche' e' importante per il Blue Team
#

L'ambiente e' un vettore di attacco. Un attaccante che modifica i dotfile puo':

  • Ridefinire PATH per far eseguire un binario malevolo al posto di quello legittimo
  • Aggiungere LD_PRELOAD per iniettare una libreria in tutti i processi
  • Modificare EDITOR o PAGER per eseguire codice quando certi comandi vengono usati
  • Usare gli alias per nascondere processi o file
# Segnali da cercare in un sistema sospetto
printenv | grep -i "ld_preload\|ld_library"  # library hijacking
alias | grep -v "^alias ll\|^alias la"        # alias insoliti
cat ~/.bashrc | grep -v "^#"                  # modifiche ai dotfile

Scenario Reale
#

Un analista esamina un server compromesso. Trova in ~/.bashrc la riga export PATH=/tmp/.hidden:$PATH. La directory /tmp/.hidden/ contiene un binario chiamato sudo che raccoglie le password prima di passarle al sudo reale. Ogni volta che l'utente usa sudo, la sua password viene silenziosamente registrata. Il PATH modificato fa si' che la shell trovi il falso sudo prima di quello vero in /usr/bin/.

Dove l'ho incontrato
#

Collegato a
#

Related