Wypisywanie nazw NetBIOS komputerów w sieci LAN.

Zainspirowany pytaniem dziq z kanału #archlinux.pl o to czym można przejrzeć przyporządkowane poszczególnym adresom IP nazwy NetBIOS, napisałem taki oto krótki skrypt w bash'u pobierający te dane przy pomocy nmap'a:

1  #!/bin/bash
2  # netbios_names.sh copyright by Łukasz Fidosz 
3  # distributed under GNU General Public License version 3
4  if [ $UID -ne 0 ]; then
5    echo "---"
6    echo "Błąd: skrypt musi zostać uruchomiony z konta root'a!"
7    echo "---"
8    exit
9  fi
10 mkdir -p /tmp/hostnames
11 cd /tmp/hostnames
12 nmap -A $(nmap -sP 192.168.1.0/24 \
      | awk '/Host.*\ be up/ {print $2}') > hosty
13 csplit -s -k -f host hosty '/^Interesting ports on/' {*}
14 for i in /tmp/hostnames/host0*
15 do
16   if [ -n "$(grep 'NetBIOS name' $i)" ];
17     then
18       ip=$(awk '/Interesting ports on/ {print $4}' $i)
19       name=$(awk '/NetBIOS name:/ {print $5}' $i | tr -d ,)
20       echo "$ip $name"
22   fi
23 done
23 rm -rf ../hostnames

Już tłumacze co robi główne polecenie-czyli 12-ta linijka. Linijka ta składa się z dwóch grup poleceń pierwsze "wewnętrzne"-znajdujące się wewnątrz $() które zwraca w wyniku dane dla drugiego polecenia-"zewnętrznego", dzieje się to właśnie dzięki znakom $(). Zacznijmy więc od tego co jest wewnątrz:

  • nmap -sP 192.168.1.1/24 Skanuje po kolei pingiem wszystkie komputery z podanej grupy adresów, w naszym przypadku jest to adres 192.168.1.0 z maską podsieci /24 zostaną więc sprawdzone wszystkie komputery o adresach IP z zakresu 192.168.1.0-192.168.1.255, wartość tą powinniśmy zmienić jeśli nasza sieć lokalna ma inny zakres adresów. Polecenie to zwróci informacje o tym które komputery z sieci są włączone które nie.
  • awk '{print $2}' Zostawia tylko linijki zawierające adresy IP hostów które są aktualnie włączone, po czym zwraca wartość drugiego pola(domyślnym separatorem pul w awk jest spacja), czyli sam adres IP bez zbędnego tekstu

String zwrócony przez poprzednie polecenie, zawierający listę adresów IP jest przekazywany następnie do polecenia "zewnętrznego", czyli: nmap -A nmap uruchomiony w ten sposób skanuje kolejno komputery których adresy IP jako argument, starając się wykryć jak najwięcej danych o systemie operacyjnym i nasłuchujących aplikacjach działających na danym komputerze, właśnie te dane zawierają nazwę NetBIOS, więc za pomocą > przekierowujemy całe wyjście programy do pliku hosty

Wypadało by w jakiś przejrzysty sposób wyświetlić tylko te informacje które nas interesują. Najpierw na pomocą csplit'a dzielimy plik na mniejsze według wzorca, czyli każdy fragment pliku zaczynający się od "Interesting ports on" (tak właśnie zaczyna sie nmap'a dotyczący każdego komputera) znajdzie się w osobnym pliku, nie znalazłem lepszego sposobu aby oddzielić komputery nie których nazwy NetBIOS nie wykryto(odrzucamy porostu pliki, które nie zawierają słów "NetBIOS name:").

W dalszej części skryptu poruszamy się w pętli przez wszystkie utworzone przed chwilą pliki i jeśli któryś zawiera słowa "NetBIOS name:" (co sprawdzamy instrukcją warunkową z linijki 16), jeśli tak to poleceniami z linijek 18 i 19 zapisujemy adres IP znajdujący się w danym pliku do zmiennej IP a nazwę NetBIOS do zmiennej name po czym wypisujemy je w obok siebie.

Aby uruchomić skrypt jako root wpisujemy: ./netbios_names (gdzie netbios_names.sh jest nazwą pod jaką zapisaliśmy skrypt, wcześniej musimy nadać mu prawa uruchamiania co robimy przez polecenie: chmod +x netbios_names).

Uwaga: Wykonywanie skryptu może potrwać naprawdę długo jeśli dużo komputerów w naszej sieci jest włączonych, każdy z nich jest dość dokładnie skanowany przez nmap'a wiec warto uzbroić się w cierpliwość;)

Oto przykład uruchomienia skryptu:

[root@hpek virhilo]# ~virhilo/skrypty/bash/netbios_names
192.168.1.100: MARK                                         
192.168.1.101: AGA

Źródła skryptu

Więcej informacji

  • man nmap
  • man grep
  • man awk
  • man csplit
MegiTeam - mówimy Twoim językiem

Komentarze do notki Wypisywanie nazw NetBIOS komputerów w sieci LAN.

  1. Livio powiedział(a):

    Oj, żeby ktoś tak potrafił rozłożyć Sambę na łopatki... Latanie po domu i pytanie o IP, coby się dostać do zasobów, mało mnie bawi :/ .

  2. virhilo powiedział(a):

    Hmm... znaczy co byś chciał uzyskać? listę aktualnie podłączonych komputerów w sieci?

  3. Livio powiedział(a):

    Chciałbym, żeby Windows mnie widział w grupie roboczej, a ja, żeby także jego widział i mógł zajrzeć do udostępnionych przez niego zasobów. Obecnie tylko via IP działa. Pewnie przez DHCP.

  4. virhilo powiedział(a):

    Ale poco latać po domu i pytać o IP jak przed chwila napisałem jak dorwać ta liste IP?:)

  5. Livio powiedział(a):

    Ale to tylko IP, a ja bym chciał, żeby mi Samba współpracowała z Windowsem, tak, jak Windowsy między sobą :P .

  6. virhilo powiedział(a):

    Nigdy nie używałem Samby a Windowsa uzywam tyko u kogoś wiec chyba nie zrozumiem jak różnicy między Samba-Windows, a Windows-Windows.

  7. Livio powiedział(a):

    Spieszę wytłumaczyć. Windows nie zawsze widzie mojego Linucha, a ja nie zawsze widzę Windows. Na dodatek, jeśli chcę "wejść" do jego komputer via Samba, to otrzymuję błąd.

  8. Livio powiedział(a):

    No, w sumie, to Twój skrypt jako środek doraźny musi wystarczyć. Jakby go tak wykorzystał jako backend to jakiegoś apletu GNOME, to, nawet nawet :> .

    Po modyfikacji, jak wpis nakazał, działa luksio (nawet widać, że jeden z komputerów wpisano w /etc/hosts) :D .

    $ sudo ./netbios_names.sh
    192.168.2.100: GEEKO
    torpedo TORPEDO
    192.168.2.102: TORPEDO-LAPTOP

  9. ` powiedział(a):

    jeżeli w skrypcie jest konstrukcja typu grep|awk to najpewniej oznacza, że ten grep jest zbędny :)

    nmap -sP 192.168.1.0/24 | awk '/Host.*\ be up/ {print $2}'

    a jak chciałbym zawsze IP to mając nazwę hosta dostaję HOST (IP) więc nieco kombinując...

    awk '/Host.*\ be up/ {if($4=="to")print $2;else print substr($3, 2, length($3)-2)}'


    Nie mam u siebie niczego co pozwoliłoby mi szukać 'NetBIOS name' więc pobawiłem się detekcją systemu tworząc takiego jednolinijkowca:

    nmap -sP 192.168.1.0/24 | awk '/Host.*\ be up/ {if($4=="to")print $2;else print substr($3, 2, length($3)-2)}' | while read IP;do X=`nmap -A -O "$IP"|awk '/OS\ details:/ {print substr($0, 13)}'`;test -n "$X" && echo "$IP: $X";done

    długość 'OS details: ' to 12 więc substr wycinam od 13 - moźna poprawić dla NetBIOS.
    Nie ma pojęcia jak się ma wywołanie nmap -A IP1 IP2 IP3 do kolejnych wywołań nmapa w pętli ale tak mi pasuje do jednolinijkowca :>

  10. virhilo powiedział(a):

    Faktycznie, jakoś tak z pośpiechu zapomniałem o tym-już poprawione na wersje bez grep'a:)

  11. ` powiedział(a):

    linie 18 i 19 też nie potrzebują grepa :P
    tr też dałoby się przenieść do awka a i tak najwięcej skrypt dostaje po dupie na pracy nmapa więc to raczej taka sztuka dla sztuki...

  12. virhilo powiedział(a):

    Poprawione już na wersję bez grepa(aż dziwne ze to przeoczyłem), ale nie chciało mi się kombinować zeby sie tr pozbywać. Dokladnie, przyspieszyć to nic nie przyspieszy, ale chociaż czytelność się zwiększy.

  13. Antracyt powiedział(a):

    No niestety u mnie na ubuntu coś nie działa najlepiej dostaje komunikat "[: 10: 0: unexpected operator" później coś robi ale nic nie znajduje a przynajmniej 1 komputer na 100% jest włączony.

  14. virhilo powiedział(a):

    Teraz napewno dziala:)

  15. nowak powiedział(a):

    Witam!
    Widze, ze sie niezle tu meczycie ;) Ja mam w cronie taki wpis do zbierania netbiosow:
    40 * * * * root echo "------------------" >> ~root/netbios && date >> ~root/netbios && for x in `seq 1 255`; do nmblookup -A 192.168.1.$x | sed '/Looking up/N;/No reply/N;/No reply/d' >> ~root/netbios; done

    Przy okazji - warto wspomniec, ze ping to nie ICMP ping: (man nmap)
    An exception to this is that an ARP scan is used for any targets which are on a local ethernet network

W górę » Strona główna

Dodaj komentarz: