diff --git a/attack.go b/attack.go index 4934e9d..2c8780d 100644 --- a/attack.go +++ b/attack.go @@ -162,7 +162,7 @@ func attackCameraRoute(target Stream, routes Routes, resultsChan chan<- Stream, } // AttackCredentials attempts to guess the provided targets' credentials using the given -// dictionary or the default dictionary if none was provided by the user +// dictionary or the default dictionary if none was provided by the user. func AttackCredentials(targets []Stream, credentials Credentials, timeout time.Duration, log bool) (results []Stream, err error) { attacks := make(chan Stream) defer close(attacks) @@ -197,7 +197,7 @@ func AttackCredentials(targets []Stream, credentials Credentials, timeout time.D } // AttackRoute attempts to guess the provided targets' streaming routes using the given -// dictionary or the default dictionary if none was provided by the user +// dictionary or the default dictionary if none was provided by the user. func AttackRoute(targets []Stream, routes Routes, timeout time.Duration, log bool) (results []Stream, err error) { attacks := make(chan Stream) defer close(attacks) diff --git a/cameraccess/cameraccess b/cameraccess/cameraccess new file mode 100755 index 0000000..d64ccdd Binary files /dev/null and b/cameraccess/cameraccess differ diff --git a/cameraccess/main.go b/cameraccess/main.go index 05384fc..7a76904 100644 --- a/cameraccess/main.go +++ b/cameraccess/main.go @@ -67,8 +67,6 @@ func main() { } } - streams, _ = cmrdr.AttackRoute(streams, routes, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs) - prettyPrint(streams) } @@ -84,10 +82,10 @@ func prettyPrint(streams []cmrdr.Stream) { if len(streams) > 0 { for _, stream := range streams { if stream.CredentialsFound && stream.RouteFound { - fmt.Printf("%s\tDevice RTSP URL:\t%s\n", green("\xE2\x96\xB6"), blue(cmrdr.RTSPURL(stream))) + fmt.Printf("%s\tDevice RTSP URL:\t%s\n", green("\xE2\x96\xB6"), blue(cmrdr.GetCameraRTSPURL(stream))) success++ } else { - fmt.Printf("%s\tAdmin panel URL:\t%s %s\n", red("\xE2\x96\xB6"), yellow(cmrdr.AdminPanelURL(stream)), white("You can use this URL to try attacking the camera's admin panel instead.")) + fmt.Printf("%s\tAdmin panel URL:\t%s %s\n", red("\xE2\x96\xB6"), yellow(cmrdr.GetCameraAdminPanelURL(stream)), white("You can use this URL to try attacking the camera's admin panel instead.")) } fmt.Printf("\tDevice model:\t\t%s\n\n", stream.Device) diff --git a/discover.go b/discover.go index 5b79faf..914c64c 100644 --- a/discover.go +++ b/discover.go @@ -41,8 +41,8 @@ const ( INSANE = 5 ) -// RunNmap runs nmap on the specified targets's specified ports, using the given nmap speed -func RunNmap(targets, ports string, resultFilePath string, nmapSpeed int, enableLogs bool) error { +// NmapRun runs nmap on the specified targets's specified ports, using the given nmap speed. +func NmapRun(targets, ports, resultFilePath string, nmapSpeed int, enableLogs bool) error { // Prepare nmap command cmd := exec.Command( "nmap", @@ -82,9 +82,9 @@ func RunNmap(targets, ports string, resultFilePath string, nmapSpeed int, enable return nil } -// ParseNmapResult returns a slice of streams from an NMap XML result file -// To generate one yourself, use the -X option when running NMap -func ParseNmapResult(nmapResultFilePath string) ([]Stream, error) { +// NmapParseResults returns a slice of streams from an NMap XML result file. +// To generate one yourself, use the -X option when running NMap. +func NmapParseResults(nmapResultFilePath string) ([]Stream, error) { var streams []Stream // Open & Read XML file @@ -94,7 +94,7 @@ func ParseNmapResult(nmapResultFilePath string) ([]Stream, error) { } // Unmarshal content of XML file into data structure - result := &NmapResult{} + result := &nmapResult{} err = xml.Unmarshal(content, &result) if err != nil { return streams, err @@ -124,26 +124,29 @@ func ParseNmapResult(nmapResultFilePath string) ([]Stream, error) { return streams, nil } -// Discover scans the target networks and tries to find RTSP streams within them -// targets - string: The addresses +// Discover scans the target networks and tries to find RTSP streams within them. +// +// targets can be: +// // - a subnet (e.g.: 172.16.100.0/24) // - an IP (e.g.: 172.16.100.10) // - a hostname (e.g.: localhost) -// - a range of IPs (e.g.: 172.16.100.10-172.16.100.20) -// - a mix of all those separated by commas (e.g.: localhost,172.17.100.0/24,172.16.100.10-172.16.100.20,0.0.0.0). -// ports - string : +// - a range of IPs (e.g.: 172.16.100.10-20) +// +// ports can be: +// // - one or multiple ports and port ranges separated by commas (e.g.: 554,8554-8560,18554-28554) -func Discover(targets string, ports string, nmapResultPath string, speed int, log bool) ([]Stream, error) { +func Discover(targets, ports, nmapResultPath string, speed int, log bool) ([]Stream, error) { var streams []Stream // Run nmap command to discover open ports on the specified targets & ports - err := RunNmap(targets, ports, nmapResultPath, speed, log) + err := NmapRun(targets, ports, nmapResultPath, speed, log) if err != nil { return streams, err } // Get found streams from nmap results - streams, err = ParseNmapResult(nmapResultPath) + streams, err = NmapParseResults(nmapResultPath) if err != nil { return streams, err } diff --git a/helpers.go b/helpers.go index 1af81c0..a55e148 100644 --- a/helpers.go +++ b/helpers.go @@ -27,12 +27,12 @@ func replace(streams []Stream, new Stream) []Stream { return updatedSlice } -// RTSPURL generates a stream's RTSP URL -func RTSPURL(stream Stream) string { +// GetCameraRTSPURL generates a stream's RTSP URL +func GetCameraRTSPURL(stream Stream) string { return "rtsp://" + stream.Username + ":" + stream.Password + "@" + stream.Address + ":" + fmt.Sprint(stream.Port) + "/" + stream.Route } -// AdminPanelURL returns the URL to the camera's admin panel -func AdminPanelURL(stream Stream) string { +// GetCameraAdminPanelURL returns the URL to the camera's admin panel +func GetCameraAdminPanelURL(stream Stream) string { return "http://" + stream.Address + "/" } diff --git a/xml_models.go b/xml_models.go index d3d25a5..fbe6ad8 100644 --- a/xml_models.go +++ b/xml_models.go @@ -15,47 +15,47 @@ package cmrdr import "encoding/xml" // NmapResult is the structure that holds all the information from an NMap scan -type NmapResult struct { +type nmapResult struct { XMLName xml.Name `xml:"nmaprun"` - Hosts []Host `xml:"host" validate:"required"` + Hosts []host `xml:"host" validate:"required"` } // Host represents a host discovered during a scan -type Host struct { +type host struct { XMLName xml.Name `xml:"host"` - Address Address `xml:"address"` - Ports Ports `xml:"ports"` + Address address `xml:"address"` + Ports ports `xml:"ports"` } // Address is a host's address discovered during a scan -type Address struct { +type address struct { XMLName xml.Name `xml:"address"` Addr string `xml:"addr,attr"` AddrType string `xml:"addrType,attr"` } // Ports is the list of openned ports on a host -type Ports struct { +type ports struct { XMLName xml.Name `xml:"ports"` - Ports []Port `xml:"port"` + Ports []port `xml:"port"` } // Port is a port found on a host during a scan -type Port struct { +type port struct { XMLName xml.Name `xml:"port"` PortID uint `xml:"portid,attr"` - State State `xml:"state"` - Service Service `xml:"service"` + State state `xml:"state"` + Service service `xml:"service"` } // State is the state of a port -type State struct { +type state struct { XMLName xml.Name `xml:"state"` State string `xml:"state,attr" validate:"required,eq=open"` } // Service represents the service that a port provides -type Service struct { +type service struct { XMLName xml.Name `xml:"service"` Name string `xml:"name,attr" validate:"required,eq=rtsp"` Product string `xml:"product,attr"`