home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / scripts / sniffer-detect.nse < prev    next >
Text File  |  2009-07-06  |  4KB  |  124 lines

  1. description = [[
  2. Checks if a target on a local Ethernet has its network card in promiscuous mode.
  3.  
  4. The techniques used are described at
  5. http://www.securityfriday.com/promiscuous_detection_01.pdf.
  6. ]]
  7.  
  8. ---
  9. -- @output
  10. -- Host script results:
  11. -- |_ sniffer-detect: Likely in promiscuous mode (tests: "11111111")
  12.  
  13. author = "Marek Majkowski <majek04+nse@gmail.com>"
  14. license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
  15.  
  16. categories = {"discovery"}
  17.  
  18. -- okay, we're interested only in hosts that are on our ethernet lan
  19. hostrule = function(host, port)
  20.     return host.directly_connected == true and
  21.         host.mac_addr ~= nil and
  22.         host.mac_addr_src ~= nil and
  23.         host.interface ~= nil and
  24.         nmap.get_interface_link(host.interface) == 'ethernet'
  25. end
  26.  
  27. callback = function(packetsz, layer2, layer3)
  28.     return string.sub(layer2, 0, 12)
  29. end
  30.  
  31.  
  32. do_test = function(dnet, pcap, host, test)
  33.     local _
  34.     local status
  35.     local i = 0
  36.  
  37.     -- ARP requests are send with timeouts: 10ms, 40ms, 90ms
  38.     -- before each try, we wait at least 100ms
  39.     -- in summary, this test takes at least 100ms and at most 440ms
  40.     for i=1,3 do
  41.         -- flush buffers :), wait quite long.
  42.         repeat
  43.             pcap:set_timeout(100)
  44.             pcap:pcap_register(host.mac_addr_src .. host.mac_addr)
  45.             status ,_,_,_ = pcap:pcap_receive()
  46.         until status ~= true
  47.         pcap:set_timeout(10 * i*i)
  48.         pcap:pcap_register(host.mac_addr_src .. host.mac_addr)
  49.  
  50.         dnet:ethernet_send(test)
  51.  
  52.         status ,_,_,_ = pcap:pcap_receive()
  53.         if status == true then
  54.             -- the basic idea, was to inform user about time, when we got packet
  55.             -- so that 1 would mean (0-10ms), 2=(10-40ms) and 3=(40ms-90ms)
  56.             -- but when we're running this tests on macs, first test is always 2.
  57.             -- which means that the first answer is dropped.
  58.             -- for now, just return 1 if test was successfull, it's easier
  59.             -- return(i)
  60.             return(1)
  61.         end
  62.     end
  63.     return('_')
  64. end
  65.  
  66. action = function(host, port)
  67.     local dnet = nmap.new_dnet()
  68.     local pcap = nmap.new_socket()
  69.     local _
  70.     local status
  71.     local results = {
  72.         ['1_____1_'] = false, -- MacOSX(Tiger.Panther)/Linux/ ?Win98/ WinXP sp2(no pcap)
  73.         ['1_______'] = false, -- Old Apple/SunOS/3Com
  74.         ['1___1_1_'] = false, -- MacOSX(Tiger)
  75.         ['11111111'] = true,  -- BSD/Linux/OSX/     (or not promiscous openwrt )
  76.         ['1_1___1_'] = false, -- WinXP sp2 + pcap|| win98 sniff || win2k sniff (see below)
  77.         ['111___1_'] = true,  -- WinXP sp2 promisc
  78. --        ['1111__1_'] = true,  -- ?Win98 promisc + ??win98 no promisc *not confirmed*
  79.         }
  80.     dnet:ethernet_open(host.interface)
  81.  
  82.     pcap:pcap_open(host.interface, 64, 0, callback, "arp")
  83.  
  84.     local test_static = host.mac_addr_src ..
  85.             string.char(0x08,0x06, 0x00,0x01, 0x08,0x00, 0x06,0x04, 0x00,0x01) ..
  86.             host.mac_addr_src ..
  87.             host.bin_ip_src ..
  88.             string.char(0x00,0x00, 0x00,0x00, 0x00,0x00) ..
  89.             host.bin_ip
  90.     local t = {
  91.         string.char(0xff,0xff, 0xff,0xff, 0xff,0xff), -- B32 no meaning?
  92.         string.char(0xff,0xff, 0xff,0xff, 0xff,0xfe), -- B31
  93.         string.char(0xff,0xff, 0x00,0x00, 0x00,0x00), -- B16
  94.         string.char(0xff,0x00, 0x00,0x00, 0x00,0x00), -- B8
  95.         string.char(0x01,0x00, 0x00,0x00, 0x00,0x00), -- G
  96.         string.char(0x01,0x00, 0x5e,0x00, 0x00,0x00), -- M0
  97.         string.char(0x01,0x00, 0x5e,0x00, 0x00,0x01), -- M1 no meaning?
  98.         string.char(0x01,0x00, 0x5e,0x00, 0x00,0x03), -- M3
  99.         }
  100.     local v
  101.     local out = ""
  102.     for _, v in ipairs(t) do
  103.         out = out .. do_test(dnet, pcap, host, v .. test_static)
  104.     end
  105.  
  106.     dnet:ethernet_close()
  107.     pcap:pcap_close()
  108.  
  109.     if out == '1_1___1_' then
  110.         return 'Windows with libpcap installed; may or may not be sniffing (tests: "' .. out .. '")'
  111.     end
  112.     if results[out] == false then
  113.         -- probably not sniffing
  114.         return
  115.     end
  116.     if results[out] == true then
  117.         -- rather sniffer.
  118.         return 'Likely in promiscuous mode (tests: "' .. out .. '")'
  119.     end
  120.  
  121.     -- results[out] == nil
  122.     return 'Unknown (tests: "' .. out .. '")'
  123. end
  124.