Le but de l'article est d'explorer le réseau avec JAVA, bien qu'il existe de nombreux outils dédiés à ce genre de tache.
Lister les postes sur le LAN
La méthodologie employée part du principe que l'on connait rien sur la topologie du réseau sur lequel on se trouve. La class LANScanner effectue des tests sur l'ensemble de la plage d'adresse ip pour trouver les postes connectés et les ports ouverts. Oui je sais ! la technique est inutile dans le cadre d'un LAN puisque le DHCP dispose de toutes infos, mais bon le but est de montrer comment réaliser le scan de réseau avec JAVA.Etapes du scan réseau:
1. Ping de chaque adresse ip pour déterminer qu'un poste y est connecté,
2. Scan de quelques ports du poste pour évaluer le type d'ordinateur.
note: lors des tests, la fonction inclue à JAVA InetAddress.isReachable() retournait trop souvent false, alors que l'ip est attribuée.La class LANScanner utilise directement la fonction Ping du poste de travail.
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Scanner les postes sur un reseau local
*
* @author Fobec 03/201
* @see http://www.fobec.com/java/1141/scanner-postes-sur-reseau-local.html
*/
public class LANScanner {
/**
* Parcourir l'ensemble du réseau pour détecter les postes de travail ou les
* serveurs
*
* @param iproot plage de départ du scan
*/
public void enumLocalNetwork(String iproot) {
//Test base Ip valide
String[] nip = iproot.split("\.");
if (nip.length != 4) {
System.out.println("Base Ip incorrecte !!! exemple 192.168.2.0");
return;
}
//timer
int ifound = 0;
Long timestart = System.currentTimeMillis();
//Entete du tableau
System.out.printf("%-16s %-30s %-10sn", "Adresse ip", "Nom du poste", "Port ouvert");
byte[] ip = {(byte) Integer.parseInt(nip[0]), (byte) Integer.parseInt(nip[1]),
(byte) Integer.parseInt(nip[2]), (byte) 0};
//Boucle sur l'ensemble du masque réseau
for (int i = 0; i < 255; i++) {
ip[3] = (byte) i;
try {
InetAddress addr = InetAddress.getByAddress(ip);
if (isAlive(addr.getHostAddress())) {
System.out.printf("%-16s %-30s %-10sn", addr.getHostAddress(),
addr.getHostName(), scanPort(addr.getHostAddress()));
ifound++;
} else {
// System.out.println(addr.getHostAddress() + " empty");
}
} catch (UnknownHostException e) {
System.out.println(e.getMessage());
}
}
Long timeelapse = System.currentTimeMillis() - timestart;
System.out.println(ifound + " postes détectés sur le réseau "
+ iproot + " en " + Math.round(timeelapse / 1000) + " secondes");
}
/**
* Ping sur une adresse ip
*
* @param Ipv4Adr ip adresse ip du poste
* @return boolean
*/
private boolean isAlive(String Ipv4Adr) {
Process p1;
boolean reachable = false;
try {
p1 = java.lang.Runtime.getRuntime().exec("ping -w 2 -n 2 " + Ipv4Adr);
int returnVal = p1.waitFor();
reachable = (returnVal == 0);
} catch (IOException | InterruptedException ex) {
Logger.getLogger(LANScanner.class.getName()).log(Level.SEVERE, null, ex);
}
return reachable;
}
/**
* Exemple de plage de port à scanner
*
* @param ip adresse ip du poste
* @return String
*/
private String scanPort(String ip) {
String openPort = "";
//Port de communication FTP
if (portIsOpen(ip, 21, 100)) {
openPort += " FTP";
}
//Port standard pour le web, par ex Apache
if (portIsOpen(ip, 80, 100)) {
openPort += " Http";
}
//Port d'une imprimante
if (portIsOpen(ip, 515, 100)) {
openPort += " Printer";
}
//Port du serveur MySql
if (portIsOpen(ip, 3306, 100)) {
openPort += " MySql";
}
return openPort.trim();
}
/**
* Tester l'état du port sur un poste
*
* @param ip adresse ip du poste
* @param port Numero du port
* @param timeout délai en ms
* @return port ouvert ou non
*/
private boolean portIsOpen(String ip, int port, int timeout) {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
return true;
} catch (Exception ex) {
return false;
}
}
/**
* Exemple de scan sur la plage 192.168.2.0
*
* @param args
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException {
LANScanner lan = new LANScanner();
lan.enumLocalNetwork("192.168.2.0");
}
}
Exemple de scan réseau
La zone verte de notre réseau informatique est fixée à la plage 192.168.2.0 à 192.168.2.255. Pour lancer le scan, j'ai lancé l'exploration avec la fonction lan.enumLocalNetwork("192.168.2.0");A la lecture des résultats, on se rend compte que mine de rien JAVA est capable de fournir de nombreuses informations sur le réseau local. L'exploration a identifié :
- les serveurs, poste ayant les ports FTP et MySql ouverts,
- les imprimantes réseaux,
- les postes de travail.
Explorer les postes sur le LAN
Pourquoi en sommes nous arrivés à scanner notre propre réseau ? En fait, les postes clients se connectent via une adresses ip attribué par le DHCP. N'ayant pas envie de reconfigurer tous les postes de travail, nous avons chercher une solution pour retrouver les ordinateurs dans une application JAVA.Attention: explorer le réseau de cette manière est déconseillée ! En effet, la méthode 'brute force' avec détection de port ouvert est la première étape lors d'une attaque sur un réseau.
Donc avant de lancer l'exemple au boulot, de manière répétitive, il est préférable de prévenir l'administrateur système de votre réseau.