dddd/lib/masscan/masscan.go
SleepingBag945 01e7d0b159 dddd
2023-08-18 08:55:46 +02:00

145 lines
2.7 KiB
Go

package masscan
import (
"bytes"
"encoding/xml"
"github.com/pkg/errors"
"io"
"os/exec"
)
type Address struct {
Addr string `xml:"addr,attr"`
AddrType string `xml:"addrtype,attr"`
}
type State struct {
State string `xml:"state,attr"`
Reason string `xml:"reason,attr"`
ReasonTTL string `xml:"reason_ttl,attr"`
}
type Host struct {
XMLName xml.Name `xml:"host"`
Endtime string `xml:"endtime,attr"`
Address Address `xml:"address"`
Ports Ports `xml:"ports>port"`
}
type Ports []struct {
Protocol string `xml:"protocol,attr"`
Portid string `xml:"portid,attr"`
State State `xml:"state"`
Service Service `xml:"service"`
}
type Service struct {
Name string `xml:"name,attr"`
Banner string `xml:"banner,attr"`
}
type Masscan struct {
SystemPath string
Args []string
Ports string
FileName string
Rate string
Exclude string
Result []byte
}
func (m *Masscan) SetSystemPath(systemPath string) {
if systemPath != "" {
m.SystemPath = systemPath
}
}
func (m *Masscan) SetArgs(arg ...string) {
m.Args = arg
}
func (m *Masscan) SetPorts(ports string) {
m.Ports = ports
}
func (m *Masscan) SetFileName(name string) {
m.FileName = name
}
func (m *Masscan) SetRate(rate string) {
m.Rate = rate
}
func (m *Masscan) SetExclude(exclude string) {
m.Exclude = exclude
}
// Start scanning
func (m *Masscan) Run() error {
var (
cmd *exec.Cmd
outb, errs bytes.Buffer
)
if m.Rate != "" {
m.Args = append(m.Args, "--rate")
m.Args = append(m.Args, m.Rate)
}
if m.FileName != "" {
m.Args = append(m.Args, "-iL")
m.Args = append(m.Args, m.FileName)
}
if m.Ports != "" {
m.Args = append(m.Args, "-p")
m.Args = append(m.Args, m.Ports)
}
if m.Exclude != "" {
m.Args = append(m.Args, "--exclude")
m.Args = append(m.Args, m.Exclude)
}
m.Args = append(m.Args, "-oX")
m.Args = append(m.Args, "-")
cmd = exec.Command(m.SystemPath, m.Args...)
cmd.Stdout = &outb
cmd.Stderr = &errs
err := cmd.Run()
if err != nil {
if errs.Len() > 0 {
return errors.New(errs.String())
}
return err
}
m.Result = outb.Bytes()
return nil
}
// Parse scans result.
func (m *Masscan) Parse() ([]Host, error) {
var hosts []Host
decoder := xml.NewDecoder(bytes.NewReader(m.Result))
for {
t, err := decoder.Token()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if t == nil {
break
}
switch se := t.(type) {
case xml.StartElement:
if se.Name.Local == "host" {
var host Host
err := decoder.DecodeElement(&host, &se)
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
hosts = append(hosts, host)
}
default:
}
}
return hosts, nil
}
func New(SystemPath string) *Masscan {
return &Masscan{
SystemPath: SystemPath,
}
}