Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von Meillo » 30.10.2012 20:15:45

goeb hat geschrieben:
Meillo hat geschrieben:@goeb: Deine Beitraege gefallen mir bis auf ihre Unportabilitaet bei sed, aber in der Sache bin ich halt ein bisschen eigen. ;-)
POSIX sed kann also kein -r. [...]
POSIX ist sicher ein guter Ansatzpunkt aber meine Vorstellung von Portabilitaet geht darueber hinaus. Das liegt daran, dass ich mich fuer alte Unix-Systeme interessiere und demnach auch fuer alte Implementierungen der Tools. Fuer mich hat sed beispielsweise keine Alternativen, wenn es auch Implementierungen gibt die das unterstuetzen und POSIX das evtl. mittlerweile aufgenommen hat. Aber wie gesagt, ich bin da halt ein bisschen eigen.
Use ed once in a while!

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von pangu » 31.10.2012 10:15:04

Mir ist aufgefallen, dass wenn ich nmap mit 192.168.0.0/16 starte oder auch 192.168.0-254.1-254 das es zu fehlenden Hosts führt. Da werden wohl nicht alle angezeigt. Wahrscheinlich liegt das an der Programmfunktion von nmap wie es zwischen den einzelnen Hostscans/Subnets vorgeht. Keine Ahnung, auf jeden Fall habe ich noch ne kleine Schleife eingebaut. Dann habe ich noch den fertigen Befehl an eine Datei umgelenkt. Der Code sieht grad so aus:

Code: Alles auswählen

for (( i=0; i<=254; i++))
do
nmap -sP 192.168.$i.1-254 | \
    sed -e '{N;s/\n//}' -re 's/(^Host|is up.*ss:|\([^)]*\)$|[()])//g' | \
    awk 'NF==3{print $2","$1","$3} NF==2{print $1",,"$2}' >ergebnisliste.csv
done
Nun würde ich das gerne so haben, dass ich dieses Skript immer wieder aufrufen könnte. Es soll dabei eine existierende 'ergebnisliste.csv' erkennen und nur die Hosts entsprechend an der sortierten Zeile mitanfügen, die noch nicht vorhanden war. Ich möchte das aus dem Grund, da bei einem einzigen Scanvorgang nicht alle Hosts erfasst werden (weil ausgeschaltet zum Beispiel). Wenn ich das täglich 2x ausführe krieg ich mit der Zeit soviele Hosts wie nur möglich. Ich will das halt alles in einer zusammengefassten Datei haben, und es soll nach IP-Adressen sortiert bleiben.

Geht das überhaupt in diesem Beispiel oder eher schwer? Denn Nmap arbeitet durch, und dann erst wenn es fertig ist wird ja alles an AWK übergeben. Man kann doch da nicht Host für Host abarbeiten, und die Abfrage durchführen (wenn Eintrag X in der ergebnisliste.csv vorhanden, dann skip)
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

uname
Beiträge: 12406
Registriert: 03.06.2008 09:33:02

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von uname » 31.10.2012 10:20:26

Wenn es Perl wäre würde ich die Datei einlesen und die Werte in Hash-Variablen speichern. Beim nmap-Durchlauf würde ich entsprechend die Werte erweitern und am Ende würde ich alle Hash-Variablen entsprechend ausgeben. Da du die Reihenfolge nach IP-Adressen sortiert haben möchtest kannst du auch nicht einfach etwas an die Datei anfügen. Du wirst die Datei sowieso neu schreiben müssen. Ob es bei "awk" auch Hash-Variablen gibt bzw. mit deinem Programm funktioniert weiß ich nicht.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von rendegast » 31.10.2012 10:43:30

pangu hat geschrieben: . Wenn ich das täglich 2x ausführe krieg ich mit der Zeit soviele Hosts wie nur möglich.
Dafür gäbe es Debianarpalert oder Debianarpwatch (mit DNS-Namen).
Diese verschicken auch Mails, zBsp. bei neuen Hosts oder IP-Wechseln bekannter.





(Ein Hacker horcht natürlich erstmal den Verkehr ab, bevor er mit passender MAC und IP dazwischenfunkt.)
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

Benutzeravatar
goeb
Beiträge: 348
Registriert: 26.08.2006 18:12:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von goeb » 31.10.2012 11:10:16

Oder die neuen Ergebnisse in eine temporäre Datei schreiben, danach die alten und neuen Daten zusammen durch sort -u jagen. Wobei die Sortierung nicht perfekt wäre, aber die IP-Adressen richtig zu sortieren (also 1.2.3.1, 1.2.3.2, ... 1.2.3.10, ... 1.2.3.100) wäre etwas aufwändiger.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von r900 » 31.10.2012 12:03:48

pangu hat geschrieben:Mir ist aufgefallen, dass wenn ich nmap mit 192.168.0.0/16 starte oder auch 192.168.0-254.1-254 das es zu fehlenden Hosts führt. Da werden wohl nicht alle angezeigt. Wahrscheinlich liegt das an der Programmfunktion von nmap wie es zwischen den einzelnen Hostscans/Subnets vorgeht.
Ich bin mit nicht hundertprozentig sicher weil ich gerade keine Lust habe 5 Minuten auf das sed-Konstrukt zu starren :wink: , denke aber es könnte daran liegen. Denn die Ergebnisse sind nicht immer 2-zeilig. Wenn du localhost scannst bekommst du nur eine Host-Zeile und das bringt wahrscheinlich alles durcheinander. Denn dann macht sed so etwas hier:

Code: Alles auswählen

Host 192.168.200.180 is up (0.0013s latency).
MAC Address: 00:22:64:BF:22:93 (Hewlett Packard)
Host 192.168.200.200 is up.
Host max.dhcp.domain.de (192.168.200.212) is up (0.00046s latency).
MAC Address: 00:aa:bb:cc:dd:ee (Fujitsu Siemens Computers)
zu

Code: Alles auswählen

Host 192.168.200.180 is up (0.0013s latency).MAC Address: 00:22:64:BF:22:93 (Hewlett Packard)
Host 192.168.200.200 is up.Host max.dhcp.domain.de (192.168.200.212) is up (0.00046s latency).
MAC Address: 00:aa:bb:cc:dd:ee (Fujitsu Siemens Computers) Host .....
Also die Zeilen beginnen ab dort mit "MAC" anstatt "Host" und du bekommst keine weiteren Einträge mehr.

Bei meinem Skript passiert das nicht. localhost wird lediglich nicht in die Datei geschrieben weil keine MAC-Adresse dazu auftaucht.
uname hat geschrieben:Wenn es Perl wäre würde ich die Datei einlesen und die Werte in Hash-Variablen speichern. Beim nmap-Durchlauf würde ich entsprechend die Werte erweitern und am Ende würde ich alle Hash-Variablen entsprechend ausgeben.
Warum Perl, bash kann mehr als du denkst :) Nur mal als Beispiel lese ich durch Komma getrennte Einträge aus input.txt und gebe sie sortiert wieder aus. Wenn man vor der Ausgabe noch nmap einbaut kann man recht einfach neue hinzufügen und bestehende aktualisieren.

Code: Alles auswählen

#!/bin/bash
declare -A mac host
while IFS=$IFS',' read -r ip hosttmp mactmp; do
   mac[$ip]=$mactmp
   host[$ip]=$hosttmp
   list+=$'\n'$ip
done < input.txt
#(..weitere Einträge erstellen, ip zu list hinzufügen ..)
list=$(echo "$list" | sort -V -u)
for ip in $list; do 
   printf '%s,%s,%s\n' "$ip" "${host[$ip]}" "${mac[$ip]}"
done
Zuletzt geändert von r900 am 31.10.2012 13:24:03, insgesamt 3-mal geändert.

Benutzeravatar
Meillo
Moderator
Beiträge: 9241
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von Meillo » 31.10.2012 12:12:03

uname hat geschrieben:Wenn es Perl wäre würde ich die Datei einlesen und die Werte in Hash-Variablen speichern. Beim nmap-Durchlauf würde ich entsprechend die Werte erweitern und am Ende würde ich alle Hash-Variablen entsprechend ausgeben.
s/Wenn es Perl wäre/Da es awk ist/ ;-)


EDIT: Oder vielleicht besser im awk-Stil: sub("Wenn es Perl wäre", "Da es awk ist");
Use ed once in a while!

Benutzeravatar
goeb
Beiträge: 348
Registriert: 26.08.2006 18:12:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von goeb » 31.10.2012 12:55:55

Die normale Ausgabe von nmap ist Müll. Leerzeile am Anfang (hätte man mir mal sagen sollen :) ), dann der (anscheinend nicht abschaltbare) Header, mal MAC-Zeilen, mal nicht, usw. Probiers mal so:

Code: Alles auswählen

nmap … | \
  sed -r '/(^(S|N)|^$)/d;N;/\nH/D;s/(^Host | i.*s:|\([^)]*\)$|[()])//g' | \
  awk 'NF==3{print $2","$1","$3} NF==2{print $1",,"$2}'

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von r900 » 31.10.2012 13:09:05

goeb hat geschrieben:Oder die neuen Ergebnisse in eine temporäre Datei schreiben, danach die alten und neuen Daten zusammen durch sort -u jagen. Wobei die Sortierung nicht perfekt wäre, aber die IP-Adressen richtig zu sortieren (also 1.2.3.1, 1.2.3.2, ... 1.2.3.10, ... 1.2.3.100) wäre etwas aufwändiger.
sort kennt Sortierung nach Versionsnummer (-V). Das funktioniert auch mit IP-Adressen. :)

Benutzeravatar
ThorstenS
Beiträge: 2875
Registriert: 24.04.2004 15:33:31

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von ThorstenS » 31.10.2012 13:43:01

Wenn ich mal schnell wissen will, wer in meinem /24er subnetz unterwegs ist, mach ich das hier:

Code: Alles auswählen

sudo nmap -TAggressive -n -sS -p80 192.168.3.0/24
Das dauert 2.5 Sekunden und sämtliche Rechner, die erreichbar sind (ob mit oder ohne Webserver ist Wurscht), sind in meiner arp-Tabelle.

sort kann auch IP Adressen sortieren: sort -n -t. -k 1,1 -k 2,2 -k 3,3 -k 4,4

Aus diesem Wissen habe ich mir mal das folgende Script gebastelt. Zum Auflösen des Netzwerkkartenherstellers setzt es allerdings das Paket Debianarpwatch oder zumindest die Datei /usr/share/arpwatch/ethercodes.dat vorraus:

Code: Alles auswählen

#!/bin/bash
# ThorstenS 2010-03-24
####################
export LANG=C

nmap -TAggressive -n -sS -p80 192.168.3.0/24 &>/dev/null

MAC2VENDOR () {
        local MAC="$1"
        MAC2=$(awk -F ':' '{ print tolower($1 ":" $2 ":" $3)}'  <<<$MAC| sed -e 's#00#0#' -e 's#:0#:#g')
        VENDOR=$(awk '/^'$MAC2'\t/ { $1 = ""; print $0 }' /usr/share/arpwatch/ethercodes.dat)
        echo ${VENDOR:-<nicht bekannt>}
}

printf "%-19s%-17s%-31s%-21s\n" "MAC-Adresse" "IP-Adresse" "DNS-Name" "NIC Hersteller"
echo "---------------------------------------------------------------------------------"
arp -a | tr -d '()' | \
while read -a array; do
        printf "%-19s" "${array[3]}"
        printf "%-17s" "${array[1]}"
        printf "%-31s" "${array[0]}"
        MAC2VENDOR ${array[3]}
done | sort -n -t. -k 1,1 -k 2,2 -k 3,3 -k 4,4
echo

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von r900 » 31.10.2012 13:55:29

ThorstenS hat geschrieben:sort kann auch IP Adressen sortieren: sort -n -t. -k 1,1 -k 2,2 -k 3,3 -k 4,4
Wie gesagt, sort -V hat den gleichen Effekt. :)

Benutzeravatar
goeb
Beiträge: 348
Registriert: 26.08.2006 18:12:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von goeb » 31.10.2012 14:01:04

sort -V funktioniert mit der Squeeze-Version von sort, unter Lenny z.B. noch nicht (wären wir wieder bei der Portabilität :), auch wenn Lenny nicht mehr unterstützt wird), sort -n -t. -k 1,1 -k 2,2 -k 3,3 -k 4,4 wird auch von älteren Versionen unterstützt. Aber gut zu wissen, kommt beides gleich mal in meine Notizen.
Zuletzt geändert von goeb am 31.10.2012 14:01:48, insgesamt 1-mal geändert.

Benutzeravatar
ThorstenS
Beiträge: 2875
Registriert: 24.04.2004 15:33:31

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von ThorstenS » 31.10.2012 14:01:39

bringt mir in dem Fall nichts, da er dann nach der MAC und nicht der IP Adresse sortiert.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von r900 » 31.10.2012 14:12:02

Dann kannst du sort -V -k 2,2 schreiben. :)

Benutzeravatar
pangu
Beiträge: 1400
Registriert: 15.11.2011 20:50:52
Lizenz eigener Beiträge: GNU General Public License
Wohnort: /proc/1

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von pangu » 31.10.2012 15:16:13

Danke euch Allen. Da ich Squeeze einsetze habe ich es einfach mit sort -u -V erledigt. Vielen Dank auch an den Hinweis zu den Paketen arpwatch und arpalert. Arpalert bringt mir nur dann was, wenn ich bereits eine MAC-Liste habe, oder? Kann ich das mit arpwatch anlegen? was bringt mir arpalert mehr wie arpwatch? Ich merke mir diese zwei Pakete auf jeden Fall, obwohl das eigentlich nicht darum ging, dass ich Angreifer entdecke.

Ich möchte damit mein WLAN-Subnet scannen. Ich will soviele Hosts wie möglich inventarisieren, eben die IP, der hostname falls existent in meinem DNS-Server und dann noch die MAC-Adresse dazu. Mein Skript habe ich jetzt aufgrund meines mangelnden Wissens etwas umständlich gestaltet, aber es scheint zu funktionieren soweit:

Code: Alles auswählen

 if [ -f hostliste.csv ]; then
        echo "Scan-Ergebnis Ausgabedatei existiert. Erweitere nun durch neu hinzugekommene Hosts..."
cp hostliste.csv lastinventory.csv
for (( i=0; i<=254; i++))
do
nmap -sP 192.168.2.$i | \
    sed -e '{N;s/\n//}' -re 's/(^Host|is up.*ss:|\([^)]*\)$|[()])//g' | \
    awk 'NF==3{print $2","$1","$3} NF==2{print $1",,"$2}' >> newinventory.csv
done
sort -u -V lastinventory.csv newinventory.csv > hostliste.csv
rm *inventory.csv
exit 0
fi

for (( j=0; j<=254; j++))
do
nmap -sP 192.168.2.$j | \
    sed -e '{N;s/\n//}' -re 's/(^Host|is up.*ss:|\([^)]*\)$|[()])//g' | \
    awk 'NF==3{print $2","$1","$3} NF==2{print $1",,"$2}' >> hostliste.csv
done
Ich bin mir sicher, dass man das auf [übertreib_modus_AN]3 Zeilen[/übertreib_modus_AUS] verkürzen kann, hehe :mrgreen: aber was solls, momentan läufts. Ich habs in die crontab gesetzt und es wird alle 10min ausgeführt. Will mal schauen, was sich da so an Daten ansammeln werden.
Man gibt Geld aus, das man nicht hat, um damit Dinge zu kaufen, die man nicht braucht, um damit Leute zu beeindrucken, die man nicht mag.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Awk aus einem zweizeiligen Grep-Ergebnis anwenden

Beitrag von rendegast » 01.11.2012 05:47:07

pangu hat geschrieben: was bringt mir arpalert mehr wie arpwatch?
Dazu
rendegast hat geschrieben: ... oder arpwatch (mit DNS-Namen).

Code: Alles auswählen

# ll /var/lib/arp*
/var/lib/arpalert:
total 4
-rw-r----- 1 arpalert arpalert   0 Feb 29  2012 arp.dat
-rw-r----- 1 arpalert arpalert   0 Feb 29  2012 arpalert.leases

/var/lib/arpwatch:
total 44
-rw-r--r-- 1 arpwatch arpwatch 9054 Nov  1 05:38 arp.dat
-rw-r--r-- 1 arpwatch arpwatch 9054 Nov  1 05:23 arp.dat-
... obwohl das eigentlich nicht darum ging, dass ich Angreifer entdecke.
Wenn es nur um die Inventarisierung geht, erfüllen beide Dienste den Zweck.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

Antworten