Il seguente perl
script usa il Digest::MD5
o Digest::SHA
modulo per trasformare un indirizzo MAC in un hash, utilizzando un salt segreto. Vedere le pagine man dei moduli per maggiori dettagli su di essi. Vale la pena notare che Digest::SHA ha molti altri algoritmi tra cui scegliere.
Il codice è scritto per semplificare la scelta di un diverso algoritmo di hashing:decommentane uno e commenta gli altri per scegliere quello che ti si addice meglio. A proposito, l'output del _base64
versioni delle funzioni è un po' più breve del _hex
funziona ma sembra più un rumore di linea.
Ho semplificato la tua regex fornita (non ho visto alcuna necessità di un look-behind). Potrebbe essere necessario modificarlo un po' per lavorare con i dati di input... non hai fornito alcun campione, quindi ho solo indovinato.
#!/usr/bin/perl
# choose one of the following digest modules:
use Digest::MD5 qw(md5_hex md5_base64);
#use Digest::SHA qw(sha256_hex sha256_base64);
use strict;
my $salt='secret salt phrase';
# store seen MAC addresses in a hash so we only have to calculate the digest
# for them once. This speed optimisation is only useful if the input file
# is large AND any given MAC address may be seen many times.
my %macs=();
while(<>) {
if (m/clientMac:\s*([A-Z0-9]{12})/i) {
my $mac = $1;
if (!defined($macs{$mac})) {
# choose one of the following digest conversions:
#my $uuid = sha256_hex($mac . $salt);
#my $uuid = sha256_base64($mac . $salt);
my $uuid = md5_hex($mac . $salt);
#my $uuid = md5_base64($mac . $salt);
$macs{$mac} = $uuid;
};
s/(clientMac:\s*)$mac/$1$macs{$mac}/gio;
};
print;
};
Come richiesto nel commento, ecco un esempio di come eseguire tale sostituzione con sed
. Hai usato il tag /linux, quindi dovrebbe essere sicuro usare GNU sed
con il suo e
flag per s
comando:
sed -E 'h;s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e;T
G;s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/' logfile
Spiegazione:
- Il
h
Il comando salva la riga nello spazio di attesa, quindi possiamo ripristinarla dopo aver incasinato la riga (-; s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e
corrisponde all'intera riga, inserendo il MAC effettivo in()
da riutilizzare nella sostituzione. La sostituzione forma il comando da eseguire:echo
inviando l'MCA insieme al "sale" e convogliandolo inmd5sum
. Ile
flag rendesed
eseguilo nella shell e inserisci nuovamente il risultato nel bufferT
si dirama alla fine dello script se non è stata effettuata alcuna sostituzione. Questo serve per stampare righe senza MAC non modificate. Le seguenti righe vengono eseguite solo se è stata effettuata una sostituzioneG
aggiunge la riga originale dal buffer di attesa, quindi ora abbiamo ilmd5sum
output, una nuova riga e la riga originale nel buffers/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/
acquisisce l'MD5 nella prima coppia di()
, la riga prima del MAC nel secondo e il resto della riga dopo il MAC nel terzo, quindi\2\1\3
sostituisce il MAC con l'MD5
Come approccio alternativo, a volte ho usato semplici numeri di riga come valore di offuscamento. Ciò rende l'output più compatto e più leggibile.
Inoltre, awk
è un ottimo strumento quando si devono eseguire operazioni "intelligenti" su un file di testo, avendo un linguaggio più leggibile di sed
. L'operazione "intelligente" da eseguire in questo caso è evitare di rieseguire l'algoritmo di offuscamento quando un qualsiasi indirizzo MAC viene rilevato più di una volta. Questo può velocizzare parecchio le operazioni se hai migliaia di righe che fanno riferimento a un piccolo numero di indirizzi MAC.
In pratica, considera il seguente script, che gestisce anche possibili indirizzi MAC multipli che si verificano su una qualsiasi riga, identificando e sostituendo ogni occorrenza e quindi stampando una tabella di mappatura alla fine:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v table='sort -k 1,1n | column -t' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
if (!($i in cache))
cache[$i]=NR "." i
$i = "MAC:" cache[$i]
}
}
1
END {
print "---Table: "FILENAME"\nnum MAC" | table
for (mac in cache)
print cache[mac], mac | table
}
' file.log
La tabella alla fine può essere facilmente separata dall'output principale mediante un ulteriore passaggio di modifica o semplicemente creando la stringa di comando nel -v table=
argomento reindirizza il suo output a un file, come in -v table='sort -k 1,1n | column -t > table'
. Può anche essere rimosso del tutto semplicemente rimuovendo l'intero END{ … }
blocco.
Come variante, utilizzando un vero motore di crittografia per calcolare i valori di offuscamento e quindi senza tabella di mappatura alla fine:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='openssl enc -aes-256-cbc -a -pass file:mypassfile' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
addr = cache[$i]
if (addr == "") {
"echo '\''" $i "'\'' | " crypter | getline addr
cache[$i] = addr
}
$i = "MAC:" addr
}
}
1
' file.log
Qui ho usato openssl
come motore di cifratura selezionando il suo aes-256-cbc
cifratura (con anche un output codificato in base64 per essere compatibile con il testo) e facendogli leggere il segreto di crittografia da un file chiamato mypassfile
.
Stringhe crittografate con un cifrario simmetrico (come aes-256-cbc
) può essere decifrato conoscendo il segreto utilizzato (il contenuto di mypassfile
, che vuoi tenere per te), quindi possono essere invertiti. Inoltre, poiché openssl
utilizza un salt casuale per impostazione predefinita, ogni esecuzione produce valori diversi per lo stesso input. Non usare un sale (opzione -nosalt
) renderebbe openssl
produrrebbe lo stesso valore per ogni esecuzione, quindi meno sicuro, ma d'altra parte produrrebbe testi più brevi pur rimanendo crittografati.
Lo stesso awk
script funzionerebbe per altri comandi esterni invece di openssl
semplicemente sostituendo il comando nel -v crypter=
argomento a awk
, purché il comando esterno scelto possa accettare l'input da stdin e stampare l'output su stdout.
Le stringhe sottoposte ad hashing con algoritmi come MD5 o SHA invece sono solo unidirezionali (ovvero non possono essere invertite) e producono sempre lo stesso valore per lo stesso input, quindi vorresti "salarle" in modo che i valori calcolati prodotto in output non può essere cercato solo su tutti i possibili indirizzi MAC. Potresti aggiungere un "sale" casuale come nel seguente script leggermente modificato:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='sha256sum' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
addr = cache[$i]
if (addr == "") {
"(dd if=/dev/random bs=16 count=1 2>/dev/null; echo '\''" $i "'\'') | " crypter | getline addr
cache[$i] = addr
}
$i = "MAC:" addr
}
}
1
' file.log
Quest'ultimo script utilizza un valore (pseudo-)casuale lungo 16 byte come "salt", producendo così un valore hash diverso a ogni esecuzione sugli stessi dati.