Add scan interval option (#245)
* Add scan interval option * Update tests for scan interval * Handle missing target properly * Update documentation to reflect that durations are not in milliseconds
This commit is contained in:
committed by
GitHub
parent
cb47aef7e4
commit
4aabf47a5d
@@ -118,8 +118,9 @@ If you have [VLC Media Player](http://www.videolan.org/vlc/), you should be able
|
|||||||
|
|
||||||
* **"-t, --targets"**: Set target. Required. Target can be a file (see [instructions on how to format the file](#format-input-file)), an IP, an IP range, a subnetwork, or a combination of those. Example: `--targets="192.168.1.72,192.168.1.74"`
|
* **"-t, --targets"**: Set target. Required. Target can be a file (see [instructions on how to format the file](#format-input-file)), an IP, an IP range, a subnetwork, or a combination of those. Example: `--targets="192.168.1.72,192.168.1.74"`
|
||||||
* **"-p, --ports"**: (Default: `554,5554,8554`) Set custom ports.
|
* **"-p, --ports"**: (Default: `554,5554,8554`) Set custom ports.
|
||||||
* **"-s, --speed"**: (Default: `4`) Set custom nmap discovery presets to improve speed or accuracy. It's recommended to lower it if you are attempting to scan an unstable and slow network, or to increase it if on a very performant and reliable network. You might also want to keep it low to keep your discovery stealthy. See [this for more info on the nmap timing templates](https://nmap.org/book/man-performance.html).
|
* **"-s, --scan-speed"**: (Default: `4`) Set custom nmap discovery presets to improve speed or accuracy. It's recommended to lower it if you are attempting to scan an unstable and slow network, or to increase it if on a very performant and reliable network. You might also want to keep it low to keep your discovery stealthy. See [this for more info on the nmap timing templates](https://nmap.org/book/man-performance.html).
|
||||||
* **"-T, --timeout"**: (Default: `2000`) Set custom timeout value in miliseconds after which an attack attempt without an answer should give up. It's recommended to increase it when attempting to scan unstable and slow networks or to decrease it on very performant and reliable networks.
|
* **"-I, --attack-interval"**: (Default: `0ms`) Set custom interval after which an attack attempt without an answer should give up. It's recommended to increase it when attempting to scan unstable and slow networks or to decrease it on fast and reliable networks.
|
||||||
|
* **"-T, --timeout"**: (Default: `2000ms`) Set custom timeout value after which an attack attempt without an answer should give up. It's recommended to increase it when attempting to scan unstable and slow networks or to decrease it on fast and reliable networks.
|
||||||
* **"-r, --custom-routes"**: (Default: `<CAMERADAR_GOPATH>/dictionaries/routes`) Set custom dictionary path for routes
|
* **"-r, --custom-routes"**: (Default: `<CAMERADAR_GOPATH>/dictionaries/routes`) Set custom dictionary path for routes
|
||||||
* **"-c, --custom-credentials"**: (Default: `<CAMERADAR_GOPATH>/dictionaries/credentials.json`) Set custom dictionary path for credentials
|
* **"-c, --custom-credentials"**: (Default: `<CAMERADAR_GOPATH>/dictionaries/credentials.json`) Set custom dictionary path for credentials
|
||||||
* **"-o, --nmap-output"**: (Default: `/tmp/cameradar_scan.xml`) Set custom nmap output path
|
* **"-o, --nmap-output"**: (Default: `/tmp/cameradar_scan.xml`) Set custom nmap output path
|
||||||
@@ -175,17 +176,23 @@ These variables are optional, allowing to replace the default dictionaries with
|
|||||||
|
|
||||||
Default values: `<CAMERADAR_GOPATH>/dictionaries/routes` and `<CAMERADAR_GOPATH>/dictionaries/credentials.json`
|
Default values: `<CAMERADAR_GOPATH>/dictionaries/routes` and `<CAMERADAR_GOPATH>/dictionaries/credentials.json`
|
||||||
|
|
||||||
### `CAMERADAR_SPEED`
|
### `CAMERADAR_SCAN_SPEED`
|
||||||
|
|
||||||
This optional variable allows you to set custom nmap discovery presets to improve speed or accuracy. It's recommended to lower it if you are attempting to scan an unstable and slow network, or to increase it if on a very performant and reliable network. See [this for more info on the nmap timing templates](https://nmap.org/book/man-performance.html).
|
This optional variable allows you to set custom nmap discovery presets to improve speed or accuracy. It's recommended to lower it if you are attempting to scan an unstable and slow network, or to increase it if on a fast and reliable network. See [this for more info on the nmap timing templates](https://nmap.org/book/man-performance.html).
|
||||||
|
|
||||||
Default value: `4`
|
Default value: `4`
|
||||||
|
|
||||||
|
### `CAMERADAR_ATTACK_INTERVAL`
|
||||||
|
|
||||||
|
This optional variable allows you to set custom interval to wait between each attack in order to stay stealthy. It's recommended to increase it when attempting to scan a network that might be protected against bruteforce attacks. By default, there is no interval, in order to make attacks as fast as possible
|
||||||
|
|
||||||
|
Default value: `0ms`
|
||||||
|
|
||||||
### `CAMERADAR_TIMEOUT`
|
### `CAMERADAR_TIMEOUT`
|
||||||
|
|
||||||
This optional variable allows you to set custom timeout value in miliseconds after which an attack attempt without an answer should give up. It's recommended to increase it when attempting to scan unstable and slow networks or to decrease it on very performant and reliable networks.
|
This optional variable allows you to set custom timeout value after which an attack attempt without an answer should give up. It's recommended to increase it when attempting to scan unstable and slow networks or to decrease it on fast and reliable networks.
|
||||||
|
|
||||||
Default value: `2000`
|
Default value: `2000ms`
|
||||||
|
|
||||||
### `CAMERADAR_LOGGING`
|
### `CAMERADAR_LOGGING`
|
||||||
|
|
||||||
@@ -231,7 +238,7 @@ Maybe your cameras have been configured and the credentials / URL have been chan
|
|||||||
|
|
||||||
> What happened to the C++ version?
|
> What happened to the C++ version?
|
||||||
|
|
||||||
You can still find it under the 1.1.4 tag on this repo, however it was less performant and stable than the current version written in Golang. It is not recommended to use it.
|
You can still find it under the 1.1.4 tag on this repo, however it was slower and less stable than the current version written in Golang. It is not recommended to use it.
|
||||||
|
|
||||||
> How to use the Cameradar library for my own project?
|
> How to use the Cameradar library for my own project?
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ func (s *Scanner) Attack(targets []Stream) ([]Stream, error) {
|
|||||||
func (s *Scanner) ValidateStreams(targets []Stream) []Stream {
|
func (s *Scanner) ValidateStreams(targets []Stream) []Stream {
|
||||||
for i := range targets {
|
for i := range targets {
|
||||||
targets[i].Available = s.validateStream(targets[i])
|
targets[i].Available = s.validateStream(targets[i])
|
||||||
|
time.Sleep(s.attackInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
return targets
|
return targets
|
||||||
@@ -78,6 +79,7 @@ func (s *Scanner) AttackCredentials(targets []Stream) []Stream {
|
|||||||
// TODO: Perf Improvement: Skip cameras with no auth type detected, and set their
|
// TODO: Perf Improvement: Skip cameras with no auth type detected, and set their
|
||||||
// CredentialsFound value to true.
|
// CredentialsFound value to true.
|
||||||
go s.attackCameraCredentials(targets[i], resChan)
|
go s.attackCameraCredentials(targets[i], resChan)
|
||||||
|
time.Sleep(s.attackInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
attackResults := []Stream{}
|
attackResults := []Stream{}
|
||||||
@@ -103,6 +105,7 @@ func (s *Scanner) AttackRoute(targets []Stream) []Stream {
|
|||||||
|
|
||||||
for i := range targets {
|
for i := range targets {
|
||||||
go s.attackCameraRoute(targets[i], resChan)
|
go s.attackCameraRoute(targets[i], resChan)
|
||||||
|
time.Sleep(s.attackInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
attackResults := []Stream{}
|
attackResults := []Stream{}
|
||||||
@@ -125,6 +128,7 @@ func (s *Scanner) AttackRoute(targets []Stream) []Stream {
|
|||||||
func (s *Scanner) DetectAuthMethods(targets []Stream) []Stream {
|
func (s *Scanner) DetectAuthMethods(targets []Stream) []Stream {
|
||||||
for i := range targets {
|
for i := range targets {
|
||||||
targets[i].AuthenticationType = s.detectAuthMethod(targets[i])
|
targets[i].AuthenticationType = s.detectAuthMethod(targets[i])
|
||||||
|
time.Sleep(s.attackInterval)
|
||||||
|
|
||||||
var authMethod string
|
var authMethod string
|
||||||
switch targets[i].AuthenticationType {
|
switch targets[i].AuthenticationType {
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ func parseArguments() error {
|
|||||||
|
|
||||||
pflag.StringSliceP("targets", "t", []string{}, "The targets on which to scan for open RTSP streams - required (ex: 172.16.100.0/24)")
|
pflag.StringSliceP("targets", "t", []string{}, "The targets on which to scan for open RTSP streams - required (ex: 172.16.100.0/24)")
|
||||||
pflag.StringSliceP("ports", "p", []string{"554", "5554", "8554"}, "The ports on which to search for RTSP streams")
|
pflag.StringSliceP("ports", "p", []string{"554", "5554", "8554"}, "The ports on which to search for RTSP streams")
|
||||||
pflag.IntP("speed", "s", 4, "The nmap speed preset to use for discovery")
|
|
||||||
pflag.DurationP("timeout", "T", 2*time.Second, "The timeout in miliseconds to use for attack attempts")
|
|
||||||
pflag.StringP("custom-routes", "r", "${GOPATH}/src/github.com/Ullaakut/cameradar/dictionaries/routes", "The path on which to load a custom routes dictionary")
|
pflag.StringP("custom-routes", "r", "${GOPATH}/src/github.com/Ullaakut/cameradar/dictionaries/routes", "The path on which to load a custom routes dictionary")
|
||||||
pflag.StringP("custom-credentials", "c", "${GOPATH}/src/github.com/Ullaakut/cameradar/dictionaries/credentials.json", "The path on which to load a custom credentials JSON dictionary")
|
pflag.StringP("custom-credentials", "c", "${GOPATH}/src/github.com/Ullaakut/cameradar/dictionaries/credentials.json", "The path on which to load a custom credentials JSON dictionary")
|
||||||
|
pflag.IntP("scan-speed", "s", 4, "The nmap speed preset to use for scanning (lower is stealthier)")
|
||||||
|
pflag.DurationP("attack-interval", "I", 0, "The interval between each attack (i.e: 2000ms, higher is stealthier)")
|
||||||
|
pflag.DurationP("timeout", "T", 2000*time.Millisecond, "The timeout to use for attack attempts (i.e: 2000ms)")
|
||||||
pflag.BoolP("debug", "d", true, "Enable the debug logs")
|
pflag.BoolP("debug", "d", true, "Enable the debug logs")
|
||||||
pflag.BoolP("verbose", "v", false, "Enable the verbose logs")
|
pflag.BoolP("verbose", "v", false, "Enable the verbose logs")
|
||||||
pflag.BoolP("help", "h", false, "displays this help message")
|
pflag.BoolP("help", "h", false, "displays this help message")
|
||||||
@@ -43,10 +44,12 @@ func parseArguments() error {
|
|||||||
fmt.Println("\tScanning your home network for RTSP streams:\tcameradar -t 192.168.0.0/24")
|
fmt.Println("\tScanning your home network for RTSP streams:\tcameradar -t 192.168.0.0/24")
|
||||||
fmt.Println("\tScanning a remote camera on a specific port:\tcameradar -t 172.178.10.14 -p 18554 -s 2")
|
fmt.Println("\tScanning a remote camera on a specific port:\tcameradar -t 172.178.10.14 -p 18554 -s 2")
|
||||||
fmt.Println("\tScanning an unstable remote network: \t\tcameradar -t 172.178.10.14/24 -s 1 --timeout 10000 -l")
|
fmt.Println("\tScanning an unstable remote network: \t\tcameradar -t 172.178.10.14/24 -s 1 --timeout 10000 -l")
|
||||||
|
fmt.Println("\tStealthily scanning a remote network: \t\tcameradar -t 172.178.10.14/24 -s 1 -I 5000")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if viper.GetStringSlice("targets") == nil {
|
if len(viper.GetStringSlice("targets")) == 0 {
|
||||||
|
pflag.Usage()
|
||||||
return errors.New("targets (-t, --targets) argument required\n examples:\n - 172.16.100.0/24\n - localhost\n - 8.8.8.8")
|
return errors.New("targets (-t, --targets) argument required\n examples:\n - 172.16.100.0/24\n - localhost\n - 8.8.8.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +69,8 @@ func main() {
|
|||||||
cameradar.WithVerbose(viper.GetBool("verbose")),
|
cameradar.WithVerbose(viper.GetBool("verbose")),
|
||||||
cameradar.WithCustomCredentials(viper.GetString("custom-credentials")),
|
cameradar.WithCustomCredentials(viper.GetString("custom-credentials")),
|
||||||
cameradar.WithCustomRoutes(viper.GetString("custom-routes")),
|
cameradar.WithCustomRoutes(viper.GetString("custom-routes")),
|
||||||
cameradar.WithSpeed(viper.GetInt("speed")),
|
cameradar.WithScanSpeed(viper.GetInt("scan-speed")),
|
||||||
|
cameradar.WithAttackInterval(viper.GetDuration("attack-interval")),
|
||||||
cameradar.WithTimeout(viper.GetDuration("timeout")),
|
cameradar.WithTimeout(viper.GetDuration("timeout")),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (s *Scanner) Scan() ([]Stream, error) {
|
|||||||
nmapScanner, err := nmap.NewScanner(
|
nmapScanner, err := nmap.NewScanner(
|
||||||
nmap.WithTargets(s.targets...),
|
nmap.WithTargets(s.targets...),
|
||||||
nmap.WithPorts(s.ports...),
|
nmap.WithPorts(s.ports...),
|
||||||
nmap.WithTimingTemplate(nmap.Timing(s.speed)),
|
nmap.WithTimingTemplate(nmap.Timing(s.scanSpeed)),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, s.term.FailStepf("unable to create network scanner: %v", err)
|
return nil, s.term.FailStepf("unable to create network scanner: %v", err)
|
||||||
|
|||||||
+4
-4
@@ -88,10 +88,10 @@ func TestScan(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanner := &Scanner{
|
scanner := &Scanner{
|
||||||
term: disgo.NewTerminal(disgo.WithDefaultOutput(ioutil.Discard)),
|
term: disgo.NewTerminal(disgo.WithDefaultOutput(ioutil.Discard)),
|
||||||
targets: test.targets,
|
targets: test.targets,
|
||||||
ports: test.ports,
|
ports: test.ports,
|
||||||
speed: test.speed,
|
scanSpeed: test.speed,
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := scanner.Scan()
|
result, err := scanner.Scan()
|
||||||
|
|||||||
+14
-4
@@ -25,7 +25,8 @@ type Scanner struct {
|
|||||||
ports []string
|
ports []string
|
||||||
debug bool
|
debug bool
|
||||||
verbose bool
|
verbose bool
|
||||||
speed int
|
scanSpeed int
|
||||||
|
attackInterval time.Duration
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
credentialDictionaryPath string
|
credentialDictionaryPath string
|
||||||
routeDictionaryPath string
|
routeDictionaryPath string
|
||||||
@@ -134,11 +135,20 @@ func WithCustomRoutes(dictionaryPath string) func(s *Scanner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSpeed specifies the speed at which the scan should be executed. Faster
|
// WithScanSpeed specifies the speed at which the scan should be executed. Faster
|
||||||
// means easier to detect, slower has bigger timeout values and is more silent.
|
// means easier to detect, slower has bigger timeout values and is more silent.
|
||||||
func WithSpeed(speed int) func(s *Scanner) {
|
func WithScanSpeed(speed int) func(s *Scanner) {
|
||||||
return func(s *Scanner) {
|
return func(s *Scanner) {
|
||||||
s.speed = speed
|
s.scanSpeed = speed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAttackInterval specifies the interval of time during which Cameradar
|
||||||
|
// should wait between each attack attempt during bruteforcing.
|
||||||
|
// Setting a high value for this obviously makes attacks much slower.
|
||||||
|
func WithAttackInterval(interval time.Duration) func(s *Scanner) {
|
||||||
|
return func(s *Scanner) {
|
||||||
|
s.attackInterval = interval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -22,6 +22,7 @@ func TestNew(t *testing.T) {
|
|||||||
customCredentials string
|
customCredentials string
|
||||||
customRoutes string
|
customRoutes string
|
||||||
speed int
|
speed int
|
||||||
|
attackInterval time.Duration
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
|
||||||
loadTargetsFail bool
|
loadTargetsFail bool
|
||||||
@@ -118,7 +119,8 @@ func TestNew(t *testing.T) {
|
|||||||
WithPorts(test.ports),
|
WithPorts(test.ports),
|
||||||
WithDebug(test.debug),
|
WithDebug(test.debug),
|
||||||
WithVerbose(test.verbose),
|
WithVerbose(test.verbose),
|
||||||
WithSpeed(test.speed),
|
WithScanSpeed(test.speed),
|
||||||
|
WithAttackInterval(test.attackInterval),
|
||||||
WithTimeout(test.timeout),
|
WithTimeout(test.timeout),
|
||||||
WithCustomCredentials(test.customCredentials),
|
WithCustomCredentials(test.customCredentials),
|
||||||
WithCustomRoutes(test.customRoutes),
|
WithCustomRoutes(test.customRoutes),
|
||||||
@@ -135,7 +137,8 @@ func TestNew(t *testing.T) {
|
|||||||
assert.Equal(t, test.ports, scanner.ports)
|
assert.Equal(t, test.ports, scanner.ports)
|
||||||
assert.Equal(t, test.debug, scanner.debug)
|
assert.Equal(t, test.debug, scanner.debug)
|
||||||
assert.Equal(t, test.verbose, scanner.verbose)
|
assert.Equal(t, test.verbose, scanner.verbose)
|
||||||
assert.Equal(t, test.speed, scanner.speed)
|
assert.Equal(t, test.speed, scanner.scanSpeed)
|
||||||
|
assert.Equal(t, test.attackInterval, scanner.attackInterval)
|
||||||
assert.Equal(t, test.timeout, scanner.timeout)
|
assert.Equal(t, test.timeout, scanner.timeout)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user