Java Port Scanner
Při scanování portů zjišťujeme, které služby jsou na síťové kartě, připojené na určité adrese, aktivní. Pro samotné scanování existuje několik způsobů. V tomto článku si vytvoříme jednoduchý scanner založený na metodě Connect.
Porty si můžeme představit jako služby na síťové kartě, které slouží pro indentifikaci na dané IP adrese, kdy je číslem portu jednoznačně určeno, k jaké službě jsou data přiřazena (například všem známý port 25, který značí SMTP).
V tomto článku si vytvoříme jednoduchý program, který bude zjišťovat, které porty jsou na dané IP adrese aktivní (které služby jsou povoleny).
Scanner bude velmi jednoduchý a bude používat metodu Connect, kdy se bude snažit připojit na danné IP adrese postupně k jednotlivým portům v rámci TCP vždy vytvořením nového Socketu.
Čím začneme je grafické rozhraní, čímž by jsem chtěl navázat na již získané znalosti z předchozích článků (Java a základy GUI,
Java a základy GUI 2,
Java a základy GUI 3,
Java a základy GUI 4).
GUI
K našemu programu si vytvoříme velice jednoduché grafické rozhraní, které bude sloužit pro ovládání programu.
V GUI budeme potřebovat vytvořit formulář pro vkládání dat, tlačítko pro odeslání a nakonec seznam s výpisem.
Do scanneru budeme zadávat IP adresu, kterou si rozdělíme na 4 části a rozsah portů (od-do), pro výstup můžeme použít například seznam List z AWT. Začneme tedy definicí proměnných:
1 2 3 4 5 6 7 |
private JTextField ip_input1; private JTextField ip_input2; private JTextField ip_input3; private JTextField ip_input4; public List ports; private JTextField from; private JTextField to; |
Nastavení okna nechám na vás a přejdu rovnou k umístění komponent do okna. Pro tuto potřebu si vytvořím Jpanel z knihovny javax.swing, ve kterém nastavím FlowLayout. Všechny prvky následně do tohoto panelu přidám:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
JPanel panelOvladani = new JPanel(); // stand. centruje panelOvladani.setLayout(new FlowLayout(FlowLayout.LEFT)); panelOvladani.add(new JLabel("IP adresa")); ip_input1 = new JTextField(3); ip_input1.setText("127"); panelOvladani.add(ip_input1); panelOvladani.add(new JLabel(".")); ip_input2 = new JTextField(3); ip_input2.setText("0"); panelOvladani.add(ip_input2); panelOvladani.add(new JLabel(".")); ip_input3 = new JTextField(3); ip_input3.setText("0"); panelOvladani.add(ip_input3); panelOvladani.add(new JLabel(".")); ip_input4 = new JTextField(3); panelOvladani.add(ip_input4); ip_input4.setText("1"); panelOvladani.add(new JLabel("Rozsah portů: ")); from = new JTextField(5); panelOvladani.add(from); from.setText("1"); panelOvladani.add(new JLabel(" - ")); to = new JTextField(5); panelOvladani.add(to); to.setText("500"); JButton submitform = new Jbutton("Scanovat"); submitform.setPreferredSize(new Dimension(280, 20)); panelOvladani.add(submitform); ports = new List(10); ports.setSize(100, 100); panelOvladani.add(ports); this.add(panelOvladani); |
Takto jsme jednoduše vytvořili grafické okno, které obsahuje formulář pro zadání dat, List pro jejich výpis a tlačítko pro odeslání.
Po odeslání tlačítka chceme aby se port scaner spustil. Musíme si tedy k tlačítku přiřadit událost:
1 2 3 4 5 6 7 8 9 10 11 |
submitform.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { try { check_form(); } catch (NumberFormatException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); |
Všimněte si že po kliknutí na tlačítko se spustí metoda check_form();, která má za úkol překontrolovat údaje ve formuláři.
Všechno co potřebujeme kontrolovat je IP adresa, jejíž jednotlivé části musí být v rozsahu 0-255 a rozsah portů, který je opět omezen a to velikostí 0-65535. Nakonec ještě zkontrolujeme, zda konečný port není větší než počáteční port:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
public void check_form() throws NumberFormatException, InterruptedException { try { if (Integer.valueOf(ip_input1.getText()) < 0 || Integer.valueOf(ip_input1.getText()) > 255 || Integer.valueOf(ip_input2.getText()) < 0 || Integer.valueOf(ip_input2.getText()) > 255 || Integer.valueOf(ip_input3.getText()) < 0 || Integer.valueOf(ip_input3.getText()) > 255 || Integer.valueOf(ip_input4.getText()) < 0 || Integer.valueOf(ip_input4.getText()) > 255) { JOptionPane.showMessageDialog(null, "Chybně zadaná IP adresa", "Error", JOptionPane.ERROR_MESSAGE); } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Chybně zadaná IP adresa", "Error", JOptionPane.ERROR_MESSAGE); } try { if (Integer.valueOf(from.getText()) < 1 || Integer.valueOf(from.getText()) > 65535) { JOptionPane.showMessageDialog(null, "Chybně zadaný rozsah portů", "Error", JOptionPane.ERROR_MESSAGE); } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Chybně zadaný rozsah portů", "Error", JOptionPane.ERROR_MESSAGE); } try { if (Integer.valueOf(to.getText()) < 1 || Integer.valueOf(to.getText()) > 65535) { JOptionPane.showMessageDialog(null, "Chybně zadaný rozsah portů", "Error", JOptionPane.ERROR_MESSAGE); } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Chybně zadaný rozsah portů", "Error", JOptionPane.ERROR_MESSAGE); } if (Integer.valueOf(to.getText()) < Integer.valueOf(from.getText())) { JOptionPane .showMessageDialog( null, "Chybně zadaný rozsah portůnMaximální rozsah musí být větší než minimální", "Error", JOptionPane.ERROR_MESSAGE); } String IpAdress = ip_input1.getText() + "." + ip_input2.getText() + "." + ip_input3.getText() + "." + ip_input4.getText(); scan(IpAdress, Integer.valueOf(from.getText()), Integer.valueOf(to .getText())); } |
Pokud nastane ve formuláři chyba, dáme o tom uživateli vědět vytvořením JoptionPane ve formě Error_Message a nic se nestane.
V případě, že všechno proběhne správně, vytvoříme IP adresu tím, že spojíme její jednotlivé části a zavoláme metodu pro scanování.
Metoda pro scanování bude obsahovat jeden cyklus for, ve kterém projde od prvního portu do posledního zadaného a pokusí se na zadané IP adrese k portu připojit.
Pro operaci připojení k portu si vytvoříme samostatnou třídu, do které předáme IP adresu, Port a ukazatel na seznam List, do kterého v případě úspěchu přidá otevřený port.
Metoda scan():
1 2 3 4 5 6 7 |
public void scan(String IpAdress, int from, int to) throws InterruptedException { delete_items(); for (int i = from; i <= to; i++) { PortScanner p = new PortScanner(IpAdress, i, ports); } } |
Navíc metoda scan() volá metodu delete_items() pro případ, že by jste scanování opakovali a potřebovali vymazat seznam List.
Class PortScanner
Třída PortScanner není nijak složitá. Pro každý port se bude snažit vytvořit nový Socket na dané IP adrese a portu. V případě že se to podaří přidá tento port do předaného Listu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class PortScanner extends Thread implements Runnable { public int port; public String IpAdress; private List in; public PortScanner(String IpAdress, int Port, List input) { this.port = Port; this.IpAdress = IpAdress; this.in = input; Thread t = new Thread(this); t.start(); } public void run() { try { Socket s = new Socket(IpAdress, port); in.add(port + "/tcp: Open " + return_port(port)); s.close(); } catch (SocketException e) { ; } catch (IOException e) { System.out.println(e + " while trying" + IpAdress + ":" + port); } } } |
Třída tedy přijme tři proměnné, v konsturktoru je nastaví a spustí nové vlákno programu.
V tomto vlákně se program pokusí připojit na daný port a v případě že se to povede přidá hodnotu portu do předaného Listu.
Třída je navíc doplněna metodou return_port, který vrací dle daného portu jeho slovní vyjádření.
Tato metoda je opět velice jednoduchá. Obsahuje pouze pole portů a vstupní parametr představuje index pole. Vrací hodnotu tohoto indexu.
Seznam portů můžete čerpat například z wikipedie.
Celý výsledek může vypadat takto:
Ahoj, máš to pěkný, jen tak dál. Jako začátečníka mě to hodně naučilo:)
Man, you turn on any news station and there’s a balanced panel on the post-debate. You turn to FOX, and you would think Romney’s President
Another great aspect of the screw compressor is that they can use oil in the process, or be completely oil free.
Trackbacks for this post