leer imagenes digitalizar con java sockets ip port-scanning

con - digitalizar imagenes en java



La forma más rápida de escanear puertos con Java (6)

Hice un escáner de puertos muy simple, pero funciona demasiado lento, así que estoy buscando la forma de escanearlo más rápido. Aquí está mi código:

public 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; } }

este código aquí prueba si el puerto específico está abierto en ip específica. Para el tiempo de espera, uso un valor mínimo de 200 porque cuando bajo, no tiene tiempo suficiente para probar el puerto. Bueno, funciona bien, pero lleva demasiado tiempo escanear de 0 a 65535. ¿Hay alguna otra forma de escanear de 0 a 65535 en menos de 5 minutos?



Escribí mi propio servicio asíncrono de explorador de puertos de Java que puede escanear puertos a través de TCP-SYN-Scan como lo hace Nmap. También admite escaneos de ping IMCP y puede trabajar con un rendimiento muy alto (dependiendo de lo que la red pueda soportar):

https://github.com/subes/invesdwin-webproxy

Internamente, utiliza un pcap vinculante de Java y expone sus servicios a través de JMS / AMQP. Aunque también puedes usarlo directamente en tu aplicación si no te importa que tenga permisos de root.


La muestra del código está inspirada en "Bruno Reis"

class PortScanner { public static void main(final String... args) throws InterruptedException, ExecutionException { final ExecutorService es = Executors.newFixedThreadPool(20); final String ip = "127.0.0.1"; final int timeout = 200; final List<Future<ScanResult>> futures = new ArrayList<>(); for (int port = 1; port <= 65535; port++) { // for (int port = 1; port <= 80; port++) { futures.add(portIsOpen(es, ip, port, timeout)); } es.awaitTermination(200L, TimeUnit.MILLISECONDS); int openPorts = 0; for (final Future<ScanResult> f : futures) { if (f.get().isOpen()) { openPorts++; System.out.println(f.get().getPort()); } } System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " + timeout + "ms)"); } public static Future<ScanResult> portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) { return es.submit(new Callable<ScanResult>() { @Override public ScanResult call() { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(ip, port), timeout); socket.close(); return new ScanResult(port, true); } catch (Exception ex) { return new ScanResult(port, false); } } }); } public static class ScanResult { private int port; private boolean isOpen; public ScanResult(int port, boolean isOpen) { super(); this.port = port; this.isOpen = isOpen; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public boolean isOpen() { return isOpen; } public void setOpen(boolean isOpen) { this.isOpen = isOpen; } } }



Si decide usar la opción Nmap y quiere continuar con Java, debe mirar Nmap4j en SourceForge.net (http://nmap4j.sourceforge.net). Es una API simple que te permite integrar Nmap en una aplicación java.

--Jon


Si necesita 200ms para cada uno de los 65536 puertos (en el peor de los casos, un firewall está bloqueando todo, lo que hace que supere su tiempo de espera para cada puerto), la matemática es bastante simple: necesita 13k segundos, o aproximadamente 3 horas y un medio.

Tienes 2 opciones (no exclusivas) para hacerlo más rápido:

  • reduzca su tiempo de espera
  • paralelizar su código

Dado que la operación está ligada a E / S (en contraste con el límite de la CPU, es decir, usted pasa tiempo esperando la E / S, y no para completar un gran cálculo), puede usar muchos, muchos hilos . Intente comenzar con 20. Ellos dividirían las 3 horas y media entre ellos, por lo que el tiempo máximo esperado es de aproximadamente 10 minutos . Solo recuerde que esto presionará al otro lado, es decir, el host escaneado verá una gran actividad de red con patrones "irracionales" o "extraños", haciendo que el escaneo sea extremadamente fácil de detectar.

La forma más sencilla (es decir, con cambios mínimos) es utilizar ExecutorService y Future APIs:

public static Future<Boolean> portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) { return es.submit(new Callable<Boolean>() { @Override public Boolean call() { try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(ip, port), timeout); socket.close(); return true; } catch (Exception ex) { return false; } } }); }

Entonces, puedes hacer algo como:

public static void main(final String... args) { final ExecutorService es = Executors.newFixedThreadPool(20); final String ip = "127.0.0.1"; final int timeout = 200; final List<Future<Boolean>> futures = new ArrayList<>(); for (int port = 1; port <= 65535; port++) { futures.add(portIsOpen(es, ip, port, timeout)); } es.shutdown(); int openPorts = 0; for (final Future<Boolean> f : futures) { if (f.get()) { openPorts++; } } System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " + timeout + "ms)"); }

Si necesita saber qué puertos están abiertos (y no solo cuántos , como en el ejemplo anterior), tendría que cambiar el tipo de devolución de la función a Future<SomethingElse> , donde SomethingElse contendría el puerto y el resultado del escaneo, algo así como:

public final class ScanResult { private final int port; private final boolean isOpen; // constructor // getters }

Luego, cambie Boolean a ScanResult en el primer fragmento y devuelva un new ScanResult(port, true) o un new ScanResult(port, false) lugar de solo true o false

EDITAR: En realidad, acabo de notar: en este caso particular, no necesita la clase ScanResult para mantener el resultado + puerto, y todavía saber qué puerto está abierto. Como agrega los futuros a una lista , que está ordenada y, luego, los procesa en el mismo orden en que los agregó , podría tener un contador que incrementaría en cada iteración para saber con qué puerto está tratando. . Pero, oye, esto es solo para ser completo y preciso. Nunca intentes hacer eso , es horrible, estoy avergonzado de haber pensado en esto ... Usar el objeto ScanResult es mucho más limpio , el código es mucho más fácil de leer y mantener, y te permite, más adelante, por ejemplo, use un CompletionService para mejorar el escáner.