Git Product home page Git Product logo

nmap's Introduction

nmap

PkgGoDev github.com/Ullaakut/nmap/v3 Coverage Status

This library aims at providing idiomatic nmap bindings for go developers, in order to make it easier to write security audit tools using golang.

What is nmap

Nmap (Network Mapper) is a free and open-source network scanner created by Gordon Lyon. Nmap is used to discover hosts and services on a computer network by sending packets and analyzing the responses.

Nmap provides a number of features for probing computer networks, including host discovery and service and operating system detection. These features are extensible by scripts that provide more advanced service detection, vulnerability detection, and other features. Nmap can adapt to network conditions including latency and congestion during a scan.

Why use go for penetration testing

Most pentest tools are currently written using Python and not Go, because it is easy to quickly write scripts, lots of libraries are available, and it's a simple language to use. However, for writing robust and reliable applications, Go is the better tool. It is statically compiled, has a static type system, much better performance, it is also a very simple language to use and goroutines are awesome... But I might be slighly biased, so feel free to disagree.

Supported features

  • All of nmap's native options.
  • Additional idiomatic go filters for filtering hosts and ports.
  • Helpful enums for nmap commands. (time templates, os families, port states, etc.)
  • Complete documentation of each option, mostly insipred from nmap's documentation.
  • Run a nmap scan asynchronously.
  • Scan progress can be piped through a channel.
  • Write the nmap output to a given file while also parsing it to the struct.
  • Stream the nmap output to an io.Writer interface while also parsing it to the struct.
  • Functionality to show local interfaces and routes.

Simple example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/Ullaakut/nmap/v3"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
	defer cancel()

	// Equivalent to `/usr/local/bin/nmap -p 80,443,843 google.com facebook.com youtube.com`,
	// with a 5-minute timeout.
	scanner, err := nmap.NewScanner(
		ctx,
		nmap.WithTargets("google.com", "facebook.com", "youtube.com"),
		nmap.WithPorts("80,443,843"),
	)
	if err != nil {
		log.Fatalf("unable to create nmap scanner: %v", err)
	}

	result, warnings, err := scanner.Run()
	if len(*warnings) > 0 {
		log.Printf("run finished with warnings: %s\n", *warnings) // Warnings are non-critical errors from nmap.
	}
	if err != nil {
		log.Fatalf("unable to run nmap scan: %v", err)
	}

	// Use the results to print an example output
	for _, host := range result.Hosts {
		if len(host.Ports) == 0 || len(host.Addresses) == 0 {
			continue
		}

		fmt.Printf("Host %q:\n", host.Addresses[0])

		for _, port := range host.Ports {
			fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name)
		}
	}

	fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed)
}

The program above outputs:

Host "172.217.16.46":
    Port 80/tcp open http
    Port 443/tcp open https
    Port 843/tcp filtered unknown
Host "31.13.81.36":
    Port 80/tcp open http
    Port 443/tcp open https
    Port 843/tcp open unknown
Host "216.58.215.110":
    Port 80/tcp open http
    Port 443/tcp open https
    Port 843/tcp filtered unknown
Nmap done: 3 hosts up scanned in 1.29 seconds

Advanced example

Cameradar already uses this library at its core to communicate with nmap, discover RTSP streams and access them remotely.

More examples:

External resources

nmap's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmap's Issues

Write complex examples of concrete use-cases

  • Basic network discovery example
  • Spoof & decoy
  • Filters example (blocked by #1)
  • OS detection example
  • Service detection example
  • Proxy example
  • Count hosts on network by OS

Real app example

  • Update cameradar to use this library and showcase it as an example of use

Review Async implementation vs Channels Implementation.

Review current Bufio Async implementation vs Async channel implementation.

The below is fully working AsyncRun with Channels

// RunAsync runs nmap asynchronously and returns error.
func (s *Scanner) RunAsync() (<-chan []byte, <-chan []byte, error) {
	stdoutChannel := make(chan []byte)
	stderrChannel := make(chan []byte)

	// Enable XML output.
	s.args = append(s.args, "-oX")

	// Get XML output in stdout instead of writing it in a file.
	s.args = append(s.args, "-")
	s.cmd = exec.Command(s.binaryPath, s.args...)

	// Get CMD Stderr Pipe
	stderr, err := s.cmd.StderrPipe()
	if err != nil {
		return nil, nil, fmt.Errorf("unable to get error output from asynchronous nmap run: %v", err)
	}

	// Get CMD Stdout Pipe
	stdout, err := s.cmd.StdoutPipe()
	if err != nil {
		return nil, nil, fmt.Errorf("unable to get standard output from asynchronous nmap run: %v", err)
	}

	if err := s.cmd.Start(); err != nil {
		return nil, nil, fmt.Errorf("unable to execute asynchronous nmap run: %v", err)
	}

	// Stream stdout to the stdoutChannel
	go func() {
		defer close(stdoutChannel)
		for {
			buf := make([]byte, 1024)
			n, err := stdout.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Fatal(err)
				}
				if n == 0 {
					break
				}
			}
			stdoutChannel <- buf[:n]
		}
	}()

	// Stream stderr to the stderrChannel
	go func() {
		defer close(stderrChannel)
		for {
			buf := make([]byte, 2048)
			n, err := stderr.Read(buf)
			if err != nil {
				if err != io.EOF {
					log.Fatal(err)
				}
				if n == 0 {
					break
				}
			}
			stderrChannel <- buf[:n]
		}
	}()

	go func() {
		<-s.ctx.Done()
		_ = s.cmd.Process.Kill()
	}()

	return stdoutChannel, stderrChannel, nil
}

Parsing errors

My work in progress on the unit tests led me to discover a few issues with the current XML parsing:

  • Missing nmap.Run.Host.EndTime and nmap.Run.Host.StartTime values are parsed as -62135596800
  • nmap.Run.Host.OS.OSClass entries are missing

Add TravisCI

  • Run golangci-lint
  • Build
  • Run testsuite
  • Run coveralls

Showing up all hosts up in privileged mode

If we try to scan for example a /24, the nmap package will tell that every host is up, even if they not.
If this can help, I think it's because you fallback on a "up" status if you can't find any "status" tag in the XML, because nmap doesn't put any info about the host in the XML if it is down.

Detect ICMP response

Hi, is there a way of using the library to detect whether a host responds to ICMP?
At the moment I have something along the lines of:

	switch mode {
	case "tcp":
		typeScanner = []func(*nmap.Scanner){
			nmap.WithServiceInfo(),
			nmap.WithSYNScan(),
			nmap.WithOSDetection(),
			nmap.WithOSScanGuess(),
			nmap.WithOSScanLimit(),
		}
		break
	case "udp":
		typeScanner = []func(*nmap.Scanner){
			nmap.WithServiceInfo(),
			nmap.WithUDPScan(),
		}
		break
	case "icmp":
		typeScanner = []func(*nmap.Scanner){
			nmap.WithServiceInfo(),
			nmap.WithICMPEchoDiscovery(),
			nmap.WithOSDetection(),
			nmap.WithOSScanGuess(),
		}
		break
	default:
		return errors.New("unknown scan mode: " + mode)
	}

...
			nmap.WithContext(ctx),
			nmap.WithTargets(ip.String()),
			nmap.WithDisabledDNSResolution(),
			nmap.WithPrivileged(),
			nmap.WithTimingTemplate(nmap.TimingAggressive),

But not sure if ServiceInfo and OSDetection do anything at the ICMP scanning phase.

Add enum for OS families

This might be more complicated than it sounds, as I'm not sure where to get a complete list of the OS families supported by nmap, but once it's done it would make it possible to replace this code:

if strings.Contains(strings.ToLower(class.Family), "linux") {
    linux++
} else if strings.Contains(strings.ToLower(class.Family), "windows") {
    windows++
} else if strings.Contains(strings.ToLower(class.Family), "macos") {
    macOS++
}

with a cleaner (and more idiomatic) switch statement like such:

switch class.Family {
case nmap.OSFamilyLinux:
	linux++
case nmap.OSFamilyWindows:
	windows++
case nmap.OSFamilyMacOS:
	macOS++
}

Issues with count_hosts_by_os example

I'm seeing a few issues with the count_hosts_by_os example in this repository.

I get this error when I run the program without sudo. Does this example require to be ran with sudo or root?

$ ./count_hosts_by_os
2021/05/23 07:03:44 nmap scan failed: unable to parse nmap output, see warnings for details

When I run the example, the number of Linux hosts is more than the number of hosts seen on the network.

$ sudo ./count_hosts_by_os
Discovered 25 linux hosts and 0 windows hosts out of 18 total up hosts.

Broken WithResumePreviousScan function

  • I'm submitting a ...
    • bug report

  • Current behavior:
    When running s scan with WithResumePreviousScan("testfilename") function, the nmap scan won't start.
    grafik
    grafik

  • What is the output from nmap directly?
    grafik


  • What needs to be changed to work properly?
  1. Remove all arguments except --resume <filename>
    grafik

  2. Reload the current file content in front of the resuming nmap xml output...
    grafik
    ... because it will only append new xml and does not starting from beginning.
    grafik

Add idiomatic filtering

Add WithFilterHost, WithFilterPort, WithFilterService etc. methods to be used like so:

    scanner, err := nmap.New(
        nmap.WithTarget("172.17.100.0/24"),
		// Filter out hosts that do not have any open port
		nmap.WithFilterHost(func(h nmap.Host) bool {
			for _, port := range h.Ports {
				if port.Status() == nmap.Open {
					return true
				}
			}
			return false
		})
    )
    if err != nil {
        log.Fatalf("unable to create nmap scanner: %v", err)
    }

    result, err := scanner.Run()
    if err != nil {
        log.Fatalf("nmap scan failed: %v", err)
    }

Feature: vuln script output

Hi, would it be possible to use the output of the nmap scripts vuln using this library?
I don't see it appearing in the XML output.

Consider adding nmap/v2.Option

It would be a minor breaking change, but would it be worth adding something like the below type?

type Option func(*Scanner)

The use case I'm seeing is two-fold:

  • Better grouping of options on pkg.go.dev (for example, see type CallOption on grpc's Index)
  • Making it a touch easier for downstream users to maintain a set of base options.

For the latter case, I'm currently doing something like so:

type X struct {
	baseOptions []func(*nmap.Scanner)
}
func newX() X {
	return X{
		baseOptions: []func(*nmap.Scanner){
			nmap.With1(),
			nmap.With2(),
			nmap.With3(),
		},
	}
}
func doTheThing(host string) {
	s, _ := nmap.NewScanner(ne.baseOptions...)
	scanner.AddOptions(nmap.WithTargets(host))
	if isIP6(host) {
		scanner.AddOptions(nmap.WithIPv6Scanning())
	}

The key improvement to the above code would be mainly in clarity, as the type a user is writing out is a bit less abstract, and it doesn't require a later reader to go cross-reference the docs to verify its accuracy.

Thanks for the time and consideration.

Added error type and enhanced the error checking

Hi,

I further improved our error handling by

  • adding a new kind of error I ran into
  • checking for certain known errors in stderr (our slice of warnings) before trying to parse the XML output

Previously, our first check was whether we can parse the Nmap XML output. That XML is inevitably broken if Nmap terminated with an error. We always returned 'ErrParseOutput' and the details of the error could be revealed by looking at the warnings.

grafik

In the picutre above, you can see how the returned error is 'ErrParseOutput', although, the primary issue was 'malloc failed'.

Now, we can check for common/known errors before trying to parse the output XML and return with more accurate errors.

Best regards!

No output options

There does not appear to be a way to also create standard nmap output files while using this library. Is that something that could be considered for a feature or was it conscious omission?

Option to Disable Host Resolution [pebkac error please delete]

I would like to be able to pass a raw IP to be scanned, rather than a fqdn. Passing a raw IP currently returns:

Host "10.10.10.191":
        Port 21/tcp closed ftp
        Port 80/tcp open http
Nmap done: 1 hosts up scanned in 104.269997 seconds
2020/11/18 17:59:20 Warnings: 
 [Failed to resolve "". WARNING: No targets were specified, so 0 hosts scanned.]
Nmap done: 0 hosts up scanned in 0.030000 seconds

Add Verbosity and Debugging Options

  • I'm submitting a ...

    • feature request
    • bug report
    • support request
  • What is the current behavior?
    The library does not provide support for adding in verbosity and debugging levels.

  • What is the expected behavior?
    Allow WithVerbosity and WithDebugging options to be called to increase Nmap verbosity and debugging.

Level 10 Verbosity -vvvvv -ddddd
Level 8 Verbosity -vvvvv -ddd
Level 5 Verbosity -vvvvv

Level 5 Debugging -ddddd

  • What is the motivation / use case for changing the behavior?
    This allows for additional information to be accessible during AsyncRun usage.

Add RunAsync() method

Allowing the users to run nmap asnchronously makes it possible to parse the live nmap output, for example for building a UI on top, or computing a progress bar.

I'm not sure if many people have this use-case though, so I won't prioritize this for now, but I find it really cool.

  • Add a RunAsync() method with the following signature func (s *Scanner) RunAsync() (stdout chan <-[]byte, stderr chan <-[]byte, error)
    • Make this method return one channel for stdout, one for stderr, and an error if the nmap process could not be started.
    • Have goroutine to kill nmap if context is done or times out.
    • Store output in private attribute to expose a nmap.Result structure once the scan is done

Unit tests

95% coverage reached.

Left to test:

nmap.Run()

  • Case where nmap is not installed. Can be done by manipulating the $PATH during this test case.
  • Case where process can not be killed. Not sure how to test this without mocking os.Exec, and I'm not going to do that. Might just remove the error check for the cmd.Process.Kill() call since I think it's useless anyway.
  • Case where nmap's output can't be parsed. Can be done by using a custom binary path and getting the output of a different command instead.

Filters

  • FilterPort can be tested only if we have nmap results with ports to filter. Might make a fake nmap binary that just outputs the test xml scan.
  • FilterHost can be tested only if we have nmap results with ports to filter. Might make a fake nmap binary that just outputs the test xml scan.

String methods

  • I didn't test the String() methods since I think it's useless, but having 100% coverage on a library is always more reassuring, so I guess I'll do it.

XML

  • Need to write a test for the ToFile method.
  • Need to find a way to test the table marshaling with cases where e.EncodeToken() fails and e.Flush() fails, but I have no clue how to test them. The first one would require creating invalid tokens, which this function never would, and the second would require having a closed encoder, which would probably make it fail upstream.
  • Need to test the Timestamp marshaling/unmarshaling, useless but increases coverage.

Add Progress function to easily stream progress updates from AsyncRun method

  • I'm submitting a ...

    • bug report
    • feature request
    • support request
  • What is the current behavior?
    AsyncRun returns bufio reader, allowing users to manipulate the data to have it perform in several different manners. However some users might only want to use AsyncRun for being able to stream progress. It would be nice to have a Progress function that would allow streaming progress without having a bunch of code to accompany it.

  • What is the expected behavior?
    Call range Progress(content) {} and have progress updates printed to screen

  • What is the motivation / use case for changing the behavior?
    Allow an easier to use Progress implementation allowing straight forward implementation of parsing Nmap xml bytes from the stream and getting progress status.

Goroutine never finishes if process is killed

Hey there,

I stumbled upon a probable memory leak in the Run function. If the Command is killed, because the timeout is reached, the goroutine waiting for cmd.Wait() to return will never finish.
This is because the done channel is not buffered and the error is never retrieved in the select statement.

Here's an example I put together. I also found this related stackoverflow post (see comments).

I did not create a PR, because the solution is pretty straight forward - Simply make a buffered channel.

	// Make a goroutine to notify the select when the scan is done.
	done := make(chan error, 1)
	go func() {
		done <- cmd.Wait()
	}()

Have a nice day

Wrong detect if port is open/close

package main

import (
	"fmt"
	"log"

	"github.com/Ullaakut/nmap/v2"
)

func main() {
	scanner, err := nmap.NewScanner(
		nmap.WithTargets("127.0.0.1"),
		nmap.WithPorts("1", "3389", "3390", "9040", "9050"),
		nmap.WithServiceInfo(),
		nmap.WithTimingTemplate(nmap.TimingAggressive),
		nmap.WithFilterHost(func(h nmap.Host) bool {
			for idx := range h.Ports {
				if h.Ports[idx].Status() == "open" {
					return true
				}
			}
			return false
		}),
	)
	if err != nil {
		log.Fatalf("unable to create nmap scanner: %v", err)
	}

	result, _, err := scanner.Run()
	if err != nil {
		log.Fatalf("nmap scan failed: %v", err)
	}
	for _, host := range result.Hosts {
		fmt.Printf("Host %s\n", host.Addresses[0])
		for _, port := range host.Ports {
			fmt.Printf("\tPort %d open, service %s\n", port.ID, port.Service.Name)
		}
	}
}

Result

Host 127.0.0.1
        Port 1 open, service tcpmux
        Port 3389 open, service ms-wbt-server
        Port 3390 open, service dsc
        Port 9040 open, service tcpwrapped
        Port 9050 open, service tor-socks

And nmap scan

nmap -A -sV -sC -Pn -T4 -p1,3389,3390,9040,9050 127.0.0.1
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-16 16:53 MSK
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00012s latency).

PORT     STATE  SERVICE       VERSION
1/tcp    closed tcpmux
3389/tcp closed ms-wbt-server
3390/tcp closed dsc
9040/tcp open   tcpwrapped
9050/tcp open   tor-socks     Tor SOCKS proxy
| socks-auth-info: 
|   No authentication
|_  Username and password
| socks-open-proxy: 
|   status: open
|   versions: 
|_    socks4

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

Parsing Nmap output misses "osclass" data

Hi there!

First of all: awesome library, thank you very much!

It appears to me that parsing Nmap output does not read the osclass data correctly. I've seen there is a solved issue regarding the same thing ( ##7). However I still have the problem, even though I'm running on your latest version.

"osmatch" data is read correctly. "osclass" data is always empty. Looking at the original Nmap XML data, "osclass" is a child of each "osmatch". In your xml.go specification, they are on the same level.

Moving
Classes []OSClass 'xml:"osclass" json:"os_classes"'
from the "OS" struct to the "OSMatch" struct would solve the issue... if that was an acceptable solution to you

best regards!

Unresolvable hosts prevent remaining results

Hi@

when a scan finishes before timeout you firstly check if something went to stderr.

Lets assume the following:

nmap -p 80,443 asdasasdasdasasdaasdassad.com google.de

First host goes to stderr with message Failed to resolve "asdasasdasdasasdaasdassad.com". and the second one finishes just fine.

The early error exit (currently https://github.com/Ullaakut/nmap/blob/master/nmap.go#L87)
from your done channel prevents access to any other successful results if just one fails :/

Problem with proxy.golang.org

Hi,
I'm sorry for asking this!
But while we resolved that issue #65 we got a new problem with go module versions.

  • When you clean your cache with go clean -modcache
  • ... delete the go path
  • ... and then run go get github.com/Ullaakut/nmap/v2

=> The official Go Proxy does not recognize the changes.
=> You can try this by calling the function RunWithProgress in version v2.0.2.

So I'm asking you to set a new Tag (v2.0.3) so hopefully the changes will be cached by Go.

nmap command line options duplication after several repeated invocations

I use nmap library to continuosly scan network so I call Run() method repeatedly for single nmap.Scanner structure.
After several invocations Run() starts returning "nmap scan timed out" error.

Using strace utility I found following command line for nmap:
execve("/usr/bin/nmap", ["/usr/bin/nmap", "192.168.xx.xxx/29", "xxx.xxx.xxx.xx", "-p", "443", "-T4", "--script=xxxxxxxxxxx", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", "-", "-oX", ...], 0xc0003ce040 /* 6 vars */ <unfinished ...>

I think that's extra command line arguments are causing this timeout. Looking at https://github.com/Ullaakut/nmap/blob/master/nmap.go#L87 I see that every Run() invocations adds to args slice that causes timeout error after some time.

add a go.mod file and make a semver-numbered release

Would you consider adding a go.mod file (can be created with: go mod init github.com/Ullaakut/nmap and after merging, creating a release (even if v0.x.x-numbered like v0.5.0 or similar)? It would make it easier to use as dependency. Thanks.

Broken module version management

Hi, I recently had many issues with go complaining about checksum mismatches when trying to "go get" this module with version v2 or greater.

I think I found the issue:
Go got the checksum mismatch because v2.0.0 does not contain a go.mod file and then got "incompatible"
https://stackoverflow.com/questions/57355929/what-does-incompatible-in-go-mod-mean-will-it-cause-harm

So I ask you to set the tag v2.0.0 to a commit where the go.mod is correct.
You may set tag v2.0.0 to the same commit as v2.0.1.

github.com/Ullaakut/nmap/v2/pkg/osfamilies: not found

I'm creating a custom build script for Pentoo using standard Gentoo ebuild and golang-vcs-snapshot eclass.

Currently, Cameradar fails to build due to the following error:

WORK=/var/tmp/portage/net-analyzer/cameradar-5.0.1-r1/temp/go-build4077822569
src/github.com/ullaakut/cameradar/vendor/github.com/Ullaakut/nmap/xml.go:11:2: cannot find package "github.com/Ullaakut/nmap/v2/pkg/osfamilies" in any of:
        /var/tmp/portage/net-analyzer/cameradar-5.0.1-r1/work/cameradar-5.0.1/src/github.com/ullaakut/cameradar/vendor/github.com/Ullaakut/nmap/v2/pkg/osfamilies (vendor tree)
        /usr/lib/go/src/github.com/Ullaakut/nmap/v2/pkg/osfamilies (from $GOROOT)
        /var/tmp/portage/net-analyzer/cameradar-5.0.1-r1/work/cameradar-5.0.1/src/github.com/Ullaakut/nmap/v2/pkg/osfamilies (from $GOPATH)
        /usr/lib/go-gentoo/src/github.com/Ullaakut/nmap/v2/pkg/osfamilies
src/github.com/ullaakut/cameradar/cmd/cameradar/cameradar.go:10:2: cannot find package "github.com/Ullaakut/cameradar/v5" in any of:
        /var/tmp/portage/net-analyzer/cameradar-5.0.1-r1/work/cameradar-5.0.1/src/github.com/ullaakut/cameradar/vendor/github.com/Ullaakut/cameradar/v5 (vendor tree)
        /usr/lib/go/src/github.com/Ullaakut/cameradar/v5 (from $GOROOT)
        /var/tmp/portage/net-analyzer/cameradar-5.0.1-r1/work/cameradar-5.0.1/src/github.com/Ullaakut/cameradar/v5 (from $GOPATH)
        /usr/lib/go-gentoo/src/github.com/Ullaakut/cameradar/v5
 * ERROR: net-analyzer/cameradar-5.0.1-r1::pentoo failed (compile phase):

There are few references which seems broken:
https://github.com/Ullaakut/nmap/blob/master/xml.go#L11
https://github.com/Ullaakut/nmap/blob/master/go.mod#L1

can you create both directories (v2/pkg/osfamilies) or remove v2 and v5 completely?

Can't see to get the output of default script.

Hello.

nmap.WithDefaultScript()

I can get all methods from port.* etc but cant see to get the output of the Script.
example:

for _, host := range result.Hosts {
                fmt.Printf("Host %s\n", host.Addresses[0])

                for _, port := range host.Ports {
                        fmt.Printf("\tPort %d/%s %s %s %s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name, port.Service.Product, port.Service.Version, port.Service.ExtraInfo)

                        for _, script := range port.Scripts {
                                fmt.Printf("%s", script.Output)
                        }
                }
        }

trying to get the script.Output from the scripts slice.
Im sure im doing something wrong.

how i get mac address?

im a rookie
i just run ur example ,but i cant get mac address
i cant find any func get mac addr like nmap -RP
image

Error handling difficult and not reliable

Issue

It is currently difficult to check whether an Nmap scan failed, due to two reasons:

  • Error messages are spread across three locations (returned by Run(), result.NmapErrors and result.Stats.Finished.ErrorMsg)
  • Error messages might actually be warnings. Nmap can only write warnings to stderr where we undestand them as errors

Examples generated by Run():

  • "unable to parse nmap output"
  • ErrScanTimeout

Examples returned via stderr:

  • "Error resolving name" (target could not be resolved, hence not scanned)
  • "No targets were specified"

Example found in result.Stats.Finished.ErrorMsg:

  • "Error resolving name" (issue with exclude list)

Suggestion

I'm suggesting to change the signature of the Run() method to:
func (s *Scanner) Run() (*Run, []strings, []error) { }

This is a breaking change on purpose. It will prevent people from compiling their old code with the updated package. We do not want to affect their application behaviour without them noticing. Ideally, they should reconsider their error handling too.

With this suggestion we can return an intuitive set of result data: result, list of warnings and list of errors.

=> Result may exist as soon as the XML could be parsed (even if there are errors returned in parallel)
=> Warnings may be there and can be used if desired.
=> The list of errors can aggregate the error messages from our run method, stderr and a copy of those from the xml output.

Possible Implementation

  • in case of timeout, just return the timeout error and nothing else. otherwise:
  • take stderr and split it into errors and warnings to be returned subsequently
  • parse xml. if parsing failed, add this error to stderr errors and return them all together. otherwise:
  • search parsed xml for error messages and add them to the existing list of errors
  • (drop result.NmapErrors again)

Really really nice to have

I'ts tricky, but mybe we want to introdcue (more) error constants (in errors.go) for whatever we run across. So that other developers directly are aware of them and can handle them as they need.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.