Nmap eigenes Script: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
*[[Nmap eigenes Script Erläuterung]]
+
 
*[[Nmap eigenes Script Beispiele]]
 
 
=Nmap eigenes Script Erläuterung=
 
=Nmap eigenes Script Erläuterung=
 +
 +
=Grundsätzliches=
 +
Der Artikel ist aus dem englischen von Alexis Rodriguez übersetzt.
 +
*https://medium.com/@bin3xish477
 +
 +
Nmap wird mit Hunderten von Skripten geliefert. Viele dieser Skripte werden tatsächlich ausgeführt, wenn Sie Nmap mit dem häufig verwendeten Flag -sC ausführen. Diese Skripte führen beispielsweise grundlegende HTTP-Aufzählungen durch, versuchen, eine Verbindung zu SMB-Freigaben herzustellen und diese aufzulisten, greifen auf Dienstbanner zu usw. Das Schreiben Ihrer eigenen NSE-Skripte kann jedoch äußerst nützlich sein. Hier ist zum Beispiel ein NSE-Skript, das Anwendungen in Ihrem Netzwerk entdeckt, die anfällig für den kürzlich offenbarten Exploit gegen die beliebte Log4J-Bibliothek sind, die immer noch in freier Wildbahn ausgenutzt wird. Lassen Sie uns ein wenig über die Struktur eines NSE-Skripts sprechen.
 +
=Aufbau eines NSE-Skripts=
 +
Die Struktur eines NSE-Skripts ist einfach. Es gibt fünf (5) Funktionen, nach denen die Nmap-Skript-Engine in einem NSE-Skript sucht, um sie auszuführen:
 +
 +
==prerule()==
 +
wird einmal ausgeführt, bevor Hosts gescannt werden
 +
==hostrule(host)==
 +
wird ausgeführt, nachdem Hosts gescannt wurden
 +
==portrule(host, port)==
 +
wird ausgeführt, nachdem Hosts gescannt wurden
 +
==postrule()==wird ausgeführt, nachdem alle Hosts gescannt wurden; Wird normalerweise zum Berichten/Parsen von Daten verwendet, die während des Scannens angesammelt wurden
 +
==action(host, port)==
 +
wird ausgeführt, wenn eine der Triggerfunktionen (oben aufgeführt) ausgelöst wird; entspricht der Hauptfunktion eines normalen Programms, das die gesamte Logik des Skripts enthält.
 +
 +
Ein NSE-Skript muss eine der oben definierten ausgelösten Funktionen enthalten, die bestimmt, ob die im Hauptteil der Aktionsfunktion angegebenen Anweisungen ausgeführt werden. Hier ist eine Vorlage, die alle Mindestanforderungen zum Schreiben eines NSE-Skripts enthält:
 +
=NSE-Skriptvorlage=
 +
Wie Sie sehen können, habe ich einige globale Variablen und einige Funktionen definiert und auch einige Kommentare eingefügt, die Sie normalerweise auch in einem NSE-Skript finden. Gehen wir einige der Komponenten durch, aus denen dieses Skript besteht.
 +
=Kommentare=
 +
Es gibt einige Standardkommentare, die in einem NSE-Skript zu finden sind. Diese Kommentare werden normalerweise oben im Skript definiert und enthalten drei Anweisungen:
 +
==@usage==
 +
was eine beispielhafte Verwendung des Skripts mit dem Nmap-CLI-Tool demonstriert
 +
==@output==
 +
was dem Benutzer eine schnelle Beispielausgabe des Skripts liefert
 +
==@args==
 +
informiert den Benutzer über die Argumente, die an das Skript übergeben werden können, um das Standardverhalten des Skripts zu ändern
 +
 +
=Globale NSE-Variablen=
 +
So wie es Standardkommentare für NSE-Skripte gibt, gibt es auch eine Reihe globaler Variablen, die für jedes von Ihnen geschriebene NSE-Skript definiert werden sollten.
 +
 +
Die '''description''' Variable ist ein String (in Lua werden mehrzeilige Strings in '''[[]]''' eckigen Klammern definiert), der dem Benutzer eine detaillierte Beschreibung dessen liefert, was das Skript macht; Die '''author''' ariable ist eine Zeichenfolge oder ein Array, das den Autor des Skripts angibt. die '''licence''' Variable stellt die Lizenz bereit, mit der das Skript vertrieben wird; und die '''categorie''' Variable ist ein Array, das die Nmap-Kategorien definiert, zu denen das Skript gehört.
 +
 +
=Beschreibungen=
 +
<pre>
 +
description = [[
 +
This is the description for this NSE script.
 +
]]
 +
author = "John Wick"
 +
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
 +
categories = {"safe", "discovery"}
 +
</pre>
 +
 +
=Trigger- und Aktionsfunktionen=
 +
Wie bereits erwähnt, sucht die Nmap Scripting Engine nach fünf Funktionen im Hauptteil eines NSE-Skripts. In der oben bereitgestellten Vorlage habe ich die Funktionen '''hostrule, portrule und action''' verwendet, um das Verhalten des NSE-Skripts zu definieren. Alle Triggerfunktionen, '''prerule, hostrule, portrule oder postrule''' , geben einen booleschen Wert zurück – wenn einer der von diesen Funktionen zurückgegebenen Werte falsch ist, wird der in der '''acion''' Funktion definierte Code abhängig von der Phase des Scans nicht ausgeführt.
 +
=Hello World=
 +
Ein einfaches Hello World Skript
 +
<pre>
 +
description = [[
 +
Simple Hello World Script.
 +
]]
 +
---
 +
-- @output
 +
-- Hello World
 +
author = "Thomas Will"
 +
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
 +
categories = {"nothing"}
 +
function hostrule()
 +
  return true
 +
end
 +
function portrule()
 +
  return true
 +
end
 +
function action(host, port)
 +
    return("Hello World")
 +
end
 +
</pre>
 +
==Ausgabe==
 +
*nmap -sn --script helloworld.nse 192.168.34.1
 +
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-26 12:20 CET
 +
Nmap scan report for 192.168.34.1
 +
Host is up (0.00036s latency).
 +
 +
Host script results:
 +
'''|_helloworld: Hello World'''
 +
 +
Nmap done: 1 IP address (1 host up) scanned in 0.26 secon
 +
 +
=Ein Beispiel-NSE-Skript=
 +
Das folgende NSE-Skript ist ein einfaches Skript, das prüft, ob die Ziel-IP-Adresse privat ist, prüft, ob die Ports 80/tcp oder 443/tcp geöffnet sind oder ob ein Port einen Dienst ausführt, der über HTTP oder HTTPS läuft – sofern die Bedingungen erfüllt sind true , druckt der Code in der Aktionsfunktion den vom Server zurückgegebenen HTTP-Server-Header. **HINWEIS**: Ich habe keine Kommentare eingefügt, da dieses Skript zu Demonstrationszwecken dient, Ihre Nicht-Demo-Skripte sollten jedoch Kommentare enthalten!
 +
<pre>
 +
---
 +
-- @usage
 +
--
 +
-- @output
 +
--
 +
-- @args
 +
--
 +
---
 +
 +
local shortPort = require "shortport"
 +
local ipOps = require "ipOps"
 +
local http = require "http"
 +
local stdNse = require "stdnse"
 +
local b64 = require "base64"
 +
 +
description = [[
 +
An example NSE script that simply makes an HTTP request to
 +
any HTTP(S) ports it finds while echoing the request status line
 +
to stdout
 +
]]
 +
 +
author = {"Alexis Rodriguez"}
 +
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
 +
categories = {
 +
  "safe"
 +
}
 +
 +
function hostrule(host)
 +
  -- checks if IP address is local, if not,
 +
  -- script won't run
 +
  return ipOps.isPrivate(host)
 +
end
 +
 +
function portrule()
 +
  -- returns a function that matches on ports, services, protocol, and state
 +
  return shortPort.port_or_service({80, 443}, {"http", "https"}, "tcp", "open")
 +
end
 +
 +
function action(host, port)
 +
  -- debug logs
 +
  stdNse.debug(1, "IP::%s", host.ip)
 +
  stdNse.debug(1, "PORT::%s", port.number)
 +
 +
  opts = {}
 +
  local resp = http.get(host, port, "/", opts)
 +
 +
  return stdNse.format_output(
 +
    true, string.format("Server Header ==> %s", resp.header["server"])
 +
  )
 +
end
 +
</pre>
 +
 +
http-server-header.nse
 +
 +
=Das Skript laufen lassen=
 +
Sehen Sie sich den Quellcode auf meinem GitHub an. Speichern Sie das Skript als http-server-header.nse und führen Sie das Skript mit dem folgenden Befehl aus:
 +
 +
*nmap -Pn --script ./http-server-header.nse -d -p 80 scanme.nmap.org
 +
nmap -Pn --script ./http-server-header.nse -d -p 80 scanme.nmap.org
 +
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-26 10:59 CET
 +
--------------- Timing report ---------------
 +
  hostgroups: min 1, max 100000
 +
  rtt-timeouts: init 1000, min 100, max 10000
 +
  max-scan-delay: TCP 1000, UDP 1000, SCTP 1000
 +
  parallelism: min 0, max 0
 +
  max-retries: 10, host-timeout: 0
 +
  min-rate: 0, max-rate: 0
 +
---------------------------------------------
 +
NSE: Using Lua 5.3.
 +
NSE: Arguments from CLI:
 +
NSE: Loaded 1 scripts for scanning.
 +
NSE: Script Pre-scanning.
 +
NSE: Starting runlevel 1 (of 1) scan.
 +
Initiating NSE at 10:59
 +
Completed NSE at 10:59, 0.00s elapsed
 +
mass_rdns: Using DNS server 127.0.0.53
 +
Initiating Parallel DNS resolution of 1 host. at 10:59
 +
mass_rdns: 0.15s 0/1 [#: 1, OK: 0, NX: 0, DR: 0, SF: 0, TR: 1]
 +
Completed Parallel DNS resolution of 1 host. at 11:00, 0.15s elapsed
 +
DNS resolution of 1 IPs took 0.15s. Mode: Async [#: 1, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
 +
Initiating Connect Scan at 11:00
 +
Scanning scanme.nmap.org (45.33.32.156) [1 port]
 +
Discovered open port 80/tcp on 45.33.32.156
 +
Completed Connect Scan at 11:00, 0.18s elapsed (1 total ports)
 +
Overall sending rates: 5.56 packets / s.
 +
NSE: Script scanning 45.33.32.156.
 +
NSE: Starting runlevel 1 (of 1) scan.
 +
Initiating NSE at 11:00
 +
'''NSE: Starting http-server-header against scanme.nmap.org (45.33.32.156:80).'''
 +
'''NSE: Finished http-server-header against scanme.nmap.org (45.33.32.156:80).'''
 +
'''Completed NSE at 11:00, 0.72s elapsed'''
 +
Nmap scan report for scanme.nmap.org (45.33.32.156)
 +
Host is up, received user-set (0.18s latency).
 +
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
 +
Scanned at 2023-02-26 11:00:00 CET for 0s
 +
 +
PORT  STATE SERVICE REASON
 +
80/tcp open  http    syn-ack
 +
|_http-server-header: Apache/2.4.7 (Ubuntu)
 +
Final times for host: srtt: 179510 rttvar: 179510  to: 897550
 +
 +
'''NSE: Script Post-scanning.'''
 +
'''NSE: Starting runlevel 1 (of 1) scan.'''
 +
'''Initiating NSE at 11:00'''
 +
'''Completed NSE at 11:00, 0.00s elapsed'''
 +
Read from /usr/bin/../share/nmap: nmap-services.
 +
Nmap done: 1 IP address (1 host up) scanned in 1.40 seconds
 +
 +
 +
 +
 +
Aus dieser Ausgabe können wir sehen, dass Nmap das Skript erfolgreich geladen und ausgeführt hat und den Server-Header des HTTP-Servers wie erwartet anzeigt.
 +
 +
EOF
 +
 +
Wenn Sie diesen Artikel gerne gelesen haben, folgen Sie mir bitte auf Medium für weitere Artikel zu Cybersicherheit/Technologie und auf GitHub für weitere Programmierprojekte zur Cybersicherheit. Vielen Dank für Ihre Zeit!
 +
 +
=Quelle=
 +
*https://medium.com/geekculture/writing-nmap-scripts-49aaa8b153e0
 +
 
=Nmap eigenes Script Beispiele=
 
=Nmap eigenes Script Beispiele=
 +
=Echt Koelnisch Wasser=
 +
==Skript==
 +
*vi echtkoelnisch.nse
 +
<pre>
 +
description = [[
 +
Prüft, ob Port 4711 offen ist, und gibt eine Nachricht aus:
 +
"Dies riecht nach Echt Kölnisch Wasser".
 +
]]
 +
 +
author = "Thomas"
 +
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
 +
categories = {"default", "discovery"}
 +
 +
portrule = function(host, port)
 +
  return port.number == 4711 and port.protocol == "tcp"
 +
end
 +
 +
action = function(host, port)
 +
  if port.state == "open" then
 +
    return "Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!"
 +
  end
 +
end
 +
</pre>
 +
==Aufruf==
 +
*nmap --script ./echtkoelnisch.nse -p 4711 10.0.10.104
 +
<pre>
 +
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:14 CEST
 +
Nmap scan report for opfer.secure.local (10.0.10.104)
 +
Host is up (0.00093s latency).
 +
 +
PORT    STATE SERVICE
 +
4711/tcp open  trinity-dist
 +
|_echtkoelnisch: Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!
 +
MAC Address: 08:00:27:70:6B:BA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
 +
 +
Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds
 +
</pre>
 +
=Checkmk Agent unverschlüsselt=
 +
==Skript==
 +
*vi checkmk-plain.nse
 +
<pre>
 +
description = [[
 +
Checks if an unencrypted Checkmk Agent is responding on port 6556.
 +
If the header <<<check_mk>>> is found, it is considered a potential information disclosure vulnerability.
 +
]]
 +
 +
author = "Thomas"
 +
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
 +
categories = {"default", "discovery", "vuln"}
 +
 +
portrule = function(host, port)
 +
  return port.number == 6556 and port.protocol == "tcp"
 +
end
 +
 +
action = function(host, port)
 +
  local socket = nmap.new_socket()
 +
  socket:set_timeout(3000)
 +
  local status, err = socket:connect(host.ip, port.number)
 +
  if not status then
 +
    return "Connection failed: " .. err
 +
  end
 +
 +
  local data
 +
  status, data = socket:receive_lines(1)
 +
  socket:close()
 +
 +
  if status and data and data:find("<<<check_mk>>>") then
 +
    return "Unencrypted Checkmk Agent detected - potential information disclosure!"
 +
  end
 +
end
 +
</pre>
 +
==Aufruf==
 +
*nmap -sV --script ./checkmk-plain.nse  -p 6556 10.0.10.104
 +
<pre>
 +
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:26 CEST
 +
Nmap scan report for userver.secure.local (10.0.10.104)
 +
Host is up (0.0014s latency).
 +
 +
PORT    STATE SERVICE  VERSION
 +
6556/tcp open  check_mk check_mk extension for Nagios 2.0.0p38
 +
|_checkmk-plain: Unencrypted Checkmk Agent detected - potential information disclosure!
 +
MAC Address: 08:00:27:23:0C:75 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
 +
 +
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
 +
Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds
 +
</pre>
 +
 +
=Echt Koelnisch Wasser=
 +
==Skript==
 +
*vi echtkoelnisch.nse
 +
<pre>
 +
description = [[
 +
Prüft, ob Port 4711 offen ist, und gibt eine Nachricht aus:
 +
"Dies riecht nach Echt Kölnisch Wasser".
 +
]]
 +
 +
author = "Thomas"
 +
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
 +
categories = {"default", "discovery"}
 +
 +
portrule = function(host, port)
 +
  return port.number == 4711 and port.protocol == "tcp"
 +
end
 +
 +
action = function(host, port)
 +
  if port.state == "open" then
 +
    return "Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!"
 +
  end
 +
end
 +
</pre>
 +
==Aufruf==
 +
*nmap --script ./echtkoelnisch.nse -p 4711 10.0.10.104
 +
<pre>
 +
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:14 CEST
 +
Nmap scan report for opfer.secure.local (10.0.10.104)
 +
Host is up (0.00093s latency).
 +
 +
PORT    STATE SERVICE
 +
4711/tcp open  trinity-dist
 +
|_echtkoelnisch: Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!
 +
MAC Address: 08:00:27:70:6B:BA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
 +
 +
Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds
 +
</pre>
 +
=Checkmk Agent unverschlüsselt=
 +
==Skript==
 +
*vi checkmk-plain.nse
 +
<pre>
 +
description = [[
 +
Checks if an unencrypted Checkmk Agent is responding on port 6556.
 +
If the header <<<check_mk>>> is found, it is considered a potential information disclosure vulnerability.
 +
]]
 +
 +
author = "Thomas"
 +
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
 +
categories = {"default", "discovery", "vuln"}
 +
 +
portrule = function(host, port)
 +
  return port.number == 6556 and port.protocol == "tcp"
 +
end
 +
 +
action = function(host, port)
 +
  local socket = nmap.new_socket()
 +
  socket:set_timeout(3000)
 +
  local status, err = socket:connect(host.ip, port.number)
 +
  if not status then
 +
    return "Connection failed: " .. err
 +
  end
 +
 +
  local data
 +
  status, data = socket:receive_lines(1)
 +
  socket:close()
 +
 +
  if status and data and data:find("<<<check_mk>>>") then
 +
    return "Unencrypted Checkmk Agent detected - potential information disclosure!"
 +
  end
 +
end
 +
</pre>
 +
==Aufruf==
 +
*nmap -sV --script ./checkmk-plain.nse  -p 6556 10.0.10.104
 +
<pre>
 +
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:26 CEST
 +
Nmap scan report for userver.secure.local (10.0.10.104)
 +
Host is up (0.0014s latency).
 +
 +
PORT    STATE SERVICE  VERSION
 +
6556/tcp open  check_mk check_mk extension for Nagios 2.0.0p38
 +
|_checkmk-plain: Unencrypted Checkmk Agent detected - potential information disclosure!
 +
MAC Address: 08:00:27:23:0C:75 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
 +
 +
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
 +
Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds
 +
</pre>

Aktuelle Version vom 21. Juni 2026, 09:36 Uhr

Nmap eigenes Script Erläuterung

Grundsätzliches

Der Artikel ist aus dem englischen von Alexis Rodriguez übersetzt.

Nmap wird mit Hunderten von Skripten geliefert. Viele dieser Skripte werden tatsächlich ausgeführt, wenn Sie Nmap mit dem häufig verwendeten Flag -sC ausführen. Diese Skripte führen beispielsweise grundlegende HTTP-Aufzählungen durch, versuchen, eine Verbindung zu SMB-Freigaben herzustellen und diese aufzulisten, greifen auf Dienstbanner zu usw. Das Schreiben Ihrer eigenen NSE-Skripte kann jedoch äußerst nützlich sein. Hier ist zum Beispiel ein NSE-Skript, das Anwendungen in Ihrem Netzwerk entdeckt, die anfällig für den kürzlich offenbarten Exploit gegen die beliebte Log4J-Bibliothek sind, die immer noch in freier Wildbahn ausgenutzt wird. Lassen Sie uns ein wenig über die Struktur eines NSE-Skripts sprechen.

Aufbau eines NSE-Skripts

Die Struktur eines NSE-Skripts ist einfach. Es gibt fünf (5) Funktionen, nach denen die Nmap-Skript-Engine in einem NSE-Skript sucht, um sie auszuführen:

prerule()

wird einmal ausgeführt, bevor Hosts gescannt werden

hostrule(host)

wird ausgeführt, nachdem Hosts gescannt wurden

portrule(host, port)

wird ausgeführt, nachdem Hosts gescannt wurden ==postrule()==wird ausgeführt, nachdem alle Hosts gescannt wurden; Wird normalerweise zum Berichten/Parsen von Daten verwendet, die während des Scannens angesammelt wurden

action(host, port)

wird ausgeführt, wenn eine der Triggerfunktionen (oben aufgeführt) ausgelöst wird; entspricht der Hauptfunktion eines normalen Programms, das die gesamte Logik des Skripts enthält.

Ein NSE-Skript muss eine der oben definierten ausgelösten Funktionen enthalten, die bestimmt, ob die im Hauptteil der Aktionsfunktion angegebenen Anweisungen ausgeführt werden. Hier ist eine Vorlage, die alle Mindestanforderungen zum Schreiben eines NSE-Skripts enthält:

NSE-Skriptvorlage

Wie Sie sehen können, habe ich einige globale Variablen und einige Funktionen definiert und auch einige Kommentare eingefügt, die Sie normalerweise auch in einem NSE-Skript finden. Gehen wir einige der Komponenten durch, aus denen dieses Skript besteht.

Kommentare

Es gibt einige Standardkommentare, die in einem NSE-Skript zu finden sind. Diese Kommentare werden normalerweise oben im Skript definiert und enthalten drei Anweisungen:

@usage

was eine beispielhafte Verwendung des Skripts mit dem Nmap-CLI-Tool demonstriert

@output

was dem Benutzer eine schnelle Beispielausgabe des Skripts liefert

@args

informiert den Benutzer über die Argumente, die an das Skript übergeben werden können, um das Standardverhalten des Skripts zu ändern

Globale NSE-Variablen

So wie es Standardkommentare für NSE-Skripte gibt, gibt es auch eine Reihe globaler Variablen, die für jedes von Ihnen geschriebene NSE-Skript definiert werden sollten.

Die description Variable ist ein String (in Lua werden mehrzeilige Strings in [[]] eckigen Klammern definiert), der dem Benutzer eine detaillierte Beschreibung dessen liefert, was das Skript macht; Die author ariable ist eine Zeichenfolge oder ein Array, das den Autor des Skripts angibt. die licence Variable stellt die Lizenz bereit, mit der das Skript vertrieben wird; und die categorie Variable ist ein Array, das die Nmap-Kategorien definiert, zu denen das Skript gehört.

Beschreibungen

description = [[
This is the description for this NSE script.
]]
author = "John Wick"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"safe", "discovery"}

Trigger- und Aktionsfunktionen

Wie bereits erwähnt, sucht die Nmap Scripting Engine nach fünf Funktionen im Hauptteil eines NSE-Skripts. In der oben bereitgestellten Vorlage habe ich die Funktionen hostrule, portrule und action verwendet, um das Verhalten des NSE-Skripts zu definieren. Alle Triggerfunktionen, prerule, hostrule, portrule oder postrule , geben einen booleschen Wert zurück – wenn einer der von diesen Funktionen zurückgegebenen Werte falsch ist, wird der in der acion Funktion definierte Code abhängig von der Phase des Scans nicht ausgeführt.

Hello World

Ein einfaches Hello World Skript

description = [[
Simple Hello World Script.
]]
---
-- @output
-- Hello World
author = "Thomas Will"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"nothing"}
function hostrule()
   return true
end
function portrule()
   return true
end
function action(host, port)
    return("Hello World")
end

Ausgabe

  • nmap -sn --script helloworld.nse 192.168.34.1
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-26 12:20 CET
Nmap scan report for 192.168.34.1
Host is up (0.00036s latency).
Host script results:
|_helloworld: Hello World
Nmap done: 1 IP address (1 host up) scanned in 0.26 secon

Ein Beispiel-NSE-Skript

Das folgende NSE-Skript ist ein einfaches Skript, das prüft, ob die Ziel-IP-Adresse privat ist, prüft, ob die Ports 80/tcp oder 443/tcp geöffnet sind oder ob ein Port einen Dienst ausführt, der über HTTP oder HTTPS läuft – sofern die Bedingungen erfüllt sind true , druckt der Code in der Aktionsfunktion den vom Server zurückgegebenen HTTP-Server-Header. **HINWEIS**: Ich habe keine Kommentare eingefügt, da dieses Skript zu Demonstrationszwecken dient, Ihre Nicht-Demo-Skripte sollten jedoch Kommentare enthalten!

---
-- @usage
--
-- @output
--
-- @args
--
---

local shortPort = require "shortport"
local ipOps = require "ipOps"
local http = require "http"
local stdNse = require "stdnse"
local b64 = require "base64"

description = [[
An example NSE script that simply makes an HTTP request to
any HTTP(S) ports it finds while echoing the request status line
to stdout
]]

author = {"Alexis Rodriguez"}
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {
  "safe"
}

function hostrule(host)
  -- checks if IP address is local, if not,
  -- script won't run
  return ipOps.isPrivate(host)
end

function portrule()
  -- returns a function that matches on ports, services, protocol, and state
  return shortPort.port_or_service({80, 443}, {"http", "https"}, "tcp", "open")
end

function action(host, port)
  -- debug logs
  stdNse.debug(1, "IP::%s", host.ip)
  stdNse.debug(1, "PORT::%s", port.number)

  opts = {}
  local resp = http.get(host, port, "/", opts)

  return stdNse.format_output(
    true, string.format("Server Header ==> %s", resp.header["server"])
  )
end

http-server-header.nse

Das Skript laufen lassen

Sehen Sie sich den Quellcode auf meinem GitHub an. Speichern Sie das Skript als http-server-header.nse und führen Sie das Skript mit dem folgenden Befehl aus:

  • nmap -Pn --script ./http-server-header.nse -d -p 80 scanme.nmap.org
nmap -Pn --script ./http-server-header.nse -d -p 80 scanme.nmap.org
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-26 10:59 CET
--------------- Timing report ---------------
  hostgroups: min 1, max 100000
  rtt-timeouts: init 1000, min 100, max 10000
  max-scan-delay: TCP 1000, UDP 1000, SCTP 1000
  parallelism: min 0, max 0
  max-retries: 10, host-timeout: 0
  min-rate: 0, max-rate: 0
---------------------------------------------
NSE: Using Lua 5.3.
NSE: Arguments from CLI:
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 10:59
Completed NSE at 10:59, 0.00s elapsed
mass_rdns: Using DNS server 127.0.0.53
Initiating Parallel DNS resolution of 1 host. at 10:59
mass_rdns: 0.15s 0/1 [#: 1, OK: 0, NX: 0, DR: 0, SF: 0, TR: 1]
Completed Parallel DNS resolution of 1 host. at 11:00, 0.15s elapsed
DNS resolution of 1 IPs took 0.15s. Mode: Async [#: 1, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 11:00
Scanning scanme.nmap.org (45.33.32.156) [1 port]
Discovered open port 80/tcp on 45.33.32.156
Completed Connect Scan at 11:00, 0.18s elapsed (1 total ports)
Overall sending rates: 5.56 packets / s.
NSE: Script scanning 45.33.32.156.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 11:00
NSE: Starting http-server-header against scanme.nmap.org (45.33.32.156:80).
NSE: Finished http-server-header against scanme.nmap.org (45.33.32.156:80).
Completed NSE at 11:00, 0.72s elapsed
Nmap scan report for scanme.nmap.org (45.33.32.156)
Host is up, received user-set (0.18s latency).
Other addresses for scanme.nmap.org (not scanned): 2600:3c01::f03c:91ff:fe18:bb2f
Scanned at 2023-02-26 11:00:00 CET for 0s

PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack
|_http-server-header: Apache/2.4.7 (Ubuntu)
Final times for host: srtt: 179510 rttvar: 179510  to: 897550

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 11:00
Completed NSE at 11:00, 0.00s elapsed
Read from /usr/bin/../share/nmap: nmap-services.
Nmap done: 1 IP address (1 host up) scanned in 1.40 seconds



Aus dieser Ausgabe können wir sehen, dass Nmap das Skript erfolgreich geladen und ausgeführt hat und den Server-Header des HTTP-Servers wie erwartet anzeigt.

EOF

Wenn Sie diesen Artikel gerne gelesen haben, folgen Sie mir bitte auf Medium für weitere Artikel zu Cybersicherheit/Technologie und auf GitHub für weitere Programmierprojekte zur Cybersicherheit. Vielen Dank für Ihre Zeit!

Quelle

Nmap eigenes Script Beispiele

Echt Koelnisch Wasser

Skript

  • vi echtkoelnisch.nse
description = [[
Prüft, ob Port 4711 offen ist, und gibt eine Nachricht aus:
"Dies riecht nach Echt Kölnisch Wasser".
]]

author = "Thomas"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery"}

portrule = function(host, port)
  return port.number == 4711 and port.protocol == "tcp"
end

action = function(host, port)
  if port.state == "open" then
    return "Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!"
  end
end

Aufruf

  • nmap --script ./echtkoelnisch.nse -p 4711 10.0.10.104
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:14 CEST
Nmap scan report for opfer.secure.local (10.0.10.104)
Host is up (0.00093s latency).

PORT     STATE SERVICE
4711/tcp open  trinity-dist
|_echtkoelnisch: Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!
MAC Address: 08:00:27:70:6B:BA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds

Checkmk Agent unverschlüsselt

Skript

  • vi checkmk-plain.nse
description = [[
Checks if an unencrypted Checkmk Agent is responding on port 6556.
If the header <<<check_mk>>> is found, it is considered a potential information disclosure vulnerability.
]]

author = "Thomas"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "vuln"}

portrule = function(host, port)
  return port.number == 6556 and port.protocol == "tcp"
end

action = function(host, port)
  local socket = nmap.new_socket()
  socket:set_timeout(3000)
  local status, err = socket:connect(host.ip, port.number)
  if not status then
    return "Connection failed: " .. err
  end

  local data
  status, data = socket:receive_lines(1)
  socket:close()

  if status and data and data:find("<<<check_mk>>>") then
    return "Unencrypted Checkmk Agent detected - potential information disclosure!"
  end
end

Aufruf

  • nmap -sV --script ./checkmk-plain.nse -p 6556 10.0.10.104
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:26 CEST
Nmap scan report for userver.secure.local (10.0.10.104)
Host is up (0.0014s latency).

PORT     STATE SERVICE  VERSION
6556/tcp open  check_mk check_mk extension for Nagios 2.0.0p38
|_checkmk-plain: Unencrypted Checkmk Agent detected - potential information disclosure!
MAC Address: 08:00:27:23:0C:75 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds

Echt Koelnisch Wasser

Skript

  • vi echtkoelnisch.nse
description = [[
Prüft, ob Port 4711 offen ist, und gibt eine Nachricht aus:
"Dies riecht nach Echt Kölnisch Wasser".
]]

author = "Thomas"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery"}

portrule = function(host, port)
  return port.number == 4711 and port.protocol == "tcp"
end

action = function(host, port)
  if port.state == "open" then
    return "Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!"
  end
end

Aufruf

  • nmap --script ./echtkoelnisch.nse -p 4711 10.0.10.104
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:14 CEST
Nmap scan report for opfer.secure.local (10.0.10.104)
Host is up (0.00093s latency).

PORT     STATE SERVICE
4711/tcp open  trinity-dist
|_echtkoelnisch: Port 4711 offen. Dies riecht nach Echt Koelnisch Wasser!
MAC Address: 08:00:27:70:6B:BA (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds

Checkmk Agent unverschlüsselt

Skript

  • vi checkmk-plain.nse
description = [[
Checks if an unencrypted Checkmk Agent is responding on port 6556.
If the header <<<check_mk>>> is found, it is considered a potential information disclosure vulnerability.
]]

author = "Thomas"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "vuln"}

portrule = function(host, port)
  return port.number == 6556 and port.protocol == "tcp"
end

action = function(host, port)
  local socket = nmap.new_socket()
  socket:set_timeout(3000)
  local status, err = socket:connect(host.ip, port.number)
  if not status then
    return "Connection failed: " .. err
  end

  local data
  status, data = socket:receive_lines(1)
  socket:close()

  if status and data and data:find("<<<check_mk>>>") then
    return "Unencrypted Checkmk Agent detected - potential information disclosure!"
  end
end

Aufruf

  • nmap -sV --script ./checkmk-plain.nse -p 6556 10.0.10.104
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 14:26 CEST
Nmap scan report for userver.secure.local (10.0.10.104)
Host is up (0.0014s latency).

PORT     STATE SERVICE  VERSION
6556/tcp open  check_mk check_mk extension for Nagios 2.0.0p38
|_checkmk-plain: Unencrypted Checkmk Agent detected - potential information disclosure!
MAC Address: 08:00:27:23:0C:75 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 0.51 seconds