mirror of
https://github.com/angryip/ipscan.git
synced 2025-10-26 11:18:17 +00:00
NetBIOSInfoFetcher implemented
git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@233 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
parent
6b11be87b2
commit
8650cf8667
6
TODO
6
TODO
@ -1,7 +1,6 @@
|
||||
Before 3.0 beta:
|
||||
|
||||
* export/import of settings (profiles?)
|
||||
* NetBIOS fetchers (like in 2.x)
|
||||
|
||||
Before 3.0:
|
||||
|
||||
@ -13,14 +12,13 @@ Before 3.0:
|
||||
* startup as root option
|
||||
* compile librocksaw for mac
|
||||
* preferences & select fetchers buttons in the toolbar
|
||||
* plugin loader
|
||||
|
||||
Later:
|
||||
|
||||
* preferences profiles (maybe even save with favorites)
|
||||
* preferences profiles (tied to favorites?)
|
||||
* offer installation on Windows
|
||||
* free text (advanced) feeder
|
||||
* comments fetcher
|
||||
* saving and restoring of results together with all options
|
||||
* plugin loader
|
||||
* advanced find (firefox-like)
|
||||
* use jpcap for raw packet injection and ARP scanning
|
||||
|
||||
@ -28,3 +28,4 @@ clipboard
|
||||
ctrl
|
||||
compiz
|
||||
placeholder
|
||||
firewall
|
||||
|
||||
@ -184,6 +184,8 @@ fetcher.comment=Comments
|
||||
fetcher.comment.info=Allows writing of comments for each host.\nThe comments are persisted and always shown then the host is scanned.
|
||||
fetcher.webDetect=Web detect
|
||||
fetcher.webDetect.info=Detects the web server software name and version, if possible.\n\nWorks by sending a HEAD request and reading the Server HTTP header from the response.
|
||||
fetcher.netbios=NetBIOS Info
|
||||
fetcher.netbios.info=Retrieves the NetBIOS information about Windows machines.\n\nThe response has the following format:\nDOMAIN\\USER@COMPUTER [MAC]\n\nWhere:\nDOMAIN - Windows domain or workgroup\nUSER - currently logged in user\nCOMPUTER - Windows computer name (may be different from DNS name)\nSome parts may be absent, depending on the response.\n\nNote that this won't work with machines that have firewall enabled (which are most modern installations).\nThis fetcher is provided mostly for feature-compatibility with version 2.x.
|
||||
fetcher.value.ms=\u00A0ms
|
||||
fetcher.value.notAvailable=[n/a]
|
||||
fetcher.value.notScanned=[n/s]
|
||||
|
||||
@ -22,6 +22,7 @@ import net.azib.ipscan.fetchers.FetcherRegistryImpl;
|
||||
import net.azib.ipscan.fetchers.FilteredPortsFetcher;
|
||||
import net.azib.ipscan.fetchers.HostnameFetcher;
|
||||
import net.azib.ipscan.fetchers.IPFetcher;
|
||||
import net.azib.ipscan.fetchers.NetBIOSInfoFetcher;
|
||||
import net.azib.ipscan.fetchers.PingFetcher;
|
||||
import net.azib.ipscan.fetchers.PingTTLFetcher;
|
||||
import net.azib.ipscan.fetchers.PortsFetcher;
|
||||
@ -97,6 +98,7 @@ public class ComponentRegistry {
|
||||
container.registerComponentImplementation(FilteredPortsFetcher.class);
|
||||
container.registerComponentImplementation(WebDetectFetcher.class);
|
||||
container.registerComponentImplementation(CommentFetcher.class);
|
||||
container.registerComponentImplementation(NetBIOSInfoFetcher.class);
|
||||
|
||||
container.registerComponentImplementation(PingerRegistry.class, PingerRegistryImpl.class);
|
||||
container.registerComponentImplementation(ScanningResultList.class);
|
||||
|
||||
146
src/net/azib/ipscan/fetchers/NetBIOSInfoFetcher.java
Normal file
146
src/net/azib/ipscan/fetchers/NetBIOSInfoFetcher.java
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* This file is a part of Angry IP Scanner source code,
|
||||
* see http://www.azib.net/ for more information.
|
||||
* Licensed under GPLv2.
|
||||
*/
|
||||
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.azib.ipscan.config.GlobalConfig;
|
||||
import net.azib.ipscan.config.LoggerFactory;
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
|
||||
/**
|
||||
* NetBIOSInfoFetcher - gathers NetBIOS info about Windows machines.
|
||||
* Provided for feature-compatibility with version 2.x
|
||||
*
|
||||
* @author Anton Keks
|
||||
*/
|
||||
public class NetBIOSInfoFetcher implements Fetcher {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger();
|
||||
|
||||
private static final int NETBIOS_UDP_PORT = 137;
|
||||
private static final byte[] REQUEST_DATA = {(byte)0xA2, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 0x00, 0x01};
|
||||
|
||||
private static final int RESPONSE_BASE_LEN = 57;
|
||||
private static final int RESPONSE_NAME_LEN = 15;
|
||||
private static final int RESPONSE_NAME_BLOCK_LEN = 18;
|
||||
|
||||
private static final int GROUP_NAME_FLAG = 128;
|
||||
private static final int NAME_TYPE_DOMAIN = 0x00;
|
||||
private static final int NAME_TYPE_MESSENGER = 0x03;
|
||||
|
||||
private GlobalConfig config;
|
||||
|
||||
public NetBIOSInfoFetcher(GlobalConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return "fetcher.netbios";
|
||||
}
|
||||
|
||||
public Object scan(ScanningSubject subject) {
|
||||
DatagramSocket socket = null;
|
||||
try {
|
||||
socket = new DatagramSocket();
|
||||
socket.setSoTimeout(config.pingTimeout);
|
||||
|
||||
socket.connect(subject.getAddress(), NETBIOS_UDP_PORT);
|
||||
socket.send(new DatagramPacket(REQUEST_DATA, REQUEST_DATA.length));
|
||||
|
||||
byte[] response = new byte[1024];
|
||||
DatagramPacket responsePacket = new DatagramPacket(response, response.length);
|
||||
socket.receive(responsePacket);
|
||||
|
||||
if (responsePacket.getLength() < RESPONSE_BASE_LEN) {
|
||||
// response was too short for some reason
|
||||
return null;
|
||||
}
|
||||
|
||||
int nameCount = response[RESPONSE_BASE_LEN-1] & 0xFF;
|
||||
if (responsePacket.getLength() < RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * (nameCount-1)) {
|
||||
// data was truncated or something is wrong
|
||||
return null;
|
||||
}
|
||||
|
||||
return extractNames(response, nameCount);
|
||||
}
|
||||
catch (SocketException e) {
|
||||
// this includes PortUnreachableException and SocketTimeoutException
|
||||
return null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
// bugs?
|
||||
LOG.log(Level.WARNING, null, e);
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String extractNames(byte[] response, int nameCount) {
|
||||
String computerName = name(response, 0);
|
||||
|
||||
String groupName = null;
|
||||
for (int i = 1; i < nameCount; i++) {
|
||||
if (nameType(response, i) == NAME_TYPE_DOMAIN && (nameFlag(response, i) & GROUP_NAME_FLAG) > 0) {
|
||||
groupName = name(response, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String userName = null;
|
||||
for (int i = nameCount - 1; i > 0; i--) {
|
||||
if (nameType(response, i) == NAME_TYPE_MESSENGER) {
|
||||
userName = name(response, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String macAddress = String.format("%02X-%02X-%02X-%02X-%02X-%02X",
|
||||
nameByte(response, nameCount, 0), nameByte(response, nameCount, 1),
|
||||
nameByte(response, nameCount, 2), nameByte(response, nameCount, 3),
|
||||
nameByte(response, nameCount, 4), nameByte(response, nameCount, 5));
|
||||
|
||||
return (groupName != null ? groupName + "\\" : "") +
|
||||
(userName != null ? userName + "@" : "") +
|
||||
computerName + " [" + macAddress + "]";
|
||||
}
|
||||
|
||||
private static String name(byte[] response, int i) {
|
||||
// as we have no idea in what encoding are the received names,
|
||||
// assume that local default encoding matches the remote one (they are on the same LAN most probably)
|
||||
return new String(response, RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * i, RESPONSE_NAME_LEN).trim();
|
||||
}
|
||||
|
||||
private static int nameByte(byte[] response, int i, int n) {
|
||||
return response[RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * i + n] & 0xFF;
|
||||
}
|
||||
|
||||
private static int nameFlag(byte[] response, int i) {
|
||||
return response[RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * i + RESPONSE_NAME_LEN + 1] & 0xFF +
|
||||
(response[RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * i + RESPONSE_NAME_LEN + 2] & 0xFF) * 0xFF;
|
||||
}
|
||||
|
||||
private static int nameType(byte[] response, int i) {
|
||||
return response[RESPONSE_BASE_LEN + RESPONSE_NAME_BLOCK_LEN * i + RESPONSE_NAME_LEN] & 0xFF;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
}
|
||||
|
||||
}
|
||||
53
test/net/azib/ipscan/fetchers/NetBIOSInfoFetcherTest.java
Normal file
53
test/net/azib/ipscan/fetchers/NetBIOSInfoFetcherTest.java
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* This file is a part of Angry IP Scanner source code,
|
||||
* see http://www.azib.net/ for more information.
|
||||
* Licensed under GPLv2.
|
||||
*/
|
||||
|
||||
package net.azib.ipscan.fetchers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* NetBIOSInfoFetcherTest
|
||||
*
|
||||
* @author Anton Keks
|
||||
*/
|
||||
public class NetBIOSInfoFetcherTest {
|
||||
@Test
|
||||
public void extractNamesNoUserNoGroup() throws Exception {
|
||||
byte[] response = ("01234567890123456789012345678901234567890123456789012345\u0001" +
|
||||
"ComputerName XYY" +
|
||||
"\u00DE\u00AD\u00BE\u00EF\u0000\u0000 XYY"
|
||||
).getBytes("ISO-8859-1");
|
||||
assertEquals("ComputerName [DE-AD-BE-EF-00-00]", NetBIOSInfoFetcher.extractNames(response, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractNamesNoUserWithGroup() throws Exception {
|
||||
byte[] response = ("01234567890123456789012345678901234567890123456789012345\u0002" +
|
||||
"ComputerName XYY" +
|
||||
"GroupName \u0000\u0080\u0000" +
|
||||
"\u0001\u0002\u0003\u0004\u0005\u0006 XYY"
|
||||
).getBytes("ISO-8859-1");
|
||||
assertEquals("GroupName\\ComputerName [01-02-03-04-05-06]", NetBIOSInfoFetcher.extractNames(response, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extractNamesWithUserAndGroup() throws Exception {
|
||||
byte[] response = ("01234567890123456789012345678901234567890123456789012345\u0007" +
|
||||
"ComputerName XYY" +
|
||||
"SomeName X\u007F\u0000" +
|
||||
"SomeName X\u0085\u0000" +
|
||||
"GroupName \u0000\u0085\u0000" +
|
||||
"WrongUserName \u0003YY" +
|
||||
"UserName \u0003YY" +
|
||||
"SomeName XYY" +
|
||||
"\u00DE\u00AD\u00BE\u00EF\u0000\u0000 XYY"
|
||||
).getBytes("ISO-8859-1");
|
||||
assertEquals("GroupName\\UserName@ComputerName [DE-AD-BE-EF-00-00]", NetBIOSInfoFetcher.extractNames(response, 7));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user