вторник, 3 декабря 2013 г.

Скрипт для сканирования сети

  Несколько лет назад задумался я над вопросом, что надо бы собрать в сети для каждого устройства аппаратный адрес, IP-адрес, NETBIOS-имя компьютера, имя пользователя, рабочую группу, и на всякий случай DNS-имя устройства. Для инвентаризации сети.
  Решил, что для меня лучше всего сделать скрипт на Linux. Линукс уже помогал мне когда я занимался поиском в сети нелегально подключенных компьютеров и искал кто рассылает в сети вирусы по открытым папкам.
  Скрипт раз в сутки сканирует сеть и собирать всю вышеперечисленную инфо в текстовый файл. Эти текстовые файлы собирать за все время. И потом всю нужную информацию собирать командой grep. Эти логи мне помогли когда в сети появились одинаковые аппаратные адреса.

  Данный скрипт написан на Fedore Core 18. Он состоит из двух файлов. Скрипт scannet.fc18 собирает всю информацию и выводит ее на экран. Функция ScanNet проходит все IP адреса сети и для каждого запускает ScanHost. Который собирает инфо командами arping, nmblookup и nmap. Выделяет полезную инфу командами grep, cut, head, tail и выводит на экран.

----- scannet.fc18 -----

#!/bin/bash

SUDO=/usr/bin/sudo
ECHO=/bin/echo
GREP=/bin/grep
CUT=/bin/cut
HEAD=/bin/head
TAIL=/bin/tail
NMAP=/bin/nmap
NMBLOOKUP=/bin/nmblookup
ARP=/usr/sbin/arp
ARPING=/usr/sbin/arping
RM=/bin/rm

NETBIOS_DATA=/tmp/scannet_netbios_data.tmp
NMAP_DATA=/tmp/scannet_nmap_data.tmp

#$1 - IP adress
function ScanHost ()
{
  IP=${1}
  MAC=`${ARPING} -c 1 ${IP} | ${GREP} "reply" | ${CUT} -f 2 -d "[" | ${CUT} -f 1 -d "]"`
  if [ "$MAC" = "" ]; then
    MAC="zero"
  else
    $NMBLOOKUP -A ${IP} > $NETBIOS_DATA
    $NMAP -p 139 ${IP} > $NMAP_DATA
    NETBIOS_NAME=`${GREP} -i "<00>" ${NETBIOS_DATA} | ${GREP} -vi "" | ${CUT} -d "<" -f 1 | ${HEAD} -n 1 | ${CUT} -f 2 | ${CUT} -d " " -f 1`
    NETBIOS_GROUP=`${GREP} -i "<00>" ${NETBIOS_DATA} | ${GREP} -i "" | ${CUT} -d "<" -f 1 | ${HEAD} -n 1 | ${CUT} -f 2 | ${CUT} -d " " -f 1`
    USER_NAME=`${GREP} -i "<03>" ${NETBIOS_DATA} | ${GREP} -i "<03>" | ${TAIL} -n 1 | ${CUT} -d "<" -f 1 | ${CUT} -f 2 | ${CUT} -d " " -f 1`
    DNS_NAME=`${GREP} -i "nmap scan report" ${NMAP_DATA} | ${CUT} -d " " -f 5`
 
    $ECHO "${MAC} | ${IP} | ${NETBIOS_NAME} | ${NETBIOS_GROUP} | ${USER_NAME} | ${DNS_NAME}"
  fi
  $RM -f $NETBIOS_DATA
  $RM -f $NMAP_DATA
}

function ScanNet()
{
ip1=10
ip2=6
for ip3 in `seq 8 15`;
do
  for ip4 in `seq 0 255`;
  do
    case "${ip1}.${ip2}.${ip3}.${ip4}" in
      10.6.8.0) ;;
      10.6.15.255) ;;
      *) ScanHost ${ip1}.${ip2}.${ip3}.${ip4} ;;
    esac
  done
done
}

${ECHO} "       MAC        |     IP     |     NAMES     |   GROUPS   |   User_Name   |   DNS   | "

ScanNet
----- конец scannet.fc18 -----

  Правда сразу обнаружилось, что имя залогиненого пользователя он показывает редко. Я когда-то заметил, что в выводе команды nbtstat -A IP_адрес_удаленного_пк если есть несколько строк с кодом 03, то последняя это имя пользователя удаленного компа. но это срабатывает не всегда.
   Следующий скрипт был написан чтобы предыдущий сценарий запускать автоматически из cron. Он определяет, что файлы пишутся в домашний каталог пользователя и имени файла присваивается текущая дата плюс в конце случайный набор символов.
----- scannet.cron -----

#!/bin/bash

DIR="${HOME}"
LOGFILE="${DIR}/`/bin/date +%Y_%m_%d_%N`.log"

${HOME}/bin/scannet.fc18 > $LOGFILE
 
----- scannet_cron конец -----


Пример вывода этих скриптов
      MAC        |     IP     |     NAMES     |   GROUPS   |   User_Name   |   DNS   | Services |
00:01:02:03:04:05 | 10.6.8.1 | COMP1 | GROUP1 |  | comp1.domain1.ua |

10:20:30:40:50 | 10.6.8.5 | COMP2 | GROUP2 |  |