- Alert alle 2:47: processo
bashcon connessione aperta verso IP esterno su porta 4444 → reverse shell attiva ss -tnp | grep ESTABLISHEDidentifica il processo e il PID in tempo realetcpdump -i eth0 -n -Alegge il payload in chiaro: comandi dell'attaccante visibili direttamente- Prima di bloccare: raccogliere
history,auth.log,find -mmin -120- agire troppo presto distrugge le prove
▶ $ history

Sono le 2:47.
Lo schermo è l'unica luce nella stanza. Il telefono vibra sul tavolo - un alert automatico, il tipo che non mandi via con uno swipe.
Anomaly detected - unusual outbound traffic from 192.168.10.45
192.168.10.45. Il web server interno. Quello che di notte non dovrebbe parlare con nessuno.
Mi siedo.
Il primo segnale#
La prima cosa che faccio non è guardare i log. È guardare chi è connesso adesso, in questo momento, mentre l'alert è ancora caldo.
sudo ss -tnp | grep ESTABLISHEDTre righe. Due le riconosco. La terza no.
ESTAB 0 0 192.168.10.45:443 185.220.101.34:52341 users:(("nginx",pid=1337))
ESTAB 0 0 192.168.10.45:22 192.168.1.10:61291 users:(("sshd",pid=2891))
ESTAB 0 0 192.168.10.45:4444 185.220.101.34:80 users:(("bash",pid=3342))
# output simulatonginx sulla 443 - normale. sshd sulla 22 - sono io, connesso da prima. bash sulla 4444 verso un IP esterno sulla porta 80 - questo no.
Un processo bash non ha nulla da dire alla rete. Tantomeno a un IP che non riconosco, su una porta che non ho aperto io.
La connessione#
sequenceDiagram
participant A as Attaccante (185.220.101.34)
participant S as Server Vittima (192.168.10.45)
Note over S: bash (pid 3342) apre connessione verso l'esterno
S->>A: TCP SYN porta 4444 → porta 80
A->>S: SYN-ACK
S->>A: ACK - connessione stabilita
A->>S: [P.] "cat /etc/passwd"
S->>A: [P.] "root:x:0:0:root..."
Note over A,S: canale bidirezionale - comandi in entrata, output in uscita
Qualcuno ha stabilito una connessione persistente. Parte dal mio server, raggiunge una macchina esterna. Su quel canale passano comandi in chiaro.
Per leggere il traffico ho bisogno di catturarlo a livello di interfaccia di rete. Non i log applicativi - quelli non operano a questo livello. Ho bisogno di intercettare i pacchetti prima che vengano interpretati.
ip a
# verifico il nome dell'interfaccia - eth0
sudo tcpdump -i eth0 -n -A host 185.220.101.34Il flag -A mostra il payload in ASCII. Se il traffico non è cifrato, leggo tutto.
Pochi secondi. Poi arriva:
03:01:14 IP 185.220.101.34.80 > 192.168.10.45.4444: Flags [P.] length 18
....
cat /etc/passwd
03:01:14 IP 192.168.10.45.4444 > 185.220.101.34.80: Flags [P.] length 89
....
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/bin/nologin
barno:x:1000:1000::/home/barno:/bin/bash
# output simulatoIn chiaro. Tutto in chiaro.
Qualcuno sta leggendo il mio /etc/passwd in tempo reale, dal proprio terminale, seduto da qualche parte nel mondo.
Smetto di respirare per un secondo.
Prima di toccare qualsiasi cosa#
L'istinto dice: chiudi la connessione. Banna l'IP. Fai smettere.
Ma se lo faccio adesso, perdo le tracce. L'attaccante sa che è stato scoperto. Forse ha altre backdoor. Forse ha già scaricato quello che cercava.
Prima si raccoglie, poi si agisce.
# cosa ha fatto nella sessione
history
# quando e come è entrato
grep "185.220.101.34" /var/log/auth.log
# quali file ha toccato nelle ultime 2 ore
find / -mmin -120 -type f 2>/dev/nullI file modificati di recente raccontano una storia. history racconta un'altra. auth.log racconta quando è cominciato tutto.
Tre fonti. Tre angolazioni diverse dello stesso evento.
La chiusura#
graph TD
Alert["Alert 02:47\noutbound anomalo"] --> SS
SS["ss -tnp | grep ESTABLISHED\nidentifica il processo e il PID"]
SS --> |"bash su porta 4444\nnon è un servizio legittimo"| TCP
TCP["tcpdump -i eth0 -n -A\ncattura e legge il payload in chiaro"]
TCP --> |"traffico non cifrato\ncomandi visibili"| Raccolta
Raccolta["Raccolta prove\nprima di toccare qualsiasi cosa"]
Raccolta --> H["history\ncosa ha eseguito nella sessione"]
Raccolta --> AL["auth.log\nquando e come è entrato"]
Raccolta --> F["find / -mmin -120 -type f\nquali file ha modificato"]
H --> Kill
AL --> Kill
F --> Kill
Kill["kill -9 3342\ninterrompe il processo bash\nsenza avvisare l'attaccante"]
Kill --> |"connessione chiusa"| Block
Block["ufw deny from 185.220.101.34\nblocca l'IP a livello firewall\ningress e egress"]
Block --> Review
Review["analisi post-incidente\ncos'altro ha fatto?\nci sono altre backdoor?"]
Solo dopo aver raccolto tutto, agisco.
sudo kill -9 3342
sudo ufw deny from 185.220.101.34La connessione si chiude. Il processo bash muore. L'IP viene bloccato a livello firewall.
Il server torna silenzioso.
Sono le 3:22. Ho sudato freddo per trentacinque minuti davanti a uno schermo.
exit 0#
Non è stato un attacco sofisticato. È stato un processo bash aperto su una porta alta, traffico in chiaro, comandi leggibili con un flag di tcpdump.
La cosa che mi ha fermato non è stata la tecnica - è stato non agire d'istinto. Non chiudere subito. Raccogliere prima.
Un incidente gestito male non è quello che non riesci a bloccare. È quello che blocchi troppo presto, prima di capire quanto in profondità è arrivato.
Dietro le quinte#
Cos'è una reverse shell#
In una connessione normale, l'attaccante si connette al server vittima. Un firewall può bloccare le connessioni in entrata verso porte non autorizzate.
In una reverse shell, è il server vittima che si connette all'attaccante. Il traffico esce - e il firewall spesso lascia passare il traffico in uscita senza filtrarlo.
Connessione normale (bloccabile):
Attaccante ──────────────► Server (porta 22, 80, 443...)
FIREWALL blocca se porta chiusa
Reverse shell (bypassa il firewall):
Server ──────────────────► Attaccante (porta 80 - sembra traffico web)
FIREWALL vede traffico in uscita → lascia passareL'attaccante sceglie la porta 80 come destinazione per sembrare traffico HTTP legittimo.
I flag TCP nel traffico della shell#
Tutto il traffico tra server e attaccante usava [P.] - PSH+ACK. Il flag PSH dice al ricevente di consumare i dati immediatamente senza aspettare che il buffer si riempia. Tipico delle shell interattive dove ogni comando deve essere eseguito subito.
[S] → apertura connessione
[S.] → conferma connessione
[P.] → dati - comando in arrivo o output in uscita
[F.] → chiusura elegante
[R] → reset bruscoPerché auth.log non ha visto nulla#
auth.log registra eventi applicativi - login SSH, sudo, autenticazione PAM. Non vede il traffico di rete grezzo. Un processo bash che apre una connessione TCP verso l'esterno non lascia nessuna traccia in auth.log.
Solo tcpdump, che opera a livello di interfaccia di rete, ha visto tutto.
IoC generati#
| Tipo | Valore | Contesto | MITRE ATT&CK |
|---|---|---|---|
| IP | 185.220.101.34 | C2 server - reverse shell | T1071 - Application Layer Protocol |
| Processo | bash (pid 3342) | shell interattiva remota | T1059.004 - Unix Shell |
| Porta | 4444 | porta sorgente reverse shell | T1571 - Non-Standard Port |
| Tecnica | traffico in chiaro su porta 80 | evasione firewall | T1048.003 |
Checklist prevenzione#
- Monitorare connessioni in uscita inaspettate con
ss -tnpperiodicamente - Configurare firewall egress - non solo ingress. Il traffico in uscita va filtrato
- Loggare tutti i processi che aprono connessioni di rete (auditd)
- Abilitare alert su processi anomali che usano la rete (bash, sh, python su porte alte)
- Non lasciare traffico non cifrato su connessioni tra sistemi interni
Comandi usati: tcpdump, ss Concetti correlati: tcp-handshake, tcp-udp Tools: wireshark




