Nmap (Network Mapper) to jedno z najbardziej rozpoznawalnych narzędzi w świecie cyberbezpieczeństwa. Służy do wykrywania hostów i usług w sieci komputerowej, a jego możliwości sięgają od prostego sprawdzenia, czy dany host jest dostępny, aż po zaawansowane wykrywanie systemu operacyjnego, wersji usług i luk bezpieczeństwa za pomocą silnika skryptowego NSE.
Wyniki skanowania wyświetlane w terminalu są przydatne na co dzień, jednak w środowiskach zawodowych — podczas audytów, testów penetracyjnych, inwentaryzacji sieci czy raportowania dla klientów — potrzebujemy czegoś więcej. Potrzebujemy dokumentu, który można wysłać mailem, wgrać do Excela lub zaprezentować na spotkaniu.
W tym miejscu pojawia się projekt Eksport-do-DOCX-HTML-CSV dostępny na GitHubie pod adresem github.com/Arkadiusz86/Eksport-do-DOCX-HTML-CSV. Zestaw trzech skryptów Pythona przekształca wyjście XML Nmapa w trzy użyteczne formaty: arkusz CSV, stronę HTML i dokument Word. Co ważne — skrypty są w pełni uniwersalne: działają niezależnie od użytych flag skanowania. Jeśli w pliku XML są dane o systemie operacyjnym, wynikach NSE, adresach MAC czy czasie działania hosta — zostaną wyeksportowane.
Kompletny workflow raportowania skanów
W praktyce bezpieczeństwa (pentesty, audyty, monitoring) sam wynik skanu to za mało. Kluczowe jest jego przetworzenie do czytelnych raportów oraz formatów możliwych do dalszej analizy (Excel, SIEM, dokumentacja).
Standardowy pipeline wygląda tak:
- Skan → XML
- XML → HTML (raport dla ludzi)
- XML → CSV (analiza danych)
- HTML → DOCX (raport formalny)
Dlaczego XML jest podstawą
Nmap natywnie wspiera wiele formatów, ale XML jest najważniejszy, ponieważ:
- jest strukturalny (łatwy do parsowania)
- przenośny między systemami
- kompatybilny z narzędziami (Python, SIEM, BI)
- stanowi bazę do konwersji na inne formaty
1. Punkt wyjścia: poprawny skan Nmap
Cały proces zaczyna się od XML:
nmap -sC -sV -oX scan.xml 192.168.1.0/24
Lub standardowo:
nmap -sC -sV -oA scan 192.168.1.0/24
Plik scan.xml jest źródłem dla wszystkich dalszych operacji.
Format XML w Nmap
Nmap potrafi zapisywać wyniki w kilku formatach: normalnym tekstowym (-oN), „grepable” (-oG), XML (-oX) oraz wszystkich jednocześnie (-oA). Format XML jest zdecydowanie najbardziej wartościowy z perspektywy automatycznego przetwarzania — jest ustrukturyzowany, dobrze zdefiniowany i obsługiwany przez standardowe biblioteki w każdym języku programowania.
Typowy plik XML Nmapa ma następującą hierarchię:
<nmaprun args="nmap -O -sV ..." version="7.99" startstr="Tue Mar 31...">
<host>
<status state="up" reason="echo-reply"/>
<address addr="192.168.1.1" addrtype="ipv4"/>
<address addr="AA:BB:CC:DD:EE:FF" addrtype="mac" vendor="Cisco"/>
<hostnames>
<hostname name="router.local" type="PTR"/>
</hostnames>
<ports>
<port protocol="tcp" portid="80">
<state state="open" reason="syn-ack"/>
<service name="http" product="Apache httpd" version="2.4.54"
extrainfo="(Ubuntu)" method="probed" conf="10"/>
<script id="http-title" output="Apache2 Default Page"/>
</port>
</ports>
<os>
<osmatch name="Linux 5.x" accuracy="95"/>
</os>
<uptime seconds="86400" lastboot="Mon Mar 30 08:00:00 2026"/>
<distance value="1"/>
</host>
<runstats>
<finished elapsed="12.34"/>
<hosts up="3" down="3" total="6"/>
</runstats>
</nmaprun>
Skrypty projektu parsują całą tę strukturę — nie tylko porty i usługi, ale również metadane skanowania, informacje o systemach operacyjnych, adresy MAC, wyniki skryptów NSE, uptime hosta, odległość sieciową i wiele więcej.
Najważniejsze flagi Nmap
Bogactwo danych w pliku XML zależy bezpośrednio od użytych flag skanowania. Poniższa tabela przedstawia najważniejsze z nich i ich wpływ na zawartość eksportu:
| Flaga | Opis | Co dodaje do XML | Wymaga root? |
|---|---|---|---|
-sS | SYN Scan (stealth) | Porty TCP, stan, powód | Tak |
-sV | Wykrywanie wersji usług | Produkt, wersja, extrainfo, metoda detekcji, CPE | Nie |
-O | Wykrywanie systemu operacyjnego | Pole os/osmatch z nazwą i dokładnością | Tak |
-sU | Skanowanie UDP | Porty UDP z protokołem „udp” | Tak |
--script <nazwa> | Skrypty NSE | Elementy <script id="..." output="..."/> | Zależy od skryptu |
-A | Agresywne skanowanie | OS + wersje + traceroute + domyślne NSE | Tak |
--traceroute | Śledzenie trasy | Element <distance> z liczbą hopów | Tak |
-Pn | Pomiń wykrywanie hostów | Skanuje host nawet gdy nie odpowiada na ping | Nie |
-p- | Wszystkie porty (1–65535) | Kompletna lista portów zamiast domyślnych 1000 | Nie |
-oX plik.xml | Zapis do XML | Tworzy plik XML — wymagany przez skrypty | Nie |
Skrypty eksportu działają poprawnie niezależnie od kombinacji powyższych flag. Jeśli dana informacja nie była zbierana podczas skanowania, pole w raporcie pozostanie puste — nie pojawi się żaden błąd.
Przeprowadzenie skanowania
Podstawowa sekwencja: uruchom skanowanie z flagą -oX, a następnie przetwórz plik wybranym skryptem:
Cel 192.168.1.0/24 → Nmap + -oX wynik.xml → Skrypt Python parse_*.py → Raport .csv / .html / .docx
Przykłady komend skanowania
Skanowanie podstawowe — tylko porty i usługi
nmap 192.168.1.1-6 -sV -oX wynik.xml
Rozszerzone — OS + wersje usług
sudo nmap 192.168.1.0/24 -O -sV -oX wynik.xml
Pełne skanowanie z NSE (wolne, szczegółowe)
sudo nmap 192.168.1.0/24 -A --script=default,vuln -oX wynik.xml
Skanowanie UDP i TCP razem
sudo nmap -sS -sU -sV -O -p U:53,123,161,T:22,80,443 192.168.1.1 -oX wynik.xml
Wszystkie porty (1–65535) z wykrywaniem wersji
nmap -p- -sV --open 192.168.1.1 -oX wynik.xml
Flagi -O, -sS i --traceroute wymagają uprawnień administratora (root/sudo na Linux, uruchomienia jako Administrator na Windows). Bez nich Nmap automatycznie przełącza się na skanowanie TCP Connect (-sT).
PowerShell — uruchomienie skanowania i eksportu jedną linią
W PowerShell operator && (z basha) nie działa w starszych wersjach. Używaj średnika ; lub -and do łączenia komend.
# Skanowanie + eksport CSV w jednej linii
nmap 192.168.1.1-6 -O -sV -oX wynik.xml ; python3 parse_csv.py wynik.xml
# Skanowanie + wszystkie trzy formaty
nmap 192.168.1.1-6 -O -sV -oX wynik.xml ; python3 parse_csv.py wynik.xml ; python3 parse_html.py wynik.xml ; python3 parse_docx.py wynik.xml
Uwaga na kolejność argumentów! Flaga -oX musi mieć tuż po niej nazwę pliku docelowego. Błąd -oX parse_csv.py wynik.xml spowoduje nadpisanie skryptu Pythona przez plik XML Nmapa, a wynik.xml zostanie potraktowany jako cel skanowania.
Architektura skryptów
Wszystkie trzy skrypty opierają się na tej samej zasadzie: parsują XML za pomocą standardowej biblioteki Pythona xml.etree.ElementTree (ewentualnie lxml dla transformacji XSLT), a następnie generują docelowy format raportu. Podejście jest dynamiczne — skrypty nie zakładają z góry, jakie pola będą wypełnione. Sprawdzają dostępność każdego elementu XML i wypełniają raport tym, co faktycznie znalazły.
Instalacja niezbędnych bibliotek do działania skryptów Windows oraz Linux !
Windows – PowerShell
python3 -m pip install lxml python-docx

Linux
python3 -m pip install lxml python-docx --break-system-packages

Dane wyciągane przez skrypty
Poniższa tabela pokazuje, które pola XML są obsługiwane przez każdy ze skryptów:
| Pole z XML Nmapa | CSV | HTML | DOCX |
|---|---|---|---|
| Adres IPv4 | Tak | Tak | Tak |
| Adres IPv6 | Tak | Tak | Tak |
| Adres MAC + producent | Tak | Tak | Tak |
| Hostname (PTR/user) | Tak | Tak | Tak |
| Stan hosta + powód | Tak | Tak | Tak |
| Port + protokół (TCP/UDP) | Tak | Tak | Tak |
| Stan portu + powód | Tak | Tak | Tak |
| Nazwa usługi | Tak | Tak | Tak |
| Produkt + wersja + extrainfo | Tak | Tak | Tak |
| CPE (Common Platform Enumeration) | Tak | Tak | Tak |
| Skrypty NSE (per-port) | Tak | Tak | Tak |
| Skrypty NSE (per-host) | — | Tak | Tak |
| System operacyjny + dokładność | Tak | Tak | Tak |
| Uptime + data ostatniego rebootu | Tak | Tak | Tak |
| Odległość sieciowa (TTL hops) | Tak | Tak | Tak |
| Metadane skanowania (komenda, czas) | — | Tak | Tak |
| Podsumowanie hostów (up/down/total) | — | Tak | Tak |
| Porty filtrowane (extraports) | — | Tak | Tak |
parse_csv.py
Skrypt parse_csv.py to najprostszy i najszybszy sposób na przeniesienie wyników skanowania do środowiska analitycznego. Generuje plik CSV z kodowaniem UTF-8 BOM — dzięki temu Excel na Windows automatycznie rozpoznaje polskie znaki bez konieczności ręcznego importowania z określonym kodowaniem.
Uruchomienie
python3 parse_csv.py wynik.xml
Skrypt automatycznie tworzy plik wynik.csv w tym samym katalogu co plik XML.
Struktura wyjściowa
Każdy wiersz CSV reprezentuje jeden port na jednym hoście. Host bez otwartych portów otrzymuje jeden wiersz z pustymi kolumnami portów — dzięki temu nie ginie z raportu. Kolumny pliku CSV:
IP, IPv6, MAC, Producent MAC, Hostname, Stan hosta, Powód stanu hosta,
Protokół, Port, Stan portu, Powód stanu portu, Usługa, Produkt, Wersja,
Dodatkowe info, Tunel, Metoda detekcji, Pewność detekcji,
CPE, Skrypty NSE, OS, Dokładność OS (%), Uptime (s), Ostatni reboot, Odległość (hop)
Jak to działa — kluczowe fragmenty kodu
Skrypt iteruje po wszystkich elementach <host> w XML, dla każdego wyciąga adresy różnych typów (IPv4, IPv6, MAC), a następnie zagnieżdżoną pętlą przechodzi po portach. Kluczowe zabezpieczenie — sprawdzenie if element is not None przed każdym dostępem — sprawia, że brak danego pola w XML nie powoduje wyjątku, tylko puste pole w CSV.
for host in root.findall('host'):
for addr in host.findall('address'):
atype = addr.attrib.get('addrtype', '')
if atype == 'ipv4': ip = addr.attrib.get('addr', '')
elif atype == 'mac': mac = addr.attrib.get('addr', '')
for port in ports.findall('port'):
svc = port.find('service')
svc_version = svc.attrib.get('version', '') if svc is not None else ''
# Skrypty NSE per-port
nse = ' | '.join(f"{s.attrib['id']}: {s.attrib['output']}"
for s in port.findall('script'))
Zastosowania CSV
- Filtrowanie i sortowanie portów w Excelu lub LibreOffice Calc
- Import do bazy danych (PostgreSQL, SQLite, MySQL)
- Analiza trendów w wielu skanowaniach (porównanie w czasie)
- Wejście dla innych skryptów automatyzacji
- Wizualizacje w narzędziach BI (Power BI, Tableau, Grafana)
Przykład wyniku skanowania z zakresu 6 hostów:

parse_html.py
Skrypt parse_html.py generuje kompletny, samodzielny plik HTML — bez żadnych zewnętrznych zależności CSS czy JavaScript. Raport można otworzyć bezpośrednio w przeglądarce lub wysłać mailem jako załącznik, który każdy odbiorca otworzy bez instalowania czegokolwiek.
Uruchomienie
python3 parse_html.py wynik.xml
Co zawiera wygenerowany HTML
- Nagłówek z datą skanowania, wersją Nmapa i użytą komendą
- Podsumowanie — liczba hostów online / offline / łącznie
- Karta każdego hosta z adresem IP, hostname, stanem, MAC, OS i uptime
- Tabela portów — port/protokół, stan (kolorowany), powód, usługa, wersja, CPE, NSE
- Sekcja skryptów hosta — wyniki NSE uruchomionych na poziomie hosta (np.
smb-os-discovery) - Informacja o portach filtrowanych — np. „998 portów w stanie: filtered”
Kolorowanie stanów
Skrypt stosuje semantyczne kolorowanie bez zewnętrznych bibliotek:
- 🟢 open — zielony (
#27ae60) - 🟠 filtered — pomarańczowy (
#e67e22) - ⚫ closed — szary (
#7f8c8d) - 🟢 Host up — zielony nagłówek karty
- 🔴 Host down — czerwony nagłówek karty
Dlaczego HTML, a nie PDF?
HTML jest edytowalny, przenośny i wyświetlany natywnie w każdej przeglądarce. Jeśli potrzebujesz PDF, wystarczy otworzyć plik HTML w przeglądarce i użyć opcji Drukuj → Zapisz jako PDF. Unikamy w ten sposób zależności od bibliotek do generowania PDF (które bywają problematyczne na Windows).
Przykład wyniku skanowania z zakresu 6 hostów:

parse_docx.py
Skrypt parse_docx.py tworzy profesjonalny dokument Word przy użyciu biblioteki python-docx. To najdokładniejszy format z punktu widzenia prezentacji — z tabelami, kolorowymi nagłówkami, formatowaniem tekstu i podziałem na sekcje per host.
Uruchomienie
python3 parse_docx.py wynik.xml
Struktura dokumentu DOCX
- Tytuł — „Raport Nmap” wycentrowany na górze
- Metadane — data skanowania, wersja Nmapa, czas skanowania, użyta komenda
- Tabela podsumowania — hosty online (zielona), offline (czerwona), łącznie (niebieska)
- Sekcja per host — kolorowany nagłówek z IP (zielony = up, czerwony = down), klucz-wartość z MAC, OS, hostname, uptime, odległością
- Tabela portów — 9 kolumn, nagłówki na ciemnoszarym tle, stan portu kolorowany
- Skrypty NSE hosta — jako lista punktowana pod tabelą portów
- Informacja o filtrowanych portach — kursywą poniżej tabeli
Formatowanie tabel
Biblioteka python-docx wymaga precyzyjnego ustawienia szerokości kolumn — zarówno na poziomie tabeli (columnWidths), jak i każdej komórki z osobna. Skrypt stosuje jednostki DXA (1440 DXA = 1 cal) i precyzyjnie rozkłada 9 kolumn na dostępną szerokość strony A4 z marginesami 2 cm.
col_labels = ['Port/Proto', 'Stan', 'Powód', 'Usługa',
'Produkt', 'Wersja', 'Info dodatkowe', 'CPE', 'Skrypty NSE']
col_widths = [2.2, 1.6, 2.0, 2.2, 2.8, 2.2, 2.8, 3.0, 4.0] # w cm
Przykład wyniku skanowania z zakresu 6 hostów:

Praktyczne przypadki użycia
Inwentaryzacja sieci firmowej
Administrator sieci skanuje całą podsieć, generuje CSV i importuje wyniki do arkusza inwentaryzacyjnego. Dzięki polom MAC i producenta karty sieciowej możliwe jest szybkie przypisanie adresów IP do urządzeń fizycznych — przełączników, drukarek, kamer IP czy stacji roboczych.
sudo nmap 10.0.0.0/16 -sn -oX siec.xml # szybka inwentaryzacja bez skanowania portów
python3 parse_csv.py siec.xml
Raport po teście penetracyjnym
Pentester po zakończeniu skanowania generuje dokument DOCX, który stanowi podstawę raportu technicznego. Tabele portów z wersjami usług i wynikami NSE (np. wykryte podatności z --script vuln) trafiają bezpośrednio do sekcji „Wyniki skanowania” raportu.
sudo nmap 10.10.10.0/24 -A --script=vuln,http-headers,smb-os-discovery -oX pentest.xml
python3 parse_docx.py pentest.xml
Monitoring zmian w infrastrukturze
Porównanie dwóch plików CSV z różnych dat pozwala szybko wykryć nowe usługi, otwarte porty lub znikające hosty. Można to zautomatyzować skryptem diffującym dwa pliki CSV.
Audyt urządzeń IoT
Skanowanie segmentu sieci z urządzeniami IoT (kamery, drukarki, czujniki) z flagą -O i eksport do HTML daje szybki przegląd systemów operacyjnych i otwartych usług na każdym urządzeniu — co jest punktem wyjścia dla oceny ryzyka.
Uwagi prawne i etyczne
Skanowanie sieci bez zgody właściciela jest nielegalne w Polsce (art. 267 Kodeksu karnego — nieuprawniony dostęp do danych) i w większości krajów. Nmap i skrypty eksportujące należy używać wyłącznie na sieciach, do których posiadasz autoryzację — własnych, firmowych z odpowiednimi uprawnieniami lub w środowiskach testowych (np. homelab – Proxmox, laboratoriach CTF, maszynach HackTheBox/TryHackMe).
Zasady bezpiecznego i etycznego korzystania z narzędzi sieciowych:
- Zawsze uzyskaj pisemną zgodę właściciela sieci przed skanowaniem
- W środowiskach produkcyjnych preferuj mniej agresywne flagi (
-T2zamiast-T5) - Przechowuj raporty z wynikami skanowania w bezpieczny sposób — zawierają wrażliwe informacje o infrastrukturze
- Nie udostępniaj plików XML ani wygenerowanych raportów osobom nieupoważnionym
- Stosuj zasadę minimalnych uprawnień — skanuj tylko zakresy adresów, które musisz
Podsumowanie
Projekt Eksport-do-DOCX-HTML-CSV rozwiązuje praktyczny problem, z którym zmaga się wielu administratorów i specjalistów ds. bezpieczeństwa: jak szybko i profesjonalnie zaprezentować wyniki skanowania Nmap w formie nadającej się do raportowania.
Trzy skrypty Pythona pokrywają trzy różne potrzeby. CSV sprawdza się w analizie danych i automatyzacji. HTML to gotowy, natychmiastowy raport do przeglądania w przeglądarce lub wysyłki mailem. DOCX to profesjonalny dokument, który można wzbogacić o komentarze, stronę tytułową czy podpis i wysłać klientowi lub przełożonemu.
Kluczowa zaleta tego rozwiązania to uniwersalność. Skrypty nie są napisane pod konkretną kombinację flag Nmapa — dynamicznie odczytują wszystko, co znajdą w pliku XML. Dodanie flag takich jak --script vuln, -sU czy --traceroute automatycznie wzbogaca generowane raporty bez żadnych modyfikacji kodu.

