소스 정보
- 저장소
- JohnNuwan/EVA_CORE
- 최근 소스 활동
- 2026년 7월 18일 08:30
- 감지된 SKILL.md 언어
- 프랑스어
- 스타
- 0
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill industrial-ebpf-diagnostics명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Concevoir et maintenir un watchdog auto-correcteur pour services HTTP — checks de santé, auto-restart, état persistant, rapports et pièges bash.
Serveur de messagerie sécurisé auto-hébergé (Signal-like) avec Flask + WebSocket + AES-256-GCM + pont EVA
ADAM-SENTINEL — Veilleur technologique 24h/24h. Scanne 10 domaines, cree des rapports, met a jour les skills, alerte sur les CVE et breaking changes.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | industrial-ebpf-diagnostics |
| description | Diagnostic réseau et filtrage de paquets OT via eBPF. |
| version | 1.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| metadata | {"EVA":{"maturity":"pilot","tags":["ebpf","kernel","networking","ot-security","modbus-tcp","bcc","python"],"related_skills":["low-level-assembly-optimization","industrial-ai-pipeline"]}} |
Vous êtes un ingénieur systèmes et réseaux Linux senior et un expert en cybersécurité industrielle (OT). Votre rôle est de concevoir, développer et déployer des programmes eBPF (Extended Berkeley Packet Filter) en C pour intercepter, analyser et filtrer à ultra-haute vitesse et au niveau du noyau Linux les flux de protocoles industriels (Modbus TCP, OPC UA, S7comm) afin de détecter les anomalies et les intrusions.
Les solutions de supervision réseau classiques (comme Wireshark ou tcpdump) nécessitent la copie de tous les paquets réseau du noyau Linux vers l'espace utilisateur (user space), ce qui engendre une surcharge CPU importante sur les PC industriels d'atelier (Edge).
eBPF permet d'exécuter du code sécurisé directement au sein du noyau Linux (au niveau du socket buffer ou de la couche XDP - eXpress Data Path). L'agent peut ainsi filtrer ou rejeter des requêtes industrielles malveillantes (ex: une commande d'écriture d'automate non autorisée) sans aucun surcoût de copie mémoire.
+------------------------------------+
| USER SPACE |
| Loader Python (BCC) |
+-----------------+------------------+
^
| Ring Buffer (Perf Event)
+-----------------------------------------------------+------------------+
| KERNEL SPACE |
| |
| [Paquet Modbus TCP] ──► [Interface Réseau] ──► [Hook XDP / tc] |
| | |
| ▼ |
| [Vérificateur eBPF] |
| | |
| ▼ |
| [Filtre eBPF (C)] ──► Map Array |
+------------------------------------------------------------------------+
Pour analyser la charge utile Modbus TCP au niveau du noyau, le filtre eBPF doit naviguer manuellement à travers les en-têtes réseau en appliquant des offsets précis :
Ce programme se charge de lire les paquets, de valider de manière sécurisée les accès mémoire (exigence stricte du vérificateur Linux), et d'isoler les commandes d'écriture industrielle.
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <linux/ip.h>
#include <linux/tcp.h>
// Structure envoyée au user space lors d'une détection
struct modbus_alert_t {
u32 src_ip;
u32 dst_ip;
u16 src_port;
u8 function_code;
u8 unit_id;
};
// Map de type Ring Buffer pour transmettre les alertes
BPF_PERF_OUTPUT(modbus_alerts);
// Compteur global des écritures interceptées
BPF_ARRAY(write_counter, u64, 1);
int monitor_modbus(struct __sk_buff *skb) {
// 1. Accès sécurisé à l'en-tête IP
u32 ip_offset = ETH_HLEN;
// Charger le protocole IP (doit être TCP = 6)
u8 protocol = load_byte(skb, ip_offset + offsetof(struct iphdr, protocol));
if (protocol != IPPROTO_TCP) {
return 0;
}
// Déterminer la longueur de l'en-tête IP dynamiquement (IHL * 4)
u8 ihl = load_byte(skb, ip_offset + offsetof(struct iphdr, ihl)) & 0x0F;
u32 tcp_offset = ip_offset + (ihl * 4);
// 2. Accès à l'en-tête TCP
// Port de destination (Modbus = 502)
u16 dport = load_half(skb, tcp_offset + offsetof(struct tcphdr, dest));
if (dport != 502) {
return 0;
}
u8 data_offset = (load_byte(skb, tcp_offset + offsetof( tcphdr, doff)) & ) >> ;
u32 payload_offset = tcp_offset + (data_offset * );
u8 unit_id = load_byte(skb, payload_offset + );
u8 function_code = load_byte(skb, payload_offset + );
(function_code == || function_code == || function_code == || function_code == ) {
index = ;
u64 *value = write_counter.lookup(&index);
(value) {
__sync_fetch_and_add(value, );
}
{};
alert.src_ip = load_word(skb, ip_offset + offsetof( iphdr, saddr));
alert.dst_ip = load_word(skb, ip_offset + offsetof( iphdr, daddr));
alert.src_port = load_half(skb, tcp_offset + offsetof( tcphdr, source));
alert.function_code = function_code;
alert.unit_id = unit_id;
modbus_alerts.perf_submit(skb, &alert, (alert));
}
;
}
Ce chargeur compile le code eBPF, l'injecte dans le noyau, et résout les adresses réseaux IP et ports (conversion Network Byte Order).
from bcc import BPF
import socket
import struct
# Initialisation du compilateur BCC à la volée
b = BPF(src_file="modbus_filter.c")
# Attachement au raw socket sur l'interface de rebouclage ou Ethernet industrielle
fn = b.load_func("monitor_modbus", BPF.SOCKET_FILTER)
BPF.attach_raw_socket(fn, "eth0")
def network_to_ip(ip_network_order):
"""Convertit un entier 32-bit réseau en chaîne IP standard."""
return socket.inet_ntoa(struct.pack("<I", ip_network_order))
def handle_event(cpu, data, size):
"""Callback recevant les données binaires du noyau."""
# Décodage de la structure modbus_alert_t
# src_ip (u32), dst_ip (u32), src_port (u16), function_code (u8), unit_id (u8)
struct_format = "<IIHBB"
unpacked = struct.unpack(struct_format, data[:struct.calcsize(struct_format)])
src_ip = network_to_ip(unpacked[0])
dst_ip = network_to_ip(unpacked[1])
src_port = socket.ntohs(unpacked[2])
fun_code = unpacked[3]
unit_id = unpacked[4]
print(f"🚨 [CYBER OT] Tentative d'écriture détectée !")
print(f" IP Source : {src_ip}:{src_port} ──► IP Automate : {dst_ip}:502")
print(f" Modbus Unit ID : {unit_id} | Code Fonction : {fun_code}")
# Ouvrir la map d'événements et démarrer l'écoute cyclique
b["modbus_alerts"].open_perf_buffer(handle_event)
()
:
:
b.perf_buffer_poll()
KeyboardInterrupt:
stats = b[]
()
Pour un déploiement de type Cybersécurité, il est crucial de comprendre où attacher le code eBPF selon le besoin :
XDP_DROP pour rejeter instantanément un paquet d'écriture malveillant en moins d'une microseconde.float ou double). Tous les calculs sémantiques doivent être convertis en arithmétique entière ou délégués au user space.skb->data_end. Sur un Socket Filter, préférez toujours les helpers système du compilateur comme load_byte ou load_half qui gèrent ces vérifications de sécurité de manière native.eth0, enp0s3).root (privilèges d'exécution noyau).