Cameradar 3.0.0: Uses ullaakut/nmap, runs faster, removed legacy code (#188)
Unit tests functional and coverage back to 100% Add more routes to dictionary, add more credentials, add default port 5554, rename cameradar logs ENV variable, improve unit test readability, remove tmp file
This commit is contained in:
committed by
GitHub
parent
878ca9f032
commit
5849898283
+123
@@ -0,0 +1,123 @@
|
||||
## Golang
|
||||
|
||||
### Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
### Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
### Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
## MacOS
|
||||
|
||||
### General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
### Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
### Thumbnails
|
||||
._*
|
||||
|
||||
### Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
### Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
## IDEs
|
||||
|
||||
### VSCode
|
||||
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
### JetBrains
|
||||
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
|
||||
# options for analysis running
|
||||
run:
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
deadline: 1m
|
||||
|
||||
tests: false
|
||||
|
||||
# which dirs to skip: they won't be analyzed;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but next dirs are always skipped independently
|
||||
# from this option's value:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs:
|
||||
- pkg/osfamilies
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
ignore: fmt:.*,io/ioutil:^Read.*,os/exec:^Kill.*
|
||||
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.8
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/org/project
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
threshold: 150
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 3
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
include-go-root: false
|
||||
packages:
|
||||
- github.com/davecgh/go-spew/spew
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||
locale: US
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 120
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
unparam:
|
||||
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
|
||||
# and rta for programs with main packages. Default is cha.
|
||||
algo: cha
|
||||
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
prealloc:
|
||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||
# For most programs usage of prealloc will be a premature optimization.
|
||||
|
||||
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||
# True by default.
|
||||
simple: true
|
||||
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||
for-loops: false # Report preallocation suggestions on for loops, false by default
|
||||
gocritic:
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint` run to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
enabled-tags:
|
||||
- performance
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- megacheck
|
||||
- govet
|
||||
enable-all: false
|
||||
disable:
|
||||
- maligned
|
||||
- prealloc
|
||||
disable-all: false
|
||||
presets:
|
||||
- bugs
|
||||
- unused
|
||||
fast: false
|
||||
|
||||
|
||||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
exclude:
|
||||
- "Subprocess launching should be audited"
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
dist: trusty
|
||||
sudo: required
|
||||
language: go
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install -y nmap
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
script:
|
||||
# Run unit tests
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken=$COVERALLS_TOKEN
|
||||
# Ensure the examples compile
|
||||
- for dir in examples/*/; do go build -o $dir/bin $dir/main.go; done
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- brendan.le-glaunec@epitech.eu
|
||||
on_success: never
|
||||
on_failure: always
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Ullaakut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
# nmap
|
||||
|
||||
<p align="center">
|
||||
<img width="350" src="img/logo.png"/>
|
||||
<p>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat" />
|
||||
</a>
|
||||
<a href="https://godoc.org/github.com/Ullaakut/nmap">
|
||||
<img src="https://godoc.org/github.com/Ullaakut/cameradar?status.svg" />
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/ullaakut/nmap">
|
||||
<img src="https://goreportcard.com/badge/github.com/ullaakut/nmap">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/Ullaakut/nmap">
|
||||
<img src="https://travis-ci.org/Ullaakut/nmap.svg?branch=master">
|
||||
</a>
|
||||
<a href="https://coveralls.io/github/Ullaakut/nmap?branch=master">
|
||||
<img src="https://coveralls.io/repos/github/Ullaakut/nmap/badge.svg?branch=master">
|
||||
</a>
|
||||
<p>
|
||||
|
||||
This library aims at providing idiomatic `nmap` bindings for go developers, in order to make it easier to write security audit tools using golang.
|
||||
|
||||
<!-- It allows not only to parse the XML output of nmap, but also to get the output of nmap as it is running, through a channel. This can be useful for computing a scan's progress, or simply displaying live information to your users. -->
|
||||
|
||||
## It's currently a work in progress
|
||||
|
||||
This paragraph won't be removed until the library is ready to be used and properly documented.
|
||||
|
||||
## Supported features
|
||||
|
||||
- [x] All of `nmap`'s options as `WithXXX` methods.
|
||||
- [x] Cancellable contexts support.
|
||||
- [x] [Idiomatic go filters](examples/service_detection/main.go#L19).
|
||||
- [x] Helpful enums for most nmap commands. (time templates, os families, port states, etc.)
|
||||
- [x] Complete documentation of each option, mostly insipred from nmap's documentation.
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Examples of usage - Work in progress (4/7 examples so far)
|
||||
- [ ] Complete unit tests - Work in progress (95% coverage so far)
|
||||
- [ ] Asynchronous scan
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/Ullaakut/nmap"
|
||||
)
|
||||
|
||||
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(
|
||||
nmap.WithTargets("google.com", "facebook.com", "youtube.com"),
|
||||
nmap.WithPorts("80,443,843"),
|
||||
nmap.WithContext(ctx),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to create nmap scanner: %v", err)
|
||||
}
|
||||
|
||||
result, err := scanner.Run()
|
||||
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 %3f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed)
|
||||
}
|
||||
```
|
||||
|
||||
The program above outputs:
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package nmap
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNmapNotInstalled means that upon trying to manually locate nmap in the user's path,
|
||||
// it was not found. Either use the WithBinaryPath method to set it manually, or make sure that
|
||||
// the nmap binary is present in the user's $PATH.
|
||||
ErrNmapNotInstalled = errors.New("'nmap' binary was not found")
|
||||
|
||||
// ErrScanTimeout means that the provided context was done before the scanner finished its scan.
|
||||
ErrScanTimeout = errors.New("nmap scan timed out")
|
||||
|
||||
// ErrNoTargetsSpecified means that no targets were specified.
|
||||
ErrNoTargetsSpecified = errors.New("no targets specified")
|
||||
)
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package nmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// A scanner can be instanciated with options to set the arguments
|
||||
// that are given to nmap.
|
||||
func ExampleScanner_simple() {
|
||||
s, err := NewScanner(
|
||||
WithTargets("google.com", "facebook.com", "youtube.com"),
|
||||
WithCustomDNSServers("8.8.8.8", "8.8.4.4"),
|
||||
WithTimingTemplate(TimingFastest),
|
||||
WithTCPScanFlags(FlagACK, FlagNULL, FlagRST),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to create nmap scanner: %v", err)
|
||||
}
|
||||
|
||||
scanResult, err := s.Run()
|
||||
if err != nil {
|
||||
log.Fatalf("nmap encountered an error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
"Scan successful: %d hosts up\n",
|
||||
scanResult.Stats.Hosts.Up,
|
||||
)
|
||||
// Output: Scan successful: 3 hosts up
|
||||
}
|
||||
|
||||
// A scanner can be given custom idiomatic filters for both hosts
|
||||
// and ports.
|
||||
func ExampleScanner_filters() {
|
||||
s, err := NewScanner(
|
||||
WithTargets("google.com", "facebook.com"),
|
||||
WithPorts("843"),
|
||||
WithFilterHost(func(h Host) bool {
|
||||
// Filter out hosts with no open ports.
|
||||
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)
|
||||
}
|
||||
|
||||
scanResult, err := s.Run()
|
||||
if err != nil {
|
||||
log.Fatalf("nmap encountered an error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
"Filtered out hosts %d / Original number of hosts: %d\n",
|
||||
len(scanResult.Hosts),
|
||||
scanResult.Stats.Hosts.Total,
|
||||
)
|
||||
// Output: Filtered out hosts 1 / Original number of hosts: 2
|
||||
}
|
||||
+1216
File diff suppressed because it is too large
Load Diff
+1781
File diff suppressed because it is too large
Load Diff
+644
@@ -0,0 +1,644 @@
|
||||
package osfamilies
|
||||
|
||||
// OSFamily describes an OS Family, usually from a constructor or
|
||||
// a kernel.
|
||||
type OSFamily string
|
||||
|
||||
// OSFamily definitions.
|
||||
const (
|
||||
TwoN OSFamily = "2N"
|
||||
TwoWire OSFamily = "2Wire"
|
||||
ThreeCom OSFamily = "3Com"
|
||||
ThreeM OSFamily = "3M"
|
||||
FourG OSFamily = "4G"
|
||||
ATec OSFamily = "A-Tec"
|
||||
ADIC OSFamily = "ADIC"
|
||||
AKCP OSFamily = "AKCP"
|
||||
AMX OSFamily = "AMX"
|
||||
APC OSFamily = "APC"
|
||||
ARCA OSFamily = "ARCA"
|
||||
ATandT OSFamily = "AT&T"
|
||||
AVM OSFamily = "AVM"
|
||||
AVtech OSFamily = "AVtech"
|
||||
AXIS OSFamily = "AXIS"
|
||||
Aastra OSFamily = "Aastra"
|
||||
AcBel OSFamily = "AcBel"
|
||||
Aceex OSFamily = "Aceex"
|
||||
Acer OSFamily = "Acer"
|
||||
Acme OSFamily = "Acme"
|
||||
Acorp OSFamily = "Acorp"
|
||||
Actiontec OSFamily = "Actiontec"
|
||||
Adaptec OSFamily = "Adaptec"
|
||||
Adtran OSFamily = "Adtran"
|
||||
Adva OSFamily = "Adva"
|
||||
Advanced OSFamily = "Advanced"
|
||||
Aerohive OSFamily = "Aerohive"
|
||||
Aethra OSFamily = "Aethra"
|
||||
Agfa OSFamily = "Agfa"
|
||||
AirLive OSFamily = "AirLive"
|
||||
AirMagnet OSFamily = "AirMagnet"
|
||||
AirSpan OSFamily = "AirSpan"
|
||||
Airaya OSFamily = "Airaya"
|
||||
Airlink101 OSFamily = "Airlink101"
|
||||
Airnet OSFamily = "Airnet"
|
||||
Airvana OSFamily = "Airvana"
|
||||
Alaxala OSFamily = "Alaxala"
|
||||
Alcatel OSFamily = "Alcatel"
|
||||
AlcatelLucent OSFamily = "Alcatel-Lucent"
|
||||
Alice OSFamily = "Alice"
|
||||
AllenBradley OSFamily = "Allen-Bradley"
|
||||
Allied OSFamily = "Allied"
|
||||
Allnet OSFamily = "Allnet"
|
||||
Allworx OSFamily = "Allworx"
|
||||
Alvarion OSFamily = "Alvarion"
|
||||
Amazon OSFamily = "Amazon"
|
||||
Ambit OSFamily = "Ambit"
|
||||
Amiga OSFamily = "Amiga"
|
||||
Anue OSFamily = "Anue"
|
||||
Apple OSFamily = "Apple"
|
||||
Arcor OSFamily = "Arcor"
|
||||
Areca OSFamily = "Areca"
|
||||
Argon OSFamily = "Argon"
|
||||
Argosy OSFamily = "Argosy"
|
||||
Arris OSFamily = "Arris"
|
||||
Aruba OSFamily = "Aruba"
|
||||
Asmax OSFamily = "Asmax"
|
||||
Asus OSFamily = "Asus"
|
||||
Atari OSFamily = "Atari"
|
||||
Atcom OSFamily = "Atcom"
|
||||
AudioCodes OSFamily = "AudioCodes"
|
||||
AudioControl OSFamily = "AudioControl"
|
||||
Avaya OSFamily = "Avaya"
|
||||
Avocent OSFamily = "Avocent"
|
||||
Axcient OSFamily = "Axcient"
|
||||
AzBox OSFamily = "AzBox"
|
||||
BECK OSFamily = "BECK"
|
||||
BSD OSFamily = "BSD"
|
||||
BSDI OSFamily = "BSDI"
|
||||
BT OSFamily = "BT"
|
||||
Barracuda OSFamily = "Barracuda"
|
||||
Barrelfish OSFamily = "Barrelfish"
|
||||
Basler OSFamily = "Basler"
|
||||
Bay OSFamily = "Bay"
|
||||
BeaconMedaes OSFamily = "BeaconMedaes"
|
||||
Beat OSFamily = "Beat"
|
||||
Belkin OSFamily = "Belkin"
|
||||
Bell OSFamily = "Bell"
|
||||
Billion OSFamily = "Billion"
|
||||
BinTec OSFamily = "BinTec"
|
||||
BlackBox OSFamily = "BlackBox"
|
||||
Blackboard OSFamily = "Blackboard"
|
||||
Blue OSFamily = "Blue"
|
||||
BlueArc OSFamily = "BlueArc"
|
||||
Bluebird OSFamily = "Bluebird"
|
||||
Bomara OSFamily = "Bomara"
|
||||
Bosch OSFamily = "Bosch"
|
||||
Bose OSFamily = "Bose"
|
||||
Boundless OSFamily = "Boundless"
|
||||
Bowers OSFamily = "Bowers"
|
||||
British OSFamily = "British"
|
||||
BroadMax OSFamily = "BroadMax"
|
||||
Brocade OSFamily = "Brocade"
|
||||
Brother OSFamily = "Brother"
|
||||
Buffalo OSFamily = "Buffalo"
|
||||
Burny OSFamily = "Burny"
|
||||
Bush OSFamily = "Bush"
|
||||
CNav OSFamily = "C-Nav"
|
||||
CAEN OSFamily = "CAEN"
|
||||
CMI OSFamily = "CMI"
|
||||
Cabletron OSFamily = "Cabletron"
|
||||
Caldera OSFamily = "Caldera"
|
||||
Calix OSFamily = "Calix"
|
||||
Cameo OSFamily = "Cameo"
|
||||
Canon OSFamily = "Canon"
|
||||
Casio OSFamily = "Casio"
|
||||
Cayman OSFamily = "Cayman"
|
||||
Ceedtec OSFamily = "Ceedtec"
|
||||
Check OSFamily = "Check"
|
||||
Chip OSFamily = "Chip"
|
||||
CipherLab OSFamily = "CipherLab"
|
||||
Cisco OSFamily = "Cisco"
|
||||
Citrix OSFamily = "Citrix"
|
||||
CoRAID OSFamily = "CoRAID"
|
||||
Cobalt OSFamily = "Cobalt"
|
||||
Cognex OSFamily = "Cognex"
|
||||
Comau OSFamily = "Comau"
|
||||
Compal OSFamily = "Compal"
|
||||
Compaq OSFamily = "Compaq"
|
||||
Comtrend OSFamily = "Comtrend"
|
||||
Conceptronic OSFamily = "Conceptronic"
|
||||
Control4 OSFamily = "Control4"
|
||||
Coyote OSFamily = "Coyote"
|
||||
Cray OSFamily = "Cray"
|
||||
Crestron OSFamily = "Crestron"
|
||||
CyanogenMod OSFamily = "CyanogenMod"
|
||||
Cyberoam OSFamily = "Cyberoam"
|
||||
Cymphonix OSFamily = "Cymphonix"
|
||||
DLink OSFamily = "D-Link"
|
||||
DEC OSFamily = "DEC"
|
||||
DMP OSFamily = "DMP"
|
||||
DTE OSFamily = "DTE"
|
||||
DVTel OSFamily = "DVTel"
|
||||
DYMO OSFamily = "DYMO"
|
||||
Data OSFamily = "Data"
|
||||
Datalogic OSFamily = "Datalogic"
|
||||
Daysequerra OSFamily = "Daysequerra"
|
||||
Decru OSFamily = "Decru"
|
||||
Dedicated OSFamily = "Dedicated"
|
||||
Dell OSFamily = "Dell"
|
||||
Denon OSFamily = "Denon"
|
||||
Denver OSFamily = "Denver"
|
||||
Develop OSFamily = "Develop"
|
||||
Dick OSFamily = "Dick"
|
||||
Digi OSFamily = "Digi"
|
||||
Digital OSFamily = "Digital"
|
||||
Digitus OSFamily = "Digitus"
|
||||
Digium OSFamily = "Digium"
|
||||
DirecTV OSFamily = "DirecTV"
|
||||
Dish OSFamily = "Dish"
|
||||
Dolby OSFamily = "Dolby"
|
||||
DragonFly OSFamily = "DragonFly"
|
||||
DragonWave OSFamily = "DragonWave"
|
||||
DrayTek OSFamily = "DrayTek"
|
||||
Draytek OSFamily = "Draytek"
|
||||
Drayton OSFamily = "Drayton"
|
||||
Dream OSFamily = "Dream"
|
||||
Drobo OSFamily = "Drobo"
|
||||
EMC OSFamily = "EMC"
|
||||
ESI OSFamily = "ESI"
|
||||
ETH OSFamily = "ETH"
|
||||
EasyPath OSFamily = "EasyPath"
|
||||
Eaton OSFamily = "Eaton"
|
||||
Efficient OSFamily = "Efficient"
|
||||
Eicon OSFamily = "Eicon"
|
||||
Elfiq OSFamily = "Elfiq"
|
||||
Elk OSFamily = "Elk"
|
||||
Elsag OSFamily = "Elsag"
|
||||
Ember OSFamily = "Ember"
|
||||
Emerson OSFamily = "Emerson"
|
||||
EnGenius OSFamily = "EnGenius"
|
||||
Encore OSFamily = "Encore"
|
||||
Endian OSFamily = "Endian"
|
||||
Enerdis OSFamily = "Enerdis"
|
||||
Engetron OSFamily = "Engetron"
|
||||
Enistic OSFamily = "Enistic"
|
||||
Enlogic OSFamily = "Enlogic"
|
||||
Enterasys OSFamily = "Enterasys"
|
||||
Epson OSFamily = "Epson"
|
||||
Ericsson OSFamily = "Ericsson"
|
||||
Espressif OSFamily = "Espressif"
|
||||
Essentia OSFamily = "Essentia"
|
||||
EtherWerX OSFamily = "EtherWerX"
|
||||
Exabyte OSFamily = "Exabyte"
|
||||
Excito OSFamily = "Excito"
|
||||
Express OSFamily = "Express"
|
||||
Exterity OSFamily = "Exterity"
|
||||
Extreme OSFamily = "Extreme"
|
||||
F5 OSFamily = "F5"
|
||||
FORE OSFamily = "FORE"
|
||||
Fatek OSFamily = "Fatek"
|
||||
FireBrick OSFamily = "FireBrick"
|
||||
Force10 OSFamily = "Force10"
|
||||
Fortinet OSFamily = "Fortinet"
|
||||
Foscam OSFamily = "Foscam"
|
||||
Foundry OSFamily = "Foundry"
|
||||
Free OSFamily = "Free"
|
||||
FreeBSD OSFamily = "FreeBSD"
|
||||
FreeNAS OSFamily = "FreeNAS"
|
||||
Freecom OSFamily = "Freecom"
|
||||
Fronius OSFamily = "Fronius"
|
||||
Frontier OSFamily = "Frontier"
|
||||
Fuji OSFamily = "Fuji"
|
||||
Fujian OSFamily = "Fujian"
|
||||
Fujitsu OSFamily = "Fujitsu"
|
||||
Funkwerk OSFamily = "Funkwerk"
|
||||
GNU OSFamily = "GNU"
|
||||
GalaxyMetalGear OSFamily = "GalaxyMetalGear"
|
||||
Gargoyle OSFamily = "Gargoyle"
|
||||
Garmin OSFamily = "Garmin"
|
||||
GbE2c OSFamily = "GbE2c"
|
||||
Geist OSFamily = "Geist"
|
||||
Gemtek OSFamily = "Gemtek"
|
||||
General OSFamily = "General"
|
||||
Generex OSFamily = "Generex"
|
||||
Gennet OSFamily = "Gennet"
|
||||
Genua OSFamily = "Genua"
|
||||
George OSFamily = "George"
|
||||
Geovision OSFamily = "Geovision"
|
||||
GlobespanVirata OSFamily = "GlobespanVirata"
|
||||
GoPro OSFamily = "GoPro"
|
||||
Google OSFamily = "Google"
|
||||
Grace OSFamily = "Grace"
|
||||
Grandstream OSFamily = "Grandstream"
|
||||
Green OSFamily = "Green"
|
||||
H3C OSFamily = "H3C"
|
||||
HID OSFamily = "HID"
|
||||
HP OSFamily = "HP"
|
||||
HW OSFamily = "HW"
|
||||
Haiku OSFamily = "Haiku"
|
||||
Hamlet OSFamily = "Hamlet"
|
||||
Harris OSFamily = "Harris"
|
||||
Hawking OSFamily = "Hawking"
|
||||
Hay OSFamily = "Hay"
|
||||
Head OSFamily = "Head"
|
||||
Henry OSFamily = "Henry"
|
||||
HighFlying OSFamily = "High-Flying"
|
||||
Hikvision OSFamily = "Hikvision"
|
||||
Hioki OSFamily = "Hioki"
|
||||
Hirschmann OSFamily = "Hirschmann"
|
||||
Hitron OSFamily = "Hitron"
|
||||
Hotway OSFamily = "Hotway"
|
||||
Huawei OSFamily = "Huawei"
|
||||
Hybertone OSFamily = "Hybertone"
|
||||
IBM OSFamily = "IBM"
|
||||
IEI OSFamily = "IEI"
|
||||
IGEL OSFamily = "IGEL"
|
||||
IHome OSFamily = "IHome"
|
||||
IOData OSFamily = "IO-Data"
|
||||
IOGear OSFamily = "IOGear"
|
||||
ION OSFamily = "ION"
|
||||
IPAD OSFamily = "IPAD"
|
||||
IPCop OSFamily = "IPCop"
|
||||
IPFire OSFamily = "IPFire"
|
||||
ISS OSFamily = "ISS"
|
||||
ITW OSFamily = "ITW"
|
||||
Icom OSFamily = "Icom"
|
||||
Icy OSFamily = "Icy"
|
||||
Imperva OSFamily = "Imperva"
|
||||
Infoblox OSFamily = "Infoblox"
|
||||
Infomir OSFamily = "Infomir"
|
||||
Infrant OSFamily = "Infrant"
|
||||
Inova OSFamily = "Inova"
|
||||
Instar OSFamily = "Instar"
|
||||
Intel OSFamily = "Intel"
|
||||
Interbell OSFamily = "Interbell"
|
||||
Interflex OSFamily = "Interflex"
|
||||
Intermec OSFamily = "Intermec"
|
||||
Interpeak OSFamily = "Interpeak"
|
||||
Intertex OSFamily = "Intertex"
|
||||
Intracom OSFamily = "Intracom"
|
||||
Inventel OSFamily = "Inventel"
|
||||
Iomega OSFamily = "Iomega"
|
||||
IronPort OSFamily = "IronPort"
|
||||
Isilon OSFamily = "Isilon"
|
||||
Iskratel OSFamily = "Iskratel"
|
||||
JTEKT OSFamily = "JTEKT"
|
||||
Joyent OSFamily = "Joyent"
|
||||
Juniper OSFamily = "Juniper"
|
||||
KA9Q OSFamily = "KA9Q"
|
||||
KCorp OSFamily = "KCorp"
|
||||
KWSoftware OSFamily = "KW-Software"
|
||||
KabaBenzing OSFamily = "Kaba-Benzing"
|
||||
Kaiomy OSFamily = "Kaiomy"
|
||||
Kapsch OSFamily = "Kapsch"
|
||||
Kartina OSFamily = "Kartina"
|
||||
Kemp OSFamily = "Kemp"
|
||||
Keyence OSFamily = "Keyence"
|
||||
Kodak OSFamily = "Kodak"
|
||||
Kongsberg OSFamily = "Kongsberg"
|
||||
Konica OSFamily = "Konica"
|
||||
Koukaam OSFamily = "Koukaam"
|
||||
Kronos OSFamily = "Kronos"
|
||||
Kyocera OSFamily = "Kyocera"
|
||||
LG OSFamily = "LG"
|
||||
LaCie OSFamily = "LaCie"
|
||||
LaCrosse OSFamily = "LaCrosse"
|
||||
LaSAT OSFamily = "LaSAT"
|
||||
Lancom OSFamily = "Lancom"
|
||||
Lanier OSFamily = "Lanier"
|
||||
Lantronix OSFamily = "Lantronix"
|
||||
Larus OSFamily = "Larus"
|
||||
Leica OSFamily = "Leica"
|
||||
Lenel OSFamily = "Lenel"
|
||||
Leolink OSFamily = "Leolink"
|
||||
LevelOne OSFamily = "LevelOne"
|
||||
Lexmark OSFamily = "Lexmark"
|
||||
Liebert OSFamily = "Liebert"
|
||||
LifeSize OSFamily = "LifeSize"
|
||||
Linksys OSFamily = "Linksys"
|
||||
Linux OSFamily = "Linux"
|
||||
LogiLink OSFamily = "LogiLink"
|
||||
Logitech OSFamily = "Logitech"
|
||||
Lorex OSFamily = "Lorex"
|
||||
Lucent OSFamily = "Lucent"
|
||||
Luminary OSFamily = "Luminary"
|
||||
Luxul OSFamily = "Luxul"
|
||||
Lyngsoe OSFamily = "Lyngsoe"
|
||||
MGE OSFamily = "MGE"
|
||||
MOXA OSFamily = "MOXA"
|
||||
MPI OSFamily = "MPI"
|
||||
Macsense OSFamily = "Macsense"
|
||||
Maipu OSFamily = "Maipu"
|
||||
Mapower OSFamily = "Mapower"
|
||||
Marantz OSFamily = "Marantz"
|
||||
McAfee OSFamily = "McAfee"
|
||||
Meinberg OSFamily = "Meinberg"
|
||||
Meru OSFamily = "Meru"
|
||||
Metrix OSFamily = "Metrix"
|
||||
MicroNet OSFamily = "MicroNet"
|
||||
Microsoft OSFamily = "Microsoft"
|
||||
Microware OSFamily = "Microware"
|
||||
MikroTik OSFamily = "MikroTik"
|
||||
Milight OSFamily = "Milight"
|
||||
Minix OSFamily = "Minix"
|
||||
Minolta OSFamily = "Minolta"
|
||||
Mirapoint OSFamily = "Mirapoint"
|
||||
Mitel OSFamily = "Mitel"
|
||||
Mitrastar OSFamily = "Mitrastar"
|
||||
Mitsubishi OSFamily = "Mitsubishi"
|
||||
Modtronix OSFamily = "Modtronix"
|
||||
Motorola OSFamily = "Motorola"
|
||||
MusicianLink OSFamily = "MusicianLink"
|
||||
NCR OSFamily = "NCR"
|
||||
NEC OSFamily = "NEC"
|
||||
NOXON OSFamily = "NOXON"
|
||||
NRG OSFamily = "NRG"
|
||||
NSFOCUS OSFamily = "NSFOCUS"
|
||||
NTI OSFamily = "NTI"
|
||||
NTT OSFamily = "NTT"
|
||||
Nashuatec OSFamily = "Nashuatec"
|
||||
National OSFamily = "National"
|
||||
NeXT OSFamily = "NeXT"
|
||||
Neopost OSFamily = "Neopost"
|
||||
Ness OSFamily = "Ness"
|
||||
Nest OSFamily = "Nest"
|
||||
NetApp OSFamily = "NetApp"
|
||||
NetBSD OSFamily = "NetBSD"
|
||||
NetBurner OSFamily = "NetBurner"
|
||||
NetOptics OSFamily = "NetOptics"
|
||||
Netasq OSFamily = "Netasq"
|
||||
Netcomm OSFamily = "Netcomm"
|
||||
Netgear OSFamily = "Netgear"
|
||||
Netgem OSFamily = "Netgem"
|
||||
Netopia OSFamily = "Netopia"
|
||||
Network OSFamily = "Network"
|
||||
NetworkAlchemy OSFamily = "NetworkAlchemy"
|
||||
NetworksAOK OSFamily = "NetworksAOK"
|
||||
Neuf OSFamily = "Neuf"
|
||||
Newave OSFamily = "Newave"
|
||||
NexStor OSFamily = "NexStor"
|
||||
Nexenta OSFamily = "Nexenta"
|
||||
Nexsan OSFamily = "Nexsan"
|
||||
Nibe OSFamily = "Nibe"
|
||||
Nintendo OSFamily = "Nintendo"
|
||||
NodeMCU OSFamily = "NodeMCU"
|
||||
Nokia OSFamily = "Nokia"
|
||||
Nomadix OSFamily = "Nomadix"
|
||||
Nortel OSFamily = "Nortel"
|
||||
Novatel OSFamily = "Novatel"
|
||||
Novell OSFamily = "Novell"
|
||||
NutOS OSFamily = "Nut/OS"
|
||||
OSRAM OSFamily = "OSRAM"
|
||||
Obihai OSFamily = "Obihai"
|
||||
Ocean OSFamily = "Ocean"
|
||||
Oki OSFamily = "Oki"
|
||||
Olivetti OSFamily = "Olivetti"
|
||||
Olympus OSFamily = "Olympus"
|
||||
Omron OSFamily = "Omron"
|
||||
On OSFamily = "On"
|
||||
OnStor OSFamily = "OnStor"
|
||||
Onboard OSFamily = "Onboard"
|
||||
OneAccess OSFamily = "OneAccess"
|
||||
OpenBSD OSFamily = "OpenBSD"
|
||||
OpenBox OSFamily = "OpenBox"
|
||||
Opto OSFamily = "Opto"
|
||||
Oracle OSFamily = "Oracle"
|
||||
Orange OSFamily = "Orange"
|
||||
Osmosys OSFamily = "Osmosys"
|
||||
Ouya OSFamily = "Ouya"
|
||||
PCBSD OSFamily = "PC-BSD"
|
||||
PCMeasure OSFamily = "PCMeasure"
|
||||
PORTech OSFamily = "PORTech"
|
||||
Packard OSFamily = "Packard"
|
||||
Packet8 OSFamily = "Packet8"
|
||||
PacketFront OSFamily = "PacketFront"
|
||||
Packeteer OSFamily = "Packeteer"
|
||||
Palmmicro OSFamily = "Palmmicro"
|
||||
Palo OSFamily = "Palo"
|
||||
Panasas OSFamily = "Panasas"
|
||||
Panasonic OSFamily = "Panasonic"
|
||||
Papouch OSFamily = "Papouch"
|
||||
Patton OSFamily = "Patton"
|
||||
Peplink OSFamily = "Peplink"
|
||||
Perfectone OSFamily = "Perfectone"
|
||||
Perle OSFamily = "Perle"
|
||||
Phar OSFamily = "Phar"
|
||||
PheeNet OSFamily = "PheeNet"
|
||||
Philips OSFamily = "Philips"
|
||||
Phoenix OSFamily = "Phoenix"
|
||||
Pingtel OSFamily = "Pingtel"
|
||||
Pioneer OSFamily = "Pioneer"
|
||||
Pirelli OSFamily = "Pirelli"
|
||||
Planet OSFamily = "Planet"
|
||||
Polycom OSFamily = "Polycom"
|
||||
Precise OSFamily = "Precise"
|
||||
Printronix OSFamily = "Printronix"
|
||||
Priva OSFamily = "Priva"
|
||||
Promise OSFamily = "Promise"
|
||||
Proxim OSFamily = "Proxim"
|
||||
QEMU OSFamily = "QEMU"
|
||||
QNAP OSFamily = "QNAP"
|
||||
QNX OSFamily = "QNX"
|
||||
QTech OSFamily = "QTech"
|
||||
Qualisys OSFamily = "Qualisys"
|
||||
Quantum OSFamily = "Quantum"
|
||||
Quarterdeck OSFamily = "Quarterdeck"
|
||||
RAD OSFamily = "RAD"
|
||||
RCA OSFamily = "RCA"
|
||||
RF OSFamily = "RF"
|
||||
RFSpace OSFamily = "RF-Space"
|
||||
RGB OSFamily = "RGB"
|
||||
RIM OSFamily = "RIM"
|
||||
RISCOS OSFamily = "RISCOS"
|
||||
RISE OSFamily = "RISE"
|
||||
RSA OSFamily = "RSA"
|
||||
Rabbit OSFamily = "Rabbit"
|
||||
Radware OSFamily = "Radware"
|
||||
Raritan OSFamily = "Raritan"
|
||||
ReactOS OSFamily = "ReactOS"
|
||||
RedM OSFamily = "Red-M"
|
||||
Redback OSFamily = "Redback"
|
||||
Reliable OSFamily = "Reliable"
|
||||
Repotech OSFamily = "Repotech"
|
||||
Revo OSFamily = "Revo"
|
||||
Ricoh OSFamily = "Ricoh"
|
||||
Rigol OSFamily = "Rigol"
|
||||
Rio OSFamily = "Rio"
|
||||
Riverbed OSFamily = "Riverbed"
|
||||
Roberts OSFamily = "Roberts"
|
||||
Rockwell OSFamily = "Rockwell"
|
||||
Roku OSFamily = "Roku"
|
||||
Ruckus OSFamily = "Ruckus"
|
||||
RuggedCom OSFamily = "RuggedCom"
|
||||
Ruijie OSFamily = "Ruijie"
|
||||
SCO OSFamily = "SCO"
|
||||
SEH OSFamily = "SEH"
|
||||
SGI OSFamily = "SGI"
|
||||
SMA OSFamily = "SMA"
|
||||
SMC OSFamily = "SMC"
|
||||
SNR OSFamily = "SNR"
|
||||
Sagem OSFamily = "Sagem"
|
||||
Sagemcom OSFamily = "Sagemcom"
|
||||
Samsung OSFamily = "Samsung"
|
||||
Sandstrom OSFamily = "Sandstrom"
|
||||
Sanyo OSFamily = "Sanyo"
|
||||
Sapling OSFamily = "Sapling"
|
||||
Satel OSFamily = "Satel"
|
||||
Savin OSFamily = "Savin"
|
||||
Schneider OSFamily = "Schneider"
|
||||
Schrack OSFamily = "Schrack"
|
||||
Schweitzer OSFamily = "Schweitzer"
|
||||
Scientific OSFamily = "Scientific"
|
||||
Seagate OSFamily = "Seagate"
|
||||
Secure OSFamily = "Secure"
|
||||
Seiko OSFamily = "Seiko"
|
||||
Senao OSFamily = "Senao"
|
||||
Sensatronics OSFamily = "Sensatronics"
|
||||
Sequent OSFamily = "Sequent"
|
||||
Sharp OSFamily = "Sharp"
|
||||
Shenzhen OSFamily = "Shenzhen"
|
||||
ShoreTel OSFamily = "ShoreTel"
|
||||
Siemens OSFamily = "Siemens"
|
||||
Silicondust OSFamily = "Silicondust"
|
||||
Sinus OSFamily = "Sinus"
|
||||
Sipura OSFamily = "Sipura"
|
||||
Sitecom OSFamily = "Sitecom"
|
||||
Sling OSFamily = "Sling"
|
||||
Slingbox OSFamily = "Slingbox"
|
||||
Smart OSFamily = "Smart"
|
||||
Smartlink OSFamily = "Smartlink"
|
||||
Snom OSFamily = "Snom"
|
||||
Solwise OSFamily = "Solwise"
|
||||
SonicWALL OSFamily = "SonicWALL"
|
||||
Sonos OSFamily = "Sonos"
|
||||
Sonus OSFamily = "Sonus"
|
||||
Sony OSFamily = "Sony"
|
||||
Source OSFamily = "Source"
|
||||
Specialix OSFamily = "Specialix"
|
||||
Sphairon OSFamily = "Sphairon"
|
||||
Star OSFamily = "Star"
|
||||
Starbridge OSFamily = "Starbridge"
|
||||
Stonewater OSFamily = "Stonewater"
|
||||
StorageTek OSFamily = "StorageTek"
|
||||
Stratus OSFamily = "Stratus"
|
||||
Suga OSFamily = "Suga"
|
||||
Sun OSFamily = "Sun"
|
||||
SunPower OSFamily = "SunPower"
|
||||
Supermicro OSFamily = "Supermicro"
|
||||
Syllable OSFamily = "Syllable"
|
||||
Symantec OSFamily = "Symantec"
|
||||
Symbian OSFamily = "Symbian"
|
||||
Symbol OSFamily = "Symbol"
|
||||
Symmetricon OSFamily = "Symmetricon"
|
||||
Synology OSFamily = "Synology"
|
||||
THome OSFamily = "T-Home"
|
||||
TMarc OSFamily = "T-Marc"
|
||||
TPLINK OSFamily = "TP-LINK"
|
||||
TPLink OSFamily = "TP-Link"
|
||||
TRENDnet OSFamily = "TRENDnet"
|
||||
Tadiran OSFamily = "Tadiran"
|
||||
Tahoe OSFamily = "Tahoe"
|
||||
Tandberg OSFamily = "Tandberg"
|
||||
Tandem OSFamily = "Tandem"
|
||||
TechniSat OSFamily = "TechniSat"
|
||||
Tektronix OSFamily = "Tektronix"
|
||||
Telco OSFamily = "Telco"
|
||||
Teldat OSFamily = "Teldat"
|
||||
Telekom OSFamily = "Telekom"
|
||||
Telewell OSFamily = "Telewell"
|
||||
Telex OSFamily = "Telex"
|
||||
Telsey OSFamily = "Telsey"
|
||||
Teltronics OSFamily = "Teltronics"
|
||||
TenAsys OSFamily = "TenAsys"
|
||||
Tenda OSFamily = "Tenda"
|
||||
Teradici OSFamily = "Teradici"
|
||||
Terratec OSFamily = "Terratec"
|
||||
Texas OSFamily = "Texas"
|
||||
Thales OSFamily = "Thales"
|
||||
Thecus OSFamily = "Thecus"
|
||||
Thomson OSFamily = "Thomson"
|
||||
Tiandy OSFamily = "Tiandy"
|
||||
Tibbo OSFamily = "Tibbo"
|
||||
Tigo OSFamily = "Tigo"
|
||||
Tintri OSFamily = "Tintri"
|
||||
TippingPoint OSFamily = "TippingPoint"
|
||||
Tizen OSFamily = "Tizen"
|
||||
Topfield OSFamily = "Topfield"
|
||||
Toptech OSFamily = "Toptech"
|
||||
Toshiba OSFamily = "Toshiba"
|
||||
Trane OSFamily = "Trane"
|
||||
TransAct OSFamily = "TransAct"
|
||||
Tranzeo OSFamily = "Tranzeo"
|
||||
Trapeze OSFamily = "Trapeze"
|
||||
Tripp OSFamily = "Tripp"
|
||||
Tut OSFamily = "Tut"
|
||||
Tyco OSFamily = "Tyco"
|
||||
USRobotics OSFamily = "USRobotics"
|
||||
UTStarcom OSFamily = "UTStarcom"
|
||||
Ubee OSFamily = "Ubee"
|
||||
Ubicom OSFamily = "Ubicom"
|
||||
Ubiquiti OSFamily = "Ubiquiti"
|
||||
Universal OSFamily = "Universal"
|
||||
VBrick OSFamily = "VBrick"
|
||||
VIPA OSFamily = "VIPA"
|
||||
VMware OSFamily = "VMware"
|
||||
VTrak OSFamily = "VTrak"
|
||||
Vantage OSFamily = "Vantage"
|
||||
Vegastream OSFamily = "Vegastream"
|
||||
Viasat OSFamily = "Viasat"
|
||||
Vilar OSFamily = "Vilar"
|
||||
Virdi OSFamily = "Virdi"
|
||||
Visual OSFamily = "Visual"
|
||||
Vocality OSFamily = "Vocality"
|
||||
Vodafone OSFamily = "Vodafone"
|
||||
Vodavi OSFamily = "Vodavi"
|
||||
Vonage OSFamily = "Vonage"
|
||||
WandT OSFamily = "W&T"
|
||||
WAGO OSFamily = "WAGO"
|
||||
WIZnet OSFamily = "WIZnet"
|
||||
Wago OSFamily = "Wago"
|
||||
Walker OSFamily = "Walker"
|
||||
WatchGuard OSFamily = "WatchGuard"
|
||||
WebSense OSFamily = "WebSense"
|
||||
Welltech OSFamily = "Welltech"
|
||||
Westell OSFamily = "Westell"
|
||||
Westermo OSFamily = "Westermo"
|
||||
Western OSFamily = "Western"
|
||||
Wind OSFamily = "Wind"
|
||||
Windows OSFamily = "Windows"
|
||||
World OSFamily = "World"
|
||||
WowWee OSFamily = "WowWee"
|
||||
Wyse OSFamily = "Wyse"
|
||||
XAVi OSFamily = "XAVi"
|
||||
XEUdotCom OSFamily = "XEU.com"
|
||||
XMOS OSFamily = "XMOS"
|
||||
Xerox OSFamily = "Xerox"
|
||||
Xiaomi OSFamily = "Xiaomi"
|
||||
Xirrus OSFamily = "Xirrus"
|
||||
Xylan OSFamily = "Xylan"
|
||||
Xyplex OSFamily = "Xyplex"
|
||||
Yamaha OSFamily = "Yamaha"
|
||||
Yealink OSFamily = "Yealink"
|
||||
ZKTeco OSFamily = "ZKTeco"
|
||||
ZTE OSFamily = "ZTE"
|
||||
Zebra OSFamily = "Zebra"
|
||||
Zelax OSFamily = "Zelax"
|
||||
Zerto OSFamily = "Zerto"
|
||||
Zhone OSFamily = "Zhone"
|
||||
Zipato OSFamily = "Zipato"
|
||||
ZoneAlarm OSFamily = "ZoneAlarm"
|
||||
Zoom OSFamily = "Zoom"
|
||||
ZyXEL OSFamily = "ZyXEL"
|
||||
Zyfer OSFamily = "Zyfer"
|
||||
cab OSFamily = "cab"
|
||||
eCosCentric OSFamily = "eCosCentric"
|
||||
iDirect OSFamily = "iDirect"
|
||||
iPXE OSFamily = "iPXE"
|
||||
iRobot OSFamily = "iRobot"
|
||||
illumos OSFamily = "illumos"
|
||||
ipTIME OSFamily = "ipTIME"
|
||||
lwIP OSFamily = "lwIP"
|
||||
m3 OSFamily = "m3"
|
||||
mbNet OSFamily = "mbNet"
|
||||
nCircle OSFamily = "nCircle"
|
||||
)
|
||||
+508
@@ -0,0 +1,508 @@
|
||||
package nmap
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
family "github.com/Ullaakut/nmap/pkg/osfamilies"
|
||||
)
|
||||
|
||||
// Run represents an nmap scanning run.
|
||||
type Run struct {
|
||||
XMLName xml.Name `xml:"nmaprun"`
|
||||
|
||||
Args string `xml:"args,attr" json:"args"`
|
||||
ProfileName string `xml:"profile_name,attr" json:"profile_name"`
|
||||
Scanner string `xml:"scanner,attr" json:"scanner"`
|
||||
StartStr string `xml:"startstr,attr" json:"start_str"`
|
||||
Version string `xml:"version,attr" json:"version"`
|
||||
XMLOutputVersion string `xml:"xmloutputversion,attr" json:"xml_output_version"`
|
||||
Debugging Debugging `xml:"debugging" json:"debugging"`
|
||||
Stats Stats `xml:"runstats" json:"run_stats"`
|
||||
ScanInfo ScanInfo `xml:"scaninfo" json:"scan_info"`
|
||||
Start Timestamp `xml:"start,attr" json:"start"`
|
||||
Verbose Verbose `xml:"verbose" json:"verbose"`
|
||||
Hosts []Host `xml:"host" json:"hosts"`
|
||||
PostScripts []Script `xml:"postscript>script" json:"post_scripts"`
|
||||
PreScripts []Script `xml:"prescript>script" json:"pre_scripts"`
|
||||
Targets []Target `xml:"target" json:"targets"`
|
||||
TaskBegin []Task `xml:"taskbegin" json:"task_begin"`
|
||||
TaskProgress []TaskProgress `xml:"taskprogress" json:"task_progress"`
|
||||
TaskEnd []Task `xml:"taskend" json:"task_end"`
|
||||
|
||||
rawXML []byte
|
||||
}
|
||||
|
||||
// ToFile writes a Run as XML into the specified file path.
|
||||
func (r Run) ToFile(filePath string) error {
|
||||
return ioutil.WriteFile(filePath, r.rawXML, 0666)
|
||||
}
|
||||
|
||||
// ScanInfo represents the scan information.
|
||||
type ScanInfo struct {
|
||||
NumServices int `xml:"numservices,attr" json:"num_services"`
|
||||
Protocol string `xml:"protocol,attr" json:"protocol"`
|
||||
ScanFlags string `xml:"scanflags,attr" json:"scan_flags"`
|
||||
Services string `xml:"services,attr" json:"services"`
|
||||
Type string `xml:"type,attr" json:"type"`
|
||||
}
|
||||
|
||||
// Verbose contains the verbosity level of the scan.
|
||||
type Verbose struct {
|
||||
Level int `xml:"level,attr" json:"level"`
|
||||
}
|
||||
|
||||
// Debugging contains the debugging level of the scan.
|
||||
type Debugging struct {
|
||||
Level int `xml:"level,attr" json:"level"`
|
||||
}
|
||||
|
||||
// Task contains information about a task.
|
||||
type Task struct {
|
||||
Time Timestamp `xml:"time,attr" json:"time"`
|
||||
Task string `xml:"task,attr" json:"task"`
|
||||
ExtraInfo string `xml:"extrainfo,attr" json:"extra_info"`
|
||||
}
|
||||
|
||||
// TaskProgress contains information about the progression of a task.
|
||||
type TaskProgress struct {
|
||||
Percent float32 `xml:"percent,attr" json:"percent"`
|
||||
Remaining int `xml:"remaining,attr" json:"remaining"`
|
||||
Task string `xml:"task,attr" json:"task"`
|
||||
Etc Timestamp `xml:"etc,attr" json:"etc"`
|
||||
Time Timestamp `xml:"time,attr" json:"time"`
|
||||
}
|
||||
|
||||
// Target represents a target, how it was specified when passed to nmap,
|
||||
// its status and the reason for its status. Example:
|
||||
// <target specification="domain.does.not.exist" status="skipped" reason="invalid"/>
|
||||
type Target struct {
|
||||
Specification string `xml:"specification,attr" json:"specification"`
|
||||
Status string `xml:"status,attr" json:"status"`
|
||||
Reason string `xml:"reason,attr" json:"reason"`
|
||||
}
|
||||
|
||||
// Host represents a host that was scanned.
|
||||
type Host struct {
|
||||
Distance Distance `xml:"distance" json:"distance"`
|
||||
EndTime Timestamp `xml:"endtime,attr,omitempty" json:"end_time"`
|
||||
IPIDSequence IPIDSequence `xml:"ipidsequence" json:"ip_id_sequence"`
|
||||
OS OS `xml:"os" json:"os"`
|
||||
StartTime Timestamp `xml:"starttime,attr,omitempty" json:"start_time"`
|
||||
Status Status `xml:"status" json:"status"`
|
||||
TCPSequence TCPSequence `xml:"tcpsequence" json:"tcp_sequence"`
|
||||
TCPTSSequence TCPTSSequence `xml:"tcptssequence" json:"tcp_ts_sequence"`
|
||||
Times Times `xml:"times" json:"times"`
|
||||
Trace Trace `xml:"trace" json:"trace"`
|
||||
Uptime Uptime `xml:"uptime" json:"uptime"`
|
||||
Comment string `xml:"comment,attr" json:"comment"`
|
||||
Addresses []Address `xml:"address" json:"addresses"`
|
||||
ExtraPorts []ExtraPort `xml:"ports>extraports" json:"extra_ports"`
|
||||
Hostnames []Hostname `xml:"hostnames>hostname" json:"hostnames"`
|
||||
HostScripts []Script `xml:"hostscript>script" json:"host_scripts"`
|
||||
Ports []Port `xml:"ports>port" json:"ports"`
|
||||
Smurfs []Smurf `xml:"smurf" json:"smurfs"`
|
||||
}
|
||||
|
||||
// Status represents a host's status.
|
||||
type Status struct {
|
||||
State string `xml:"state,attr" json:"state"`
|
||||
Reason string `xml:"reason,attr" json:"reason"`
|
||||
ReasonTTL float32 `xml:"reason_ttl,attr" json:"reason_ttl"`
|
||||
}
|
||||
|
||||
func (s Status) String() string {
|
||||
return s.State
|
||||
}
|
||||
|
||||
// Address contains a IPv4 or IPv6 address for a host.
|
||||
type Address struct {
|
||||
Addr string `xml:"addr,attr" json:"addr"`
|
||||
AddrType string `xml:"addrtype,attr" json:"addr_type"`
|
||||
Vendor string `xml:"vendor,attr" json:"vendor"`
|
||||
}
|
||||
|
||||
func (a Address) String() string {
|
||||
return a.Addr
|
||||
}
|
||||
|
||||
// Hostname is a name for a host.
|
||||
type Hostname struct {
|
||||
Name string `xml:"name,attr" json:"name"`
|
||||
Type string `xml:"type,attr" json:"type"`
|
||||
}
|
||||
|
||||
func (h Hostname) String() string {
|
||||
return h.Name
|
||||
}
|
||||
|
||||
// Smurf contains repsonses from a smurf attack.
|
||||
type Smurf struct {
|
||||
Responses string `xml:"responses,attr" json:"responses"`
|
||||
}
|
||||
|
||||
// ExtraPort contains the information about the closed and filtered ports.
|
||||
type ExtraPort struct {
|
||||
State string `xml:"state,attr" json:"state"`
|
||||
Count int `xml:"count,attr" json:"count"`
|
||||
Reasons []Reason `xml:"extrareasons" json:"reasons"`
|
||||
}
|
||||
|
||||
// Reason represents a reason why a port is closed or filtered.
|
||||
// This won't be in the scan results unless WithReason is used.
|
||||
type Reason struct {
|
||||
Reason string `xml:"reason,attr" json:"reason"`
|
||||
Count int `xml:"count,attr" json:"count"`
|
||||
}
|
||||
|
||||
// Port contains all the information about a scanned port.
|
||||
type Port struct {
|
||||
ID uint16 `xml:"portid,attr" json:"id"`
|
||||
Protocol string `xml:"protocol,attr" json:"protocol"`
|
||||
Owner Owner `xml:"owner" json:"owner"`
|
||||
Service Service `xml:"service" json:"service"`
|
||||
State State `xml:"state" json:"state"`
|
||||
Scripts []Script `xml:"script" json:"scripts"`
|
||||
}
|
||||
|
||||
// PortStatus represents a port's state.
|
||||
type PortStatus string
|
||||
|
||||
// Enumerates the different possible state values.
|
||||
const (
|
||||
Open PortStatus = "open"
|
||||
Closed PortStatus = "closed"
|
||||
Filtered PortStatus = "filtered"
|
||||
Unfiltered PortStatus = "unfiltered"
|
||||
)
|
||||
|
||||
// Status returns the status of a port.
|
||||
func (p Port) Status() PortStatus {
|
||||
return PortStatus(p.State.State)
|
||||
}
|
||||
|
||||
// State contains information about a given port's status.
|
||||
// State will be open, closed, etc.
|
||||
type State struct {
|
||||
State string `xml:"state,attr" json:"state"`
|
||||
Reason string `xml:"reason,attr" json:"reason"`
|
||||
ReasonIP string `xml:"reason_ip,attr" json:"reason_ip"`
|
||||
ReasonTTL float32 `xml:"reason_ttl,attr" json:"reason_ttl"`
|
||||
}
|
||||
|
||||
func (s State) String() string {
|
||||
return s.State
|
||||
}
|
||||
|
||||
// Owner contains the name of a port's owner.
|
||||
type Owner struct {
|
||||
Name string `xml:"name,attr" json:"name"`
|
||||
}
|
||||
|
||||
func (o Owner) String() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// Service contains detailed information about a service on an open port.
|
||||
type Service struct {
|
||||
DeviceType string `xml:"devicetype,attr" json:"device_type"`
|
||||
ExtraInfo string `xml:"extrainfo,attr" json:"extra_info"`
|
||||
HighVersion string `xml:"highver,attr" json:"high_version"`
|
||||
Hostname string `xml:"hostname,attr" json:"hostname"`
|
||||
LowVersion string `xml:"lowver,attr" json:"low_version"`
|
||||
Method string `xml:"method,attr" json:"method"`
|
||||
Name string `xml:"name,attr" json:"name"`
|
||||
OSType string `xml:"ostype,attr" json:"os_type"`
|
||||
Product string `xml:"product,attr" json:"product"`
|
||||
Proto string `xml:"proto,attr" json:"proto"`
|
||||
RPCNum string `xml:"rpcnum,attr" json:"rpc_num"`
|
||||
ServiceFP string `xml:"servicefp,attr" json:"service_fp"`
|
||||
Tunnel string `xml:"tunnel,attr" json:"tunnel"`
|
||||
Version string `xml:"version,attr" json:"version"`
|
||||
Configuration int `xml:"conf,attr" json:"configuration"`
|
||||
CPEs []CPE `xml:"cpe" json:"cpes"`
|
||||
}
|
||||
|
||||
func (s Service) String() string {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
// CPE (Common Platform Enumeration) is a standardized way to name software
|
||||
// applications, operating systems and hardware platforms.
|
||||
type CPE string
|
||||
|
||||
// Script represents an Nmap Scripting Engine script.
|
||||
type Script struct {
|
||||
ID string `xml:"id,attr" json:"id"`
|
||||
Output string `xml:"output,attr" json:"output"`
|
||||
Tables Table `xml:"table" json:"tables"`
|
||||
}
|
||||
|
||||
// Table contains the output of the script in an easily parsable form.
|
||||
type Table map[string]string
|
||||
|
||||
// MarshalXML implements the xml.Marshaler interface.
|
||||
func (t Table) MarshalXML(e *xml.Encoder, startElem xml.StartElement) error {
|
||||
tokens := []xml.Token{startElem}
|
||||
|
||||
// Add all key/value pairs as entries in the XML array.
|
||||
for key, value := range t {
|
||||
// Start of the XML element.
|
||||
start := xml.StartElement{
|
||||
Name: xml.Name{
|
||||
Local: "elem",
|
||||
},
|
||||
Attr: []xml.Attr{
|
||||
{
|
||||
Name: xml.Name{
|
||||
Local: "key",
|
||||
},
|
||||
Value: key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// End of the XML element.
|
||||
end := xml.EndElement{
|
||||
Name: start.Name,
|
||||
}
|
||||
|
||||
// Append the start, content and end of the new element to the list of XML tokens.
|
||||
tokens = append(tokens, start, xml.CharData(value), end)
|
||||
}
|
||||
|
||||
tokens = append(tokens, xml.EndElement{
|
||||
Name: startElem.Name,
|
||||
})
|
||||
|
||||
// Encode all tokens.
|
||||
for _, t := range tokens {
|
||||
err := e.EncodeToken(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Flush the encoder to ensure that the tokens are written.
|
||||
err := e.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalXML implements the xml.Unmarshaler interface.
|
||||
func (t *Table) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
table := make(map[string]string)
|
||||
|
||||
var (
|
||||
currentKey string
|
||||
currentValue string
|
||||
)
|
||||
|
||||
for {
|
||||
token, err := d.Token()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
switch element := token.(type) {
|
||||
case xml.StartElement:
|
||||
for _, attribute := range element.Attr {
|
||||
if attribute.Name.Local == "key" {
|
||||
currentKey = attribute.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
case xml.CharData:
|
||||
currentValue = string(element)
|
||||
case xml.EndElement:
|
||||
// Insert the current key/value pair.
|
||||
table[currentKey] = currentValue
|
||||
|
||||
// Reset the temporary variables for the next pair.
|
||||
currentKey = ""
|
||||
currentValue = ""
|
||||
}
|
||||
}
|
||||
|
||||
*t = table
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OS contains the fingerprinted operating system for a host.
|
||||
type OS struct {
|
||||
PortsUsed []PortUsed `xml:"portused" json:"ports_used"`
|
||||
Matches []OSMatch `xml:"osmatch" json:"os_matches"`
|
||||
Fingerprints []OSFingerprint `xml:"osfingerprint" json:"os_fingerprints"`
|
||||
Classes []OSClass `xml:"osclass" json:"os_classes"`
|
||||
}
|
||||
|
||||
// PortUsed is the port used to fingerprint an operating system.
|
||||
type PortUsed struct {
|
||||
State string `xml:"state,attr" json:"state"`
|
||||
Proto string `xml:"proto,attr" json:"proto"`
|
||||
ID int `xml:"portid,attr" json:"port_id"`
|
||||
}
|
||||
|
||||
// OSMatch contains detailed information regarding an operating system fingerprint.
|
||||
type OSMatch struct {
|
||||
Name string `xml:"name,attr" json:"name"`
|
||||
Accuracy int `xml:"accuracy,attr" json:"accuracy"`
|
||||
Line int `xml:"line,attr" json:"line"`
|
||||
}
|
||||
|
||||
// OSClass contains vendor information about an operating system.
|
||||
type OSClass struct {
|
||||
Vendor string `xml:"vendor,attr" json:"vendor"`
|
||||
OSGeneration string `xml:"osgen,attr" json:"os_generation"`
|
||||
Type string `xml:"type,attr" json:"type"`
|
||||
Accuracy int `xml:"accuracy,attr" json:"accuracy"`
|
||||
Family string `xml:"osfamily,attr" json:"os_family"`
|
||||
CPEs []CPE `xml:"cpe" json:"cpes"`
|
||||
}
|
||||
|
||||
// OSFamily returns the OS family in an enumerated format.
|
||||
func (o OSClass) OSFamily() family.OSFamily {
|
||||
return family.OSFamily(o.Family)
|
||||
}
|
||||
|
||||
// OSFingerprint is the actual fingerprint string of an operating system.
|
||||
type OSFingerprint struct {
|
||||
Fingerprint string `xml:"fingerprint,attr" json:"fingerprint"`
|
||||
}
|
||||
|
||||
// Distance is the amount of hops to a particular host.
|
||||
type Distance struct {
|
||||
Value int `xml:"value,attr" json:"value"`
|
||||
}
|
||||
|
||||
// Uptime is the amount of time the host has been up.
|
||||
type Uptime struct {
|
||||
Seconds int `xml:"seconds,attr" json:"seconds"`
|
||||
Lastboot string `xml:"lastboot,attr" json:"last_boot"`
|
||||
}
|
||||
|
||||
// Sequence represents a detected sequence.
|
||||
type Sequence struct {
|
||||
Class string `xml:"class,attr" json:"class"`
|
||||
Values string `xml:"values,attr" json:"values"`
|
||||
}
|
||||
|
||||
// TCPSequence represents a detected TCP sequence.
|
||||
type TCPSequence struct {
|
||||
Index int `xml:"index,attr" json:"index"`
|
||||
Difficulty string `xml:"difficulty,attr" json:"difficulty"`
|
||||
Values string `xml:"values,attr" json:"values"`
|
||||
}
|
||||
|
||||
// IPIDSequence represents a detected IP ID sequence.
|
||||
type IPIDSequence Sequence
|
||||
|
||||
// TCPTSSequence represents a detected TCP TS sequence.
|
||||
type TCPTSSequence Sequence
|
||||
|
||||
// Trace represents the trace to a host, including the hops.
|
||||
type Trace struct {
|
||||
Proto string `xml:"proto,attr" json:"proto"`
|
||||
Port int `xml:"port,attr" json:"port"`
|
||||
Hops []Hop `xml:"hop" json:"hops"`
|
||||
}
|
||||
|
||||
// Hop is an IP hop to a host.
|
||||
type Hop struct {
|
||||
TTL float32 `xml:"ttl,attr" json:"ttl"`
|
||||
RTT string `xml:"rtt,attr" json:"rtt"`
|
||||
IPAddr string `xml:"ipaddr,attr" json:"ip_addr"`
|
||||
Host string `xml:"host,attr" json:"host"`
|
||||
}
|
||||
|
||||
// Times contains time statistics for an nmap scan.
|
||||
type Times struct {
|
||||
SRTT string `xml:"srtt,attr" json:"srtt"`
|
||||
RTT string `xml:"rttvar,attr" json:"rttv"`
|
||||
To string `xml:"to,attr" json:"to"`
|
||||
}
|
||||
|
||||
// Stats contains statistics for an nmap scan.
|
||||
type Stats struct {
|
||||
Finished Finished `xml:"finished" json:"finished"`
|
||||
Hosts HostStats `xml:"hosts" json:"hosts"`
|
||||
}
|
||||
|
||||
// Finished contains detailed statistics regarding a finished scan.
|
||||
type Finished struct {
|
||||
Time Timestamp `xml:"time,attr" json:"time"`
|
||||
TimeStr string `xml:"timestr,attr" json:"time_str"`
|
||||
Elapsed float32 `xml:"elapsed,attr" json:"elapsed"`
|
||||
Summary string `xml:"summary,attr" json:"summary"`
|
||||
Exit string `xml:"exit,attr" json:"exit"`
|
||||
ErrorMsg string `xml:"errormsg,attr" json:"error_msg"`
|
||||
}
|
||||
|
||||
// HostStats contains the amount of up and down hosts and the total count.
|
||||
type HostStats struct {
|
||||
Up int `xml:"up,attr" json:"up"`
|
||||
Down int `xml:"down,attr" json:"down"`
|
||||
Total int `xml:"total,attr" json:"total"`
|
||||
}
|
||||
|
||||
// Timestamp represents time as a UNIX timestamp in seconds.
|
||||
type Timestamp time.Time
|
||||
|
||||
// ParseTime converts a UNIX timestamp string to a time.Time.
|
||||
func (t *Timestamp) ParseTime(s string) error {
|
||||
timestamp, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = Timestamp(time.Unix(timestamp, 0))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FormatTime formats the time.Time value as a UNIX timestamp string.
|
||||
func (t Timestamp) FormatTime() string {
|
||||
return strconv.FormatInt(time.Time(t).Unix(), 10)
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (t Timestamp) MarshalJSON() ([]byte, error) {
|
||||
return []byte(t.FormatTime()), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (t *Timestamp) UnmarshalJSON(b []byte) error {
|
||||
return t.ParseTime(string(b))
|
||||
}
|
||||
|
||||
// MarshalXMLAttr implements the xml.MarshalerAttr interface.
|
||||
func (t Timestamp) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
|
||||
if time.Time(t).IsZero() {
|
||||
return xml.Attr{}, nil
|
||||
}
|
||||
|
||||
return xml.Attr{Name: name, Value: t.FormatTime()}, nil
|
||||
}
|
||||
|
||||
// UnmarshalXMLAttr implements the xml.UnmarshalXMLAttr interface.
|
||||
func (t *Timestamp) UnmarshalXMLAttr(attr xml.Attr) (err error) {
|
||||
return t.ParseTime(attr.Value)
|
||||
}
|
||||
|
||||
// Parse takes a byte array of nmap xml data and unmarshals it into a
|
||||
// Run struct.
|
||||
func Parse(content []byte) (*Run, error) {
|
||||
r := &Run{
|
||||
rawXML: content,
|
||||
}
|
||||
|
||||
err := xml.Unmarshal(content, r)
|
||||
|
||||
return r, err
|
||||
}
|
||||
+939
@@ -0,0 +1,939 @@
|
||||
package nmap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
family "github.com/Ullaakut/nmap/pkg/osfamilies"
|
||||
)
|
||||
|
||||
func TestParseTime(t *testing.T) {
|
||||
ts := Timestamp{}
|
||||
|
||||
err := ts.ParseTime("invalid")
|
||||
if err == nil {
|
||||
t.Errorf("expected strconv.ParseInt: parsing \"invalid\": invalid syntax got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatTime(t *testing.T) {
|
||||
originalStr := "123456789"
|
||||
ts := Timestamp{}
|
||||
|
||||
err := ts.ParseTime(originalStr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
result := ts.FormatTime()
|
||||
|
||||
if result != originalStr {
|
||||
t.Errorf("expected %s got %s", originalStr, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOSFamily(t *testing.T) {
|
||||
osc := OSClass{
|
||||
Family: "Linux",
|
||||
}
|
||||
|
||||
if osc.OSFamily() != family.Linux {
|
||||
t.Errorf("expected OSClass.OSFamily() to be equal to %v, got %v", family.Linux, osc.OSFamily())
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTableXML(t *testing.T) {
|
||||
expectedTable := map[string]string{
|
||||
"key": "AAAAB3NzaC1yc2EAAAABIwAAAQEAwVKoTY/7GFG7BmKkG6qFAHY/f3ciDX2MXTBLMEJP0xyUJsoy/CVRYw2b4qUB/GCJ5lh2InP+LVnPD3ZdtpyIvbS0eRZs/BH+mVLGh9xA/wOEUiiCfzQRsHj1xn7cqeWViAzQtdGluk/5CVAvr1FU3HNaaWkg7KQOSiKAzgDwCBtQhlgI40xdXgbqMkrHeP4M1p4MxoEVpZMe4oObACWwazeHP/Xas1vy5rbnmE59MpEZaA8t7AfGlW4MrVMhAB1JsFMdd0qFLpy/l93H3ptSlx1+6PQ5gUyjhmDUjMR+k6fb0yOeGdOrjN8IrWPmebZRFBjK5aCJwubgY/03VsSBMQ==",
|
||||
"fingerprint": "79f809acd4e232421049d3bd208285ec",
|
||||
"type": "ssh-rsa",
|
||||
"bits": "2048",
|
||||
}
|
||||
|
||||
input := []byte(fmt.Sprintf(
|
||||
`<table><elem key="key">%s</elem><elem key="fingerprint">%s</elem><elem key="type">%s</elem><elem key="bits">%s</elem></table>`,
|
||||
expectedTable["key"],
|
||||
expectedTable["fingerprint"],
|
||||
expectedTable["type"],
|
||||
expectedTable["bits"],
|
||||
))
|
||||
|
||||
var table Table
|
||||
|
||||
err := xml.Unmarshal(input, &table)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if table["key"] != expectedTable["key"] {
|
||||
t.Errorf("expected %v got %v", expectedTable["key"], table["key"])
|
||||
}
|
||||
|
||||
if table["fingerprint"] != expectedTable["fingerprint"] {
|
||||
t.Errorf("expected %v got %v", expectedTable["fingerprint"], table["fingerprint"])
|
||||
}
|
||||
|
||||
if table["type"] != expectedTable["type"] {
|
||||
t.Errorf("expected %v got %v", expectedTable["type"], table["type"])
|
||||
}
|
||||
|
||||
if table["bits"] != expectedTable["bits"] {
|
||||
t.Errorf("expected %v got %v", expectedTable["bits"], table["bits"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatTableXML(t *testing.T) {
|
||||
table := Table(map[string]string{
|
||||
"key": "AAAAB3NzaC1yc2EAAAABIwAAAQEAwVKoTY/7GFG7BmKkG6qFAHY/f3ciDX2MXTBLMEJP0xyUJsoy/CVRYw2b4qUB/GCJ5lh2InP+LVnPD3ZdtpyIvbS0eRZs/BH+mVLGh9xA/wOEUiiCfzQRsHj1xn7cqeWViAzQtdGluk/5CVAvr1FU3HNaaWkg7KQOSiKAzgDwCBtQhlgI40xdXgbqMkrHeP4M1p4MxoEVpZMe4oObACWwazeHP/Xas1vy5rbnmE59MpEZaA8t7AfGlW4MrVMhAB1JsFMdd0qFLpy/l93H3ptSlx1+6PQ5gUyjhmDUjMR+k6fb0yOeGdOrjN8IrWPmebZRFBjK5aCJwubgY/03VsSBMQ==",
|
||||
"fingerprint": "79f809acd4e232421049d3bd208285ec",
|
||||
"type": "ssh-rsa",
|
||||
"bits": "2048",
|
||||
})
|
||||
|
||||
expectedXML := [][]byte{
|
||||
[]byte("<Table>"),
|
||||
[]byte(fmt.Sprintf(`<elem key="key">%s</elem>`, table["key"])),
|
||||
[]byte(fmt.Sprintf(`<elem key="fingerprint">%s</elem>`, table["fingerprint"])),
|
||||
[]byte(fmt.Sprintf(`<elem key="type">%s</elem>`, table["type"])),
|
||||
[]byte(fmt.Sprintf(`<elem key="bits">%s</elem>`, table["bits"])),
|
||||
[]byte("</Table>"),
|
||||
}
|
||||
|
||||
XML, err := xml.Marshal(table)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, expectedXMLElement := range expectedXML {
|
||||
if !bytes.Contains(XML, expectedXMLElement) {
|
||||
t.Errorf("missing %s in %s", expectedXMLElement, XML)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRunXML(t *testing.T) {
|
||||
tests := []struct {
|
||||
inputFile string
|
||||
|
||||
expectedResult *Run
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
inputFile: "test_xml/scan01.xml",
|
||||
|
||||
expectedResult: &Run{
|
||||
Args: "nmap -A -v -oX sample-03.xml freshmeat.net sourceforge.net nmap.org kernel.org openbsd.org netbsd.org google.com gmail.com",
|
||||
Scanner: "nmap",
|
||||
StartStr: "Sun Jan 27 21:10:02 2008",
|
||||
Version: "4.53",
|
||||
XMLOutputVersion: "1.01",
|
||||
ScanInfo: ScanInfo{
|
||||
NumServices: 1714,
|
||||
Protocol: "tcp",
|
||||
Services: "1-1027,1029-1033,1040,1043,1050,1058-1059,1067-1068,1076,1080,1083-1084,1103,1109-1110,1112,1127,1139,1155,1158,1178,1212,1214,1220,1222,1234,1241,1248,1270,1337,1346-1381,1383-1552,1600,1650-1652,1661-1672,1680,1720,1723,1755,1761-1764,1827,1900,1935,1984,1986-2028,2030,2032-2035,2038,2040-2049,2053,2064-2065,2067-2068,2105-2106,2108,2111-2112,2120-2121,2201,2232,2241,2301,2307,2401,2430-2433,2500-2501,2564,2600-2605,2627-2628,2638,2766,2784,2809,2903,2998,3000-3001,3005-3006,3025,3045,3049,3052,3064,3086,3128,3141,3264,3268-3269,3292,3299,3306,3333,3372,3389,3397-3399,3421,3455-3457,3462,3531,3632,3689,3900,3984-3986,3999-4000,4002,4008,4045,4125,4132-4133,4144,4199,4224,4321,4333,4343,4444,4480,4500,4557,4559,4660,4662,4672,4899,4987,4998,5000-5003,5009-5011,5050,5060,5100-5102,5145,5190-5193,5232,5236,5300-5305,5308,5400,5405,5432,5490,5500,5510,5520,5530,5540,5550,5555,5560,5631-5632,5679-5680,5713-5717,5800-5803,5900-5903,5977-5979,5997-6009,6017,6050,6101,6103,6105-6106,6110-6112,6141-6148,6222,6346-6347,6400-6401,6502,6543-6544,6547-6548,6558,6588,6662,6665-6670,6699-6701,6881,6969,7000-7010,7070,7100,7200-7201,7273,7326,7464,7597,7937-7938,8000,8007,8009,8021,8076,8080-8082,8118,8123,8443,8770,8888,8892,9040,9050-9051,9090,9100-9107,9111,9152,9535,9876,9991-9992,9999-10000,10005,10082-10083,11371,12000,12345-12346,13701-13702,13705-13706,13708-13718,13720-13722,13782-13783,14141,15126,15151,16080,16444,16959,17007,17300,18000,18181-18185,18187,19150,20005,22273,22289,22305,22321,22370,26208,27000-27010,27374,27665,31337,31416,32770-32780,32786-32787,38037,38292,43188,44334,44442-44443,47557,49400,50000,50002,54320,61439-61441,65301",
|
||||
Type: "syn",
|
||||
},
|
||||
Start: Timestamp(time.Unix(1201479002, 0)),
|
||||
Verbose: Verbose{
|
||||
Level: 1,
|
||||
},
|
||||
Stats: Stats{
|
||||
Finished: Finished{
|
||||
Time: Timestamp(time.Unix(1201481569, 0)),
|
||||
TimeStr: "Sun Jan 27 21:52:49 2008",
|
||||
},
|
||||
Hosts: HostStats{
|
||||
Up: 8,
|
||||
Total: 8,
|
||||
Down: 0,
|
||||
},
|
||||
},
|
||||
Hosts: []Host{
|
||||
{
|
||||
IPIDSequence: IPIDSequence{
|
||||
Class: "All zeros",
|
||||
Values: "0,0,0,0,0,0",
|
||||
},
|
||||
OS: OS{
|
||||
PortsUsed: []PortUsed{
|
||||
{
|
||||
State: "open",
|
||||
Proto: "tcp",
|
||||
ID: 80,
|
||||
},
|
||||
{
|
||||
State: "closed",
|
||||
Proto: "tcp",
|
||||
ID: 443,
|
||||
},
|
||||
},
|
||||
Matches: []OSMatch{
|
||||
{
|
||||
Name: "MicroTik RouterOS 2.9.46",
|
||||
Accuracy: 94,
|
||||
Line: 14788,
|
||||
},
|
||||
{
|
||||
Name: "Linksys WRT54GS WAP (Linux kernel)",
|
||||
Accuracy: 94,
|
||||
Line: 8292,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.4.18 - 2.4.32 (likely embedded)",
|
||||
Accuracy: 94,
|
||||
Line: 8499,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.4.21 - 2.4.33",
|
||||
Accuracy: 94,
|
||||
Line: 8624,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.4.27",
|
||||
Accuracy: 94,
|
||||
Line: 8675,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.4.28 - 2.4.30",
|
||||
Accuracy: 94,
|
||||
Line: 8693,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.6.5 - 2.6.18",
|
||||
Accuracy: 94,
|
||||
Line: 11411,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.6.8",
|
||||
Accuracy: 94,
|
||||
Line: 11485,
|
||||
},
|
||||
{
|
||||
Name: "WebVOIZE 120 IP phone",
|
||||
Accuracy: 94,
|
||||
Line: 18921,
|
||||
},
|
||||
{
|
||||
Name: "Linux 2.4.2 (Red Hat 7.1)",
|
||||
Accuracy: 91,
|
||||
Line: 8533,
|
||||
},
|
||||
},
|
||||
Fingerprints: []OSFingerprint{
|
||||
{
|
||||
Fingerprint: fingerprint,
|
||||
},
|
||||
},
|
||||
Classes: []OSClass{
|
||||
{
|
||||
Vendor: "MikroTik",
|
||||
OSGeneration: "2.X",
|
||||
Type: "software router",
|
||||
Accuracy: 94,
|
||||
Family: "RouterOS",
|
||||
},
|
||||
{
|
||||
Vendor: "Linksys",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 94,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "general purpose",
|
||||
Accuracy: 94,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.6.X",
|
||||
Type: "general purpose",
|
||||
Accuracy: 94,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "WebVOIZE",
|
||||
Type: "VoIP phone",
|
||||
Accuracy: 94,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "D-Link",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Inventel",
|
||||
Type: "WAP",
|
||||
Accuracy: 91,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "USRobotics",
|
||||
Type: "broadband router",
|
||||
Accuracy: 91,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "broadband router",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "media device",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Linux",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "VoIP gateway",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Netgear",
|
||||
Type: "WAP",
|
||||
Accuracy: 91,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "QLogic",
|
||||
Type: "switch",
|
||||
Accuracy: 91,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Sharp",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "PDA",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "FON",
|
||||
OSGeneration: "2.6.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 91,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "FON",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 90,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Belkin",
|
||||
Type: "WAP",
|
||||
Accuracy: 90,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Asus",
|
||||
Type: "WAP",
|
||||
Accuracy: 90,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Netgear",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "WAP",
|
||||
Accuracy: 90,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Xerox",
|
||||
Type: "printer",
|
||||
Accuracy: 90,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Aladdin",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "security-misc",
|
||||
Accuracy: 89,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Occam",
|
||||
Type: "VoIP gateway",
|
||||
Accuracy: 89,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Roku",
|
||||
Type: "media device",
|
||||
Accuracy: 89,
|
||||
Family: "embedded",
|
||||
},
|
||||
{
|
||||
Vendor: "Siemens",
|
||||
Type: "WAP",
|
||||
Accuracy: 89,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "3Com",
|
||||
OSGeneration: "2.4.X",
|
||||
Type: "broadband router",
|
||||
Accuracy: 89,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Dream Multimedia",
|
||||
OSGeneration: "2.6.X",
|
||||
Type: "media device",
|
||||
Accuracy: 89,
|
||||
Family: "Linux",
|
||||
},
|
||||
{
|
||||
Vendor: "Iomega",
|
||||
OSGeneration: "2.6.X",
|
||||
Type: "storage-misc",
|
||||
Accuracy: 89,
|
||||
Family: "Linux",
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: Status{
|
||||
State: "up",
|
||||
Reason: "reset",
|
||||
},
|
||||
TCPSequence: TCPSequence{
|
||||
Index: 242,
|
||||
Difficulty: "Good luck!",
|
||||
Values: "457B276,4584FC8,161C122C,161B185F,1605EA95,1614C498",
|
||||
},
|
||||
TCPTSSequence: TCPTSSequence{
|
||||
Class: "other",
|
||||
Values: "3FB03AA9,3FB03C75,45B26360,45B2636A,45B26374,45B2637E",
|
||||
},
|
||||
Times: Times{
|
||||
SRTT: "269788",
|
||||
RTT: "41141",
|
||||
To: "434352",
|
||||
},
|
||||
Trace: Trace{
|
||||
Proto: "tcp",
|
||||
Port: 80,
|
||||
Hops: []Hop{
|
||||
{
|
||||
TTL: 1,
|
||||
RTT: "1.83",
|
||||
IPAddr: "192.168.254.254",
|
||||
},
|
||||
{
|
||||
TTL: 2,
|
||||
RTT: "18.95",
|
||||
IPAddr: "200.217.89.32",
|
||||
},
|
||||
{
|
||||
TTL: 3,
|
||||
RTT: "18.33",
|
||||
IPAddr: "200.217.30.250",
|
||||
Host: "gigabitethernet5-1.80-cto-rn-rotd-02.telemar.net.br",
|
||||
},
|
||||
{
|
||||
TTL: 4,
|
||||
RTT: "45.05",
|
||||
IPAddr: "200.97.65.250",
|
||||
Host: "pos15-1-nbv-pe-rotd-03.telemar.net.br",
|
||||
},
|
||||
{
|
||||
TTL: 5,
|
||||
RTT: "43.49",
|
||||
IPAddr: "200.223.131.13",
|
||||
Host: "pos6-0-nbv-pe-rotn-01.telemar.net.br",
|
||||
},
|
||||
{
|
||||
TTL: 6,
|
||||
RTT: "91.27",
|
||||
IPAddr: "200.223.131.205",
|
||||
Host: "so-0-2-0-0-arc-rj-rotn-01.telemar.net.br",
|
||||
},
|
||||
{
|
||||
TTL: 8,
|
||||
RTT: "191.87",
|
||||
IPAddr: "200.223.131.110",
|
||||
Host: "PO0-3.ARC-RJ-ROTN-01.telemar.net.br",
|
||||
},
|
||||
{
|
||||
TTL: 9,
|
||||
RTT: "177.30",
|
||||
IPAddr: "208.173.90.89",
|
||||
Host: "bpr2-so-5-2-0.miamimit.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 10,
|
||||
RTT: "181.50",
|
||||
IPAddr: "208.172.97.169",
|
||||
Host: "cr2-pos-0-3-1-0.miami.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 11,
|
||||
RTT: "336.43",
|
||||
IPAddr: "206.24.210.70",
|
||||
Host: "cr1-loopback.sfo.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 12,
|
||||
RTT: "245.32",
|
||||
IPAddr: "204.70.200.229",
|
||||
Host: "er1-te-1-0-1.SanJose3Equinix.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 13,
|
||||
RTT: "238.47",
|
||||
IPAddr: "204.70.200.210",
|
||||
Host: "hr1-te-2-0-0.santaclarasc4.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 14,
|
||||
RTT: "322.90",
|
||||
IPAddr: "204.70.200.217",
|
||||
Host: "hr1-te-2-0-0.santaclarasc9.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 15,
|
||||
RTT: "330.96",
|
||||
IPAddr: "204.70.203.146",
|
||||
},
|
||||
{
|
||||
TTL: 16,
|
||||
RTT: "342.57",
|
||||
IPAddr: "66.35.194.59",
|
||||
Host: "csr2-ve242.santaclarasc8.savvis.net",
|
||||
},
|
||||
{
|
||||
TTL: 17,
|
||||
RTT: "248.22",
|
||||
IPAddr: "66.35.210.202",
|
||||
},
|
||||
{
|
||||
TTL: 18,
|
||||
RTT: "238.36",
|
||||
IPAddr: "66.35.250.168",
|
||||
Host: "freshmeat.net",
|
||||
},
|
||||
},
|
||||
},
|
||||
Uptime: Uptime{
|
||||
Seconds: 206,
|
||||
Lastboot: "Sun Jan 27 21:43:11 2008",
|
||||
},
|
||||
Addresses: []Address{
|
||||
{
|
||||
Addr: "66.35.250.168",
|
||||
AddrType: "ipv4",
|
||||
},
|
||||
},
|
||||
ExtraPorts: []ExtraPort{
|
||||
{
|
||||
State: "filtered",
|
||||
Count: 1712,
|
||||
Reasons: []Reason{
|
||||
{
|
||||
Reason: "host-prohibiteds",
|
||||
Count: 1712,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Hostnames: []Hostname{
|
||||
{
|
||||
Name: "freshmeat.net",
|
||||
Type: "PTR",
|
||||
},
|
||||
},
|
||||
Ports: []Port{
|
||||
{
|
||||
ID: 80,
|
||||
Protocol: "tcp",
|
||||
Service: Service{
|
||||
Name: "http",
|
||||
ExtraInfo: "(Unix) PHP/4.4.7",
|
||||
Method: "probed",
|
||||
Product: "Apache httpd",
|
||||
Version: "1.3.39",
|
||||
Configuration: 10,
|
||||
},
|
||||
State: State{
|
||||
State: "open",
|
||||
Reason: "syn-ack",
|
||||
ReasonTTL: 45,
|
||||
},
|
||||
Scripts: []Script{
|
||||
{
|
||||
ID: "robots.txt",
|
||||
Output: "User-Agent: * /img/ /redir/ ",
|
||||
},
|
||||
{
|
||||
ID: "HTML title",
|
||||
Output: "freshmeat.net: Welcome to freshmeat.net",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 443,
|
||||
Protocol: "tcp",
|
||||
Service: Service{
|
||||
Name: "https",
|
||||
Method: "table",
|
||||
Configuration: 3,
|
||||
},
|
||||
State: State{
|
||||
State: "closed",
|
||||
Reason: "reset",
|
||||
ReasonTTL: 46,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TaskBegin: []Task{
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479013, 0)),
|
||||
Task: "Ping Scan",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479014, 0)),
|
||||
Task: "Parallel DNS resolution of 8 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479015, 0)),
|
||||
Task: "System CNAME DNS resolution of 4 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479016, 0)),
|
||||
Task: "SYN Stealth Scan",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201480879, 0)),
|
||||
Task: "Service scan",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481006, 0)),
|
||||
Task: "Traceroute",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481028, 0)),
|
||||
Task: "Traceroute",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481059, 0)),
|
||||
Task: "Parallel DNS resolution of 85 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481070, 0)),
|
||||
Task: "System CNAME DNS resolution of 8 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481086, 0)),
|
||||
Task: "SCRIPT ENGINE",
|
||||
},
|
||||
},
|
||||
TaskProgress: []TaskProgress{
|
||||
{
|
||||
Percent: 3.22,
|
||||
Remaining: 903,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201479949, 0)),
|
||||
Time: Timestamp(time.Unix(1201479046, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 56.66,
|
||||
Remaining: 325,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201479767, 0)),
|
||||
Time: Timestamp(time.Unix(1201479442, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 77.02,
|
||||
Remaining: 225,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201479995, 0)),
|
||||
Time: Timestamp(time.Unix(1201479770, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 81.95,
|
||||
Remaining: 215,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480212, 0)),
|
||||
Time: Timestamp(time.Unix(1201479996, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 86.79,
|
||||
Remaining: 182,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480395, 0)),
|
||||
Time: Timestamp(time.Unix(1201480213, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 87.84,
|
||||
Remaining: 172,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480433, 0)),
|
||||
Time: Timestamp(time.Unix(1201480260, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 91.65,
|
||||
Remaining: 129,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480564, 0)),
|
||||
Time: Timestamp(time.Unix(1201480435, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 94.43,
|
||||
Remaining: 91,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480656, 0)),
|
||||
Time: Timestamp(time.Unix(1201480565, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 96.35,
|
||||
Remaining: 62,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480720, 0)),
|
||||
Time: Timestamp(time.Unix(1201480658, 0)),
|
||||
},
|
||||
{
|
||||
Percent: 97.76,
|
||||
Remaining: 39,
|
||||
Task: "SYN Stealth Scan",
|
||||
Etc: Timestamp(time.Unix(1201480760, 0)),
|
||||
Time: Timestamp(time.Unix(1201480721, 0)),
|
||||
},
|
||||
},
|
||||
TaskEnd: []Task{
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479014, 0)),
|
||||
Task: "Ping Scan",
|
||||
ExtraInfo: "8 total hosts",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479015, 0)),
|
||||
Task: "Parallel DNS resolution of 8 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201479016, 0)),
|
||||
Task: "System CNAME DNS resolution of 4 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201480878, 0)),
|
||||
Task: "SYN Stealth Scan",
|
||||
ExtraInfo: "8570 total ports",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201480984, 0)),
|
||||
Task: "Service scan",
|
||||
ExtraInfo: "20 services on 5 hosts",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481028, 0)),
|
||||
Task: "Traceroute",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481059, 0)),
|
||||
Task: "Traceroute",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481070, 0)),
|
||||
Task: "Parallel DNS resolution of 85 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481086, 0)),
|
||||
Task: "System CNAME DNS resolution of 8 hosts.",
|
||||
},
|
||||
{
|
||||
Time: Timestamp(time.Unix(1201481197, 0)),
|
||||
Task: "SCRIPT ENGINE",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.inputFile, func(t *testing.T) {
|
||||
rawXML, err := ioutil.ReadFile(test.inputFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
result, err := Parse(rawXML)
|
||||
|
||||
// Remove rawXML before comparing
|
||||
result.rawXML = []byte{}
|
||||
|
||||
compareResults(t, test.expectedResult, result)
|
||||
|
||||
if err != test.expectedError {
|
||||
t.Errorf("expected %v got %v", test.expectedError, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func compareResults(t *testing.T, expected, got *Run) {
|
||||
if got.Args != expected.Args {
|
||||
t.Errorf("unexpected arguments, expected %v got %v", expected.Args, got.Args)
|
||||
}
|
||||
|
||||
if got.ProfileName != expected.ProfileName {
|
||||
t.Errorf("unexpected arguments, expected %v got %v", expected.ProfileName, got.ProfileName)
|
||||
}
|
||||
|
||||
if got.Scanner != expected.Scanner {
|
||||
t.Errorf("unexpected arguments, expected %v got %v", expected.Scanner, got.Scanner)
|
||||
}
|
||||
|
||||
if got.StartStr != expected.StartStr {
|
||||
t.Errorf("unexpected arguments, expected %v got %v", expected.StartStr, got.StartStr)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got.Debugging, expected.Debugging) {
|
||||
t.Errorf("unexpected debugging, expected %+v got %+v", expected.Debugging, got.Debugging)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got.ScanInfo, expected.ScanInfo) {
|
||||
t.Errorf("unexpected scan info, expected %+v got %+v", expected.ScanInfo, got.ScanInfo)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got.Start, expected.Start) {
|
||||
t.Errorf("unexpected start time, expected %+v got %+v", expected.Start, got.Start)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got.Targets, expected.Targets) {
|
||||
t.Errorf("unexpected targets, expected %+v got %+v", expected.Targets, got.Targets)
|
||||
}
|
||||
|
||||
if len(expected.TaskBegin) != len(got.TaskBegin) {
|
||||
t.Errorf("unexpected tasks begin entries, expected to have %d entries, got %d instead", len(expected.TaskBegin), len(got.TaskBegin))
|
||||
} else {
|
||||
for idx := range expected.TaskBegin {
|
||||
if !reflect.DeepEqual(got.TaskBegin[idx], expected.TaskBegin[idx]) {
|
||||
t.Errorf("unexpected task begin entry, expected %+v got %+v", expected.TaskBegin[idx], got.TaskBegin[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(expected.TaskProgress) != len(got.TaskProgress) {
|
||||
t.Errorf("unexpected tasks progress entries, expected to have %d entries, got %d instead", len(expected.TaskProgress), len(got.TaskProgress))
|
||||
} else {
|
||||
for idx := range expected.TaskProgress {
|
||||
if !reflect.DeepEqual(got.TaskProgress[idx], expected.TaskProgress[idx]) {
|
||||
t.Errorf("unexpected task progress entry, expected %+v got %+v", expected.TaskProgress[idx], got.TaskProgress[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(expected.TaskEnd) != len(got.TaskEnd) {
|
||||
t.Errorf("unexpected tasks end entries, expected to have %d entries, got %d instead", len(expected.TaskEnd), len(got.TaskEnd))
|
||||
} else {
|
||||
for idx := range expected.TaskEnd {
|
||||
if !reflect.DeepEqual(got.TaskEnd[idx], expected.TaskEnd[idx]) {
|
||||
t.Errorf("unexpected task end entry, expected %+v got %+v", expected.TaskEnd[idx], got.TaskEnd[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(expected.Hosts) != len(got.Hosts) {
|
||||
t.Errorf("unexpected number of hosts, expected to have %d hosts, got %d instead", len(expected.Hosts), len(got.Hosts))
|
||||
} else {
|
||||
for idx := range expected.Hosts {
|
||||
if expected.Hosts[idx].Comment != got.Hosts[idx].Comment {
|
||||
t.Errorf("unexpected host comment, expected %v got %v", expected.Hosts[idx].Comment, got.Hosts[idx].Comment)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Addresses, got.Hosts[idx].Addresses) {
|
||||
t.Errorf("unexpected host addresses, expected %+v got %+v", expected.Hosts[idx].Addresses, got.Hosts[idx].Addresses)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Distance, got.Hosts[idx].Distance) {
|
||||
t.Errorf("unexpected host distance, expected %+v got %+v", expected.Hosts[idx].Distance, got.Hosts[idx].Distance)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].ExtraPorts, got.Hosts[idx].ExtraPorts) {
|
||||
t.Errorf("unexpected host extra ports, expected %+v got %+v", expected.Hosts[idx].ExtraPorts, got.Hosts[idx].ExtraPorts)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].HostScripts, got.Hosts[idx].HostScripts) {
|
||||
t.Errorf("unexpected host host scripts, expected %+v got %+v", expected.Hosts[idx].HostScripts, got.Hosts[idx].HostScripts)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Hostnames, got.Hosts[idx].Hostnames) {
|
||||
t.Errorf("unexpected host host names, expected %+v got %+v", expected.Hosts[idx].Hostnames, got.Hosts[idx].Hostnames)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].IPIDSequence, got.Hosts[idx].IPIDSequence) {
|
||||
t.Errorf("unexpected host IPIDSequence, expected %+v got %+v", expected.Hosts[idx].IPIDSequence, got.Hosts[idx].IPIDSequence)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].OS, got.Hosts[idx].OS) {
|
||||
t.Errorf("unexpected host OS, expected %+v got %+v", expected.Hosts[idx].OS, got.Hosts[idx].OS)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Ports, got.Hosts[idx].Ports) {
|
||||
t.Errorf("unexpected host ports, expected %+v got %+v", expected.Hosts[idx].Ports, got.Hosts[idx].Ports)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Smurfs, got.Hosts[idx].Smurfs) {
|
||||
t.Errorf("unexpected host smurfs, expected %+v got %+v", expected.Hosts[idx].Smurfs, got.Hosts[idx].Smurfs)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].StartTime, got.Hosts[idx].StartTime) {
|
||||
t.Errorf("unexpected host start time, expected %+v got %+v", expected.Hosts[idx].StartTime, got.Hosts[idx].StartTime)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Status, got.Hosts[idx].Status) {
|
||||
t.Errorf("unexpected host status, expected %+v got %+v", expected.Hosts[idx].Status, got.Hosts[idx].Status)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].TCPSequence, got.Hosts[idx].TCPSequence) {
|
||||
t.Errorf("unexpected host TCPSequence, expected %+v got %+v", expected.Hosts[idx].TCPSequence, got.Hosts[idx].TCPSequence)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].TCPTSSequence, got.Hosts[idx].TCPTSSequence) {
|
||||
t.Errorf("unexpected host TCPTSSequence, expected %+v got %+v", expected.Hosts[idx].TCPTSSequence, got.Hosts[idx].TCPTSSequence)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Times, got.Hosts[idx].Times) {
|
||||
t.Errorf("unexpected host times, expected %+v got %+v", expected.Hosts[idx].Times, got.Hosts[idx].Times)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Trace, got.Hosts[idx].Trace) {
|
||||
t.Errorf("unexpected host trace, expected %+v got %+v", expected.Hosts[idx].Trace, got.Hosts[idx].Trace)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected.Hosts[idx].Uptime, got.Hosts[idx].Uptime) {
|
||||
t.Errorf("unexpected host uptime, expected %+v got %+v", expected.Hosts[idx].Uptime, got.Hosts[idx].Uptime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fingerprint = "SCAN(V=4.53%D=1/27%OT=80%CT=443%CU=%PV=N%G=N%TM=479D25ED%P=i686-pc-linux-gnu)\nSEQ(SP=F2%GCD=1%ISR=E9%TI=Z%TS=1C)\nOPS(O1=M5B4ST11NW0%O2=M5B4ST11NW0%O3=M5B4NNT11NW0%O4=M5B4ST11NW0%O5=M5B4ST11NW0%O6=M5B4ST11)\nWIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16A0)\nECN(R=Y%DF=Y%TG=40%W=16D0%O=M5B4NNSNW0%CC=N%Q=)\nT1(R=Y%DF=Y%TG=40%S=O%A=S+%F=AS%RD=0%Q=)\nT2(R=N)\nT3(R=Y%DF=Y%TG=40%W=16A0%S=O%A=S+%F=AS%O=M5B4ST11NW0%RD=0%Q=)\nT4(R=Y%DF=Y%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)\nT5(R=Y%DF=Y%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)\nT6(R=Y%DF=Y%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)\nT7(R=Y%DF=Y%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)\nU1(R=N)\nIE(R=N)\n"
|
||||
Reference in New Issue
Block a user