diff --git a/modules/checkpoint_topology.go b/modules/checkpoint_topology.go new file mode 100644 index 00000000..e643470f --- /dev/null +++ b/modules/checkpoint_topology.go @@ -0,0 +1,8 @@ +package modules + +import checkpointtopology "github.com/zmap/zgrab2/modules/checkpoint_topology" + +func init() { + checkpointtopology.RegisterModule() + +} diff --git a/modules/checkpoint_topology/scanner.go b/modules/checkpoint_topology/scanner.go new file mode 100644 index 00000000..0dc55b94 --- /dev/null +++ b/modules/checkpoint_topology/scanner.go @@ -0,0 +1,147 @@ +package checkpointtopology + +import ( + "bytes" + "encoding/hex" + "fmt" + "log" + "regexp" + + "github.com/zmap/zgrab2" +) + +type Flags struct { + zgrab2.BaseFlags + Hex bool `short:"x" long:"hex" description:"Оutputs as a byte sequence or conversion to a string"` +} + +// Module is the implementation of the zgrab2.Module interface. +type Module struct { +} + +// Scanner is the implementation of the zgrab2.Scanner interface. +type Scanner struct { + config *Flags +} + +// GetName returns the configured name for the Scanner. +func (s *Scanner) GetName() string { + return s.config.Name +} + +// GetTrigger returns the Trigger defined in the Flags. +func (s *Scanner) GetTrigger() string { + return s.config.Trigger +} + +// Init initializes the Scanner instance with the flags from the command +// line. +func (s *Scanner) Init(flags zgrab2.ScanFlags) error { + f, _ := flags.(*Flags) + s.config = f + return nil +} + +// InitPerSender does nothing in this module. +func (s *Scanner) InitPerSender(senderID int) error { + return nil +} + +// Protocol returns the protocol identifer for the scanner. +func (s *Scanner) Protocol() string { + return "checkpoint_topology" +} + +// Help returns this module's help string. +func (f *Flags) Help() string { + return "" +} + +// Validate flags +func (f *Flags) Validate(args []string) (err error) { + return nil +} + +// RegisterModule registers this module in zgrab2 +func RegisterModule() { + var module Module + _, err := zgrab2.AddCommand("checkpoint_topology", "checkpoint_topology", module.Description(), 264, &module) + if err != nil { + log.Fatal(err) + } +} + +func (m *Module) Description() string { + return "Сollect information on checkpoint_topology" +} + +// NewFlags returns the default flags object to be filled in with the +// command-line arguments. +func (m *Module) NewFlags() interface{} { + return new(Flags) +} + +// NewScanner returns a new Scanner instance. +func (m *Module) NewScanner() zgrab2.Scanner { + return new(Scanner) +} + +type StartControlConnectionReply struct { + FirewallHost string + SmartCenterHost string + Banner string +} + +// Reading the response and filling in the structure +func (scanner *Scanner) readReply(data []byte) *StartControlConnectionReply { + + re, _ := regexp.Compile("CN=(.+),O=(.+)\u0000") + res := re.FindAllStringSubmatch(string(data), 2) + + reply := &StartControlConnectionReply{} + if len(res) > 0 { + if len(res[0]) > 1 { + reply.FirewallHost = res[0][1] + } + if len(res[0]) > 2 { + reply.SmartCenterHost = res[0][2] + } + } + + if scanner.config.Hex { + reply.Banner = hex.EncodeToString(data) + } else { + reply.Banner = string(data) + } + + return reply +} + +func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (status zgrab2.ScanStatus, result interface{}, thrown error) { + + conn, err := target.Open(&scanner.config.BaseFlags) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, fmt.Errorf("error opening connection: %w", err) + } + defer conn.Close() + + conn.Write([]byte("\x51\x00\x00\x00\x00\x00\x00\x21")) + + data, err := zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + + if !bytes.Equal(data, []byte("Y\x00\x00\x00")) { + return zgrab2.SCAN_UNKNOWN_ERROR, nil, fmt.Errorf("banner not equal") + } + + conn.Write([]byte("\x00\x00\x00\x0bsecuremote\x00")) + data, err = zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + reply := scanner.readReply(data) + + return zgrab2.SCAN_SUCCESS, reply, nil +} diff --git a/modules/dahua_dvr.go b/modules/dahua_dvr.go new file mode 100644 index 00000000..512204e7 --- /dev/null +++ b/modules/dahua_dvr.go @@ -0,0 +1,7 @@ +package modules + +import "github.com/zmap/zgrab2/modules/dahua_dvr" + +func init() { + dahua_dvr.RegisterModule() +} diff --git a/modules/dahua_dvr/scanner.go b/modules/dahua_dvr/scanner.go new file mode 100644 index 00000000..d579fad5 --- /dev/null +++ b/modules/dahua_dvr/scanner.go @@ -0,0 +1,159 @@ +package dahua_dvr + +import ( + "bytes" + "encoding/hex" + "fmt" + "log" + "os" + "regexp" + + "github.com/zmap/zgrab2" +) + +type Flags struct { + zgrab2.BaseFlags + Hex bool `short:"x" long:"hex" description:"Оutputs as a byte sequence or conversion to a string"` +} + +// Module is the implementation of the zgrab2.Module interface. +type Module struct { +} + +// Scanner is the implementation of the zgrab2.Scanner interface. +type Scanner struct { + config *Flags +} + +// GetName returns the configured name for the Scanner. +func (s *Scanner) GetName() string { + return s.config.Name +} + +// GetTrigger returns the Trigger defined in the Flags. +func (s *Scanner) GetTrigger() string { + return s.config.Trigger +} + +// Init initializes the Scanner instance with the flags from the command +// line. +func (s *Scanner) Init(flags zgrab2.ScanFlags) error { + f, _ := flags.(*Flags) + s.config = f + return nil +} + +// InitPerSender does nothing in this module. +func (s *Scanner) InitPerSender(senderID int) error { + return nil +} + +// Protocol returns the protocol identifer for the scanner. +func (s *Scanner) Protocol() string { + return "dahua_dvr" +} + +// Help returns this module's help string. +func (f *Flags) Help() string { + return "" +} + +// Validate flags +func (f *Flags) Validate(args []string) (err error) { + return nil +} + +// RegisterModule registers the ftp zgrab2 module. +func RegisterModule() { + var module Module + _, err := zgrab2.AddCommand("dahua_dvr", "Dahua DVR", module.Description(), 37777, &module) + if err != nil { + log.Fatal(err) + } +} + +func (m *Module) Description() string { + return "Сollect information on Dahua DVR" +} + +// NewFlags returns the default flags object to be filled in with the +// command-line arguments. +func (m *Module) NewFlags() interface{} { + return new(Flags) +} + +// NewScanner returns a new Scanner instance. +func (m *Module) NewScanner() zgrab2.Scanner { + return new(Scanner) +} + +type ConnectionReply struct { + /* Start [32]byte + Model string //16 + Middle [32]byte + FirmwareVersion string // 16 + End [32]byte + SerialNumber string // 16 */ + Model string + FirmwareVersion string + SerialNumber string + Length int + Banner string +} + +func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (status zgrab2.ScanStatus, result interface{}, thrown error) { + + conn, err := target.Open(&scanner.config.BaseFlags) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, fmt.Errorf("error opening connection: %w", err) + } + defer conn.Close() + + request, err := hex.DecodeString("a4000000000000000b0000000000000000000000000000000000000000000000") + if err != nil { + fmt.Printf("Failed to encode request: %v\n", err) + os.Exit(1) + } + conn.Write(request) + data, err := zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + if !(bytes.Equal(data[:3], []byte{0xb4, 0x00, 0x00}) && data[8] == byte(0x0b)) { + return zgrab2.SCAN_UNKNOWN_ERROR, nil, fmt.Errorf("its not a dahua dvr") + } + + re, _ := regexp.Compile(`[A-Za-z\d-\./\(\)]{2,20}`) + reply := &ConnectionReply{ + Model: re.FindString(string(data)), + Banner: string(data), + } + + request, err = hex.DecodeString("a400000000000000080000000000000000000000000000000000000000000000") + if err != nil { + fmt.Printf("Failed to encode request: %v\n", err) + os.Exit(1) + } + conn.Write(request) + data, err = zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + reply.FirmwareVersion = re.FindString(string(data)) + reply.Banner = reply.Banner + string(data) + + request, err = hex.DecodeString("a400000000000000070000000000000000000000000000000000000000000000") + if err != nil { + fmt.Printf("Failed to encode request: %v\n", err) + os.Exit(1) + } + conn.Write(request) + data, err = zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + reply.SerialNumber = re.FindString(string(data)) + reply.Banner = reply.Banner + string(data) + + return zgrab2.SCAN_SUCCESS, reply, nil +} diff --git a/modules/mikrotik_bw.go b/modules/mikrotik_bw.go new file mode 100644 index 00000000..9687648b --- /dev/null +++ b/modules/mikrotik_bw.go @@ -0,0 +1,7 @@ +package modules + +import "github.com/zmap/zgrab2/modules/mikrotik_bw" + +func init() { + mikrotik_bw.RegisterModule() +} diff --git a/modules/mikrotik_bw/scanner.go b/modules/mikrotik_bw/scanner.go new file mode 100644 index 00000000..1f0d2363 --- /dev/null +++ b/modules/mikrotik_bw/scanner.go @@ -0,0 +1,130 @@ +package mikrotik_bw + +import ( + "bytes" + "encoding/hex" + "fmt" + "log" + + "github.com/zmap/zgrab2" +) + +type Flags struct { + zgrab2.BaseFlags + Hex bool `short:"x" long:"hex" description:"Оutputs as a byte sequence or conversion to a string"` +} + +// Module is the implementation of the zgrab2.Module interface. +type Module struct { +} + +// Scanner is the implementation of the zgrab2.Scanner interface. +type Scanner struct { + config *Flags +} + +// GetName returns the configured name for the Scanner. +func (s *Scanner) GetName() string { + return s.config.Name +} + +// GetTrigger returns the Trigger defined in the Flags. +func (s *Scanner) GetTrigger() string { + return s.config.Trigger +} + +// Init initializes the Scanner instance with the flags from the command +// line. +func (s *Scanner) Init(flags zgrab2.ScanFlags) error { + f, _ := flags.(*Flags) + s.config = f + return nil +} + +// InitPerSender does nothing in this module. +func (s *Scanner) InitPerSender(senderID int) error { + return nil +} + +// Protocol returns the protocol identifer for the scanner. +func (s *Scanner) Protocol() string { + return "mikrotik_bw" +} + +// Help returns this module's help string. +func (f *Flags) Help() string { + return "" +} + +// Validate flags +func (f *Flags) Validate(args []string) (err error) { + return nil +} + +// RegisterModule registers this module in zgrab2 +func RegisterModule() { + var module Module + _, err := zgrab2.AddCommand("mikrotik_bw", "mikrotik_bw", module.Description(), 2000, &module) + if err != nil { + log.Fatal(err) + } +} + +func (m *Module) Description() string { + return "Сollect information on mikrotik_bw" +} + +// NewFlags returns the default flags object to be filled in with the +// command-line arguments. +func (m *Module) NewFlags() interface{} { + return new(Flags) +} + +// NewScanner returns a new Scanner instance. +func (m *Module) NewScanner() zgrab2.Scanner { + return new(Scanner) +} + +type StartControlConnectionReply struct { + Vendor string + Banner string +} + +// Reading the response and filling in the structure +func (scanner *Scanner) readReply(data []byte) *StartControlConnectionReply { + + reply := &StartControlConnectionReply{} + + if scanner.config.Hex { + reply.Banner = hex.EncodeToString(data) + } else { + reply.Banner = string(data) + } + if bytes.Equal(data, []byte("\x01\x00\x00\x00")) { + reply.Vendor = "Mikrotik RouterOS" + } + + return reply +} + +func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (status zgrab2.ScanStatus, result interface{}, thrown error) { + + conn, err := target.Open(&scanner.config.BaseFlags) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, fmt.Errorf("error opening connection: %w", err) + } + defer conn.Close() + + conn.Write([]byte("")) + + data, err := zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + reply := scanner.readReply(data) + if reply.Vendor == "" { + return zgrab2.SCAN_UNKNOWN_ERROR, reply, fmt.Errorf("banner not equal") + } + + return zgrab2.SCAN_SUCCESS, reply, nil +} diff --git a/modules/pptp.go b/modules/pptp.go new file mode 100644 index 00000000..eaaf2ddd --- /dev/null +++ b/modules/pptp.go @@ -0,0 +1,9 @@ +package modules + +import ( + "github.com/zmap/zgrab2/modules/pptp" +) + +func init() { + pptp.RegisterModule() +} diff --git a/modules/pptp/input.txt b/modules/pptp/input.txt new file mode 100644 index 00000000..1d354f38 --- /dev/null +++ b/modules/pptp/input.txt @@ -0,0 +1,6 @@ +5.128.122.68 +213.219.205.156 +144.217.253.149 +54.36.174.134 +51.75.145.20 +198.7.62.204 \ No newline at end of file diff --git a/modules/pptp/multiple.ini b/modules/pptp/multiple.ini new file mode 100644 index 00000000..302891e3 --- /dev/null +++ b/modules/pptp/multiple.ini @@ -0,0 +1,4 @@ +[Application Options] +[pptp] +name="pptp" +port=1723 \ No newline at end of file diff --git a/modules/pptp/output.txt b/modules/pptp/output.txt new file mode 100644 index 00000000..3db32703 --- /dev/null +++ b/modules/pptp/output.txt @@ -0,0 +1,6 @@ +{"ip":"213.219.205.156","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":2,"BearerCapabilities":3,"MaxChannels":0,"FirmwareRevision":0,"Hostname":"","Vendor":"Microsoft","Banner":"\u0000\ufffd\u0000\u0001\u001a+\u003cM\u0000\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000\u0000\u0002\u0000\u0000\u0000\u0003\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Microsoft\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"timestamp":"2024-06-14T22:13:15+03:00"}}} +{"ip":"5.128.122.68","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"TP-LINK_SMB_TL-ER604W(UN)","Vendor":"TP-LINK","Banner":"\u0000\ufffd\u0000\u0001\u001a+\u003cM\u0000\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0001TP-LINK_SMB_TL-ER604W(UN)\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TP-LINK\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"timestamp":"2024-06-14T22:13:15+03:00"}}} +{"ip":"54.36.174.134","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux","Banner":"\u0000\ufffd\u0000\u0001\u001a+\u003cM\u0000\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0001local\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000linux\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"timestamp":"2024-06-14T22:13:15+03:00"}}} +{"ip":"144.217.253.149","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux","Banner":"\u0000\ufffd\u0000\u0001\u001a+\u003cM\u0000\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0001local\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000linux\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"timestamp":"2024-06-14T22:13:15+03:00"}}} +{"ip":"198.7.62.204","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux","Banner":"\u0000\ufffd\u0000\u0001\u001a+\u003cM\u0000\u0002\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0001\u0000\u0001local\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000linux\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"},"timestamp":"2024-06-14T22:13:15+03:00"}}} +{"ip":"51.75.145.20","data":{"pptp":{"status":"connection-timeout","protocol":"pptp","timestamp":"2024-06-14T22:13:15+03:00","error":"error opening connection: dial tcp 51.75.145.20:1723: i/o timeout"}}} diff --git a/modules/pptp/output2.txt b/modules/pptp/output2.txt new file mode 100644 index 00000000..c792f28d --- /dev/null +++ b/modules/pptp/output2.txt @@ -0,0 +1,6 @@ +{"ip":"5.128.122.68","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"TP-LINK_SMB_TL-ER604W(UN)","Vendor":"TP-LINK"},"timestamp":"2024-06-14T18:47:26+03:00"}}} +{"ip":"54.36.174.134","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux"},"timestamp":"2024-06-14T18:47:26+03:00"}}} +{"ip":"198.7.62.204","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux"},"timestamp":"2024-06-14T18:47:26+03:00"}}} +{"ip":"144.217.253.149","data":{"pptp":{"status":"success","protocol":"pptp","result":{"Length":156,"MsgType":1,"MagicCookie":439041101,"ControlMessageType":2,"Reserved0":0,"ProtocolVersion":256,"ResultCode":16,"ErrorCode":0,"FramingCapabilities":0,"BearerCapabilities":0,"MaxChannels":1,"FirmwareRevision":1,"Hostname":"local","Vendor":"linux"},"timestamp":"2024-06-14T18:47:26+03:00"}}} +{"ip":"51.75.145.20","data":{"pptp":{"status":"connection-timeout","protocol":"pptp","timestamp":"2024-06-14T18:47:26+03:00","error":"error opening connection: dial tcp 51.75.145.20:1723: i/o timeout"}}} +{"ip":"213.219.205.156","data":{"pptp":{"status":"connection-timeout","protocol":"pptp","timestamp":"2024-06-14T18:47:26+03:00","error":"error opening connection: dial tcp 213.219.205.156:1723: i/o timeout"}}} diff --git a/modules/pptp/scanner.go b/modules/pptp/scanner.go new file mode 100644 index 00000000..f29fb893 --- /dev/null +++ b/modules/pptp/scanner.go @@ -0,0 +1,207 @@ +package pptp + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "fmt" + "log" + "os" + + "github.com/zmap/zgrab2" +) + +type Flags struct { + zgrab2.BaseFlags + Hex bool `short:"x" long:"hex" description:"Оutputs as a byte sequence or conversion to a string"` +} + +// Module is the implementation of the zgrab2.Module interface. +type Module struct { +} + +// Scanner is the implementation of the zgrab2.Scanner interface. +type Scanner struct { + config *Flags +} + +// GetName returns the configured name for the Scanner. +func (s *Scanner) GetName() string { + return s.config.Name +} + +// GetTrigger returns the Trigger defined in the Flags. +func (s *Scanner) GetTrigger() string { + return s.config.Trigger +} + +// Init initializes the Scanner instance with the flags from the command +// line. +func (s *Scanner) Init(flags zgrab2.ScanFlags) error { + f, _ := flags.(*Flags) + s.config = f + return nil +} + +// InitPerSender does nothing in this module. +func (s *Scanner) InitPerSender(senderID int) error { + return nil +} + +// Protocol returns the protocol identifer for the scanner. +func (s *Scanner) Protocol() string { + return "pptp" +} + +// Help returns this module's help string. +func (f *Flags) Help() string { + return "" +} + +// Validate flags +func (f *Flags) Validate(args []string) (err error) { + return nil +} + +// RegisterModule registers the ftp zgrab2 module. +func RegisterModule() { + var module Module + _, err := zgrab2.AddCommand("pptp", "PPTP", module.Description(), 1723, &module) + if err != nil { + log.Fatal(err) + } +} + +func (m *Module) Description() string { + return "Сollect information on PPTP" +} + +// NewFlags returns the default flags object to be filled in with the +// command-line arguments. +func (m *Module) NewFlags() interface{} { + return new(Flags) +} + +// NewScanner returns a new Scanner instance. +func (m *Module) NewScanner() zgrab2.Scanner { + return new(Scanner) +} + +const MAGIC_COOKIE = 0x1A2B3C4D + +type StartControlConnectionRequest struct { + Length uint16 + MsgType uint16 + MagicCookie uint32 + ControlMessageType uint16 + Reserved0 uint16 + ProtocolVersion uint16 + Reserved1 uint16 + FramingCapabilities uint32 + BearerCapabilities uint32 + MaxChannels uint16 + FirmwareRevision uint16 + Hostname [64]byte + Vendor [64]byte +} + +func createStartControlConnectionRequest() *StartControlConnectionRequest { + request := &StartControlConnectionRequest{ + Length: 156, + MsgType: 1, + MagicCookie: MAGIC_COOKIE, + ControlMessageType: 1, + ProtocolVersion: 0x0100, + FramingCapabilities: 0x1, + BearerCapabilities: 0x1, + FirmwareRevision: 0x1, + } + copy(request.Hostname[:], "Client") + copy(request.Vendor[:], "Go") + + return request +} + +type StartControlConnectionReply struct { + Length uint16 + MsgType uint16 + MagicCookie uint32 + ControlMessageType uint16 + Reserved0 uint16 + ProtocolVersion uint16 + ResultCode uint8 + ErrorCode uint8 + FramingCapabilities uint32 + BearerCapabilities uint32 + MaxChannels uint16 + FirmwareRevision uint16 + Hostname string + Vendor string + Banner string +} + +// Reading the response and filling in the structure +func (scanner *Scanner) readReply(data []byte) *StartControlConnectionReply { + + //Clipping the last insignificant zeros in a string + cutLastZero := func(b []byte) []byte { + for i := len(b) - 1; i > 0; i-- { + if b[i] != 0 { + return b[:i+1] + } + } + return make([]byte, 0) + } + + reply := &StartControlConnectionReply{ + Length: binary.BigEndian.Uint16(data[0:2]), + MsgType: binary.BigEndian.Uint16(data[2:4]), + MagicCookie: binary.BigEndian.Uint32(data[4:8]), + ControlMessageType: binary.BigEndian.Uint16(data[8:10]), + ProtocolVersion: binary.BigEndian.Uint16(data[12:14]), + ResultCode: uint8(data[14]) << 4, + ErrorCode: uint8(data[15]) << 4, + FramingCapabilities: binary.BigEndian.Uint32(data[16:20]), + BearerCapabilities: binary.BigEndian.Uint32(data[20:24]), + MaxChannels: binary.BigEndian.Uint16(data[24:26]), + FirmwareRevision: binary.BigEndian.Uint16(data[26:28]), + Hostname: string(cutLastZero(data[28:92])), + Vendor: string(cutLastZero(data[92:156])), + } + + if scanner.config.Hex { + reply.Banner = hex.EncodeToString(data) + } else { + reply.Banner = string(data) + } + + return reply +} + +func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (status zgrab2.ScanStatus, result interface{}, thrown error) { + + conn, err := target.Open(&scanner.config.BaseFlags) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, fmt.Errorf("error opening connection: %w", err) + } + defer conn.Close() + + request := createStartControlConnectionRequest() + var buffer bytes.Buffer + if err := binary.Write(&buffer, binary.BigEndian, request); err != nil { + fmt.Printf("Failed to encode request: %v\n", err) + os.Exit(1) + } + conn.Write(buffer.Bytes()) + + data, err := zgrab2.ReadAvailable(conn) + if err != nil { + return zgrab2.TryGetScanStatus(err), nil, err + } + reply := scanner.readReply(data) + if reply.MagicCookie != MAGIC_COOKIE { + return zgrab2.SCAN_UNKNOWN_ERROR, nil, fmt.Errorf("magic cookie is not equal") + } + + return zgrab2.SCAN_SUCCESS, reply, nil +}