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:
Brendan Le Glaunec
2019-11-11 21:42:38 +01:00
committed by GitHub
parent cb47aef7e4
commit 4aabf47a5d
7 changed files with 50 additions and 22 deletions
+14 -7
View File
@@ -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"`
* **"-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).
* **"-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.
* **"-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).
* **"-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
* **"-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
@@ -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`
### `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`
### `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`
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`
@@ -231,7 +238,7 @@ Maybe your cameras have been configured and the credentials / URL have been chan
> 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?
+4
View File
@@ -63,6 +63,7 @@ func (s *Scanner) Attack(targets []Stream) ([]Stream, error) {
func (s *Scanner) ValidateStreams(targets []Stream) []Stream {
for i := range targets {
targets[i].Available = s.validateStream(targets[i])
time.Sleep(s.attackInterval)
}
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
// CredentialsFound value to true.
go s.attackCameraCredentials(targets[i], resChan)
time.Sleep(s.attackInterval)
}
attackResults := []Stream{}
@@ -103,6 +105,7 @@ func (s *Scanner) AttackRoute(targets []Stream) []Stream {
for i := range targets {
go s.attackCameraRoute(targets[i], resChan)
time.Sleep(s.attackInterval)
}
attackResults := []Stream{}
@@ -125,6 +128,7 @@ func (s *Scanner) AttackRoute(targets []Stream) []Stream {
func (s *Scanner) DetectAuthMethods(targets []Stream) []Stream {
for i := range targets {
targets[i].AuthenticationType = s.detectAuthMethod(targets[i])
time.Sleep(s.attackInterval)
var authMethod string
switch targets[i].AuthenticationType {
+8 -4
View File
@@ -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("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-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("verbose", "v", false, "Enable the verbose logs")
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 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("\tStealthily scanning a remote network: \t\tcameradar -t 172.178.10.14/24 -s 1 -I 5000")
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")
}
@@ -66,7 +69,8 @@ func main() {
cameradar.WithVerbose(viper.GetBool("verbose")),
cameradar.WithCustomCredentials(viper.GetString("custom-credentials")),
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")),
)
if err != nil {
+1 -1
View File
@@ -25,7 +25,7 @@ func (s *Scanner) Scan() ([]Stream, error) {
nmapScanner, err := nmap.NewScanner(
nmap.WithTargets(s.targets...),
nmap.WithPorts(s.ports...),
nmap.WithTimingTemplate(nmap.Timing(s.speed)),
nmap.WithTimingTemplate(nmap.Timing(s.scanSpeed)),
)
if err != nil {
return nil, s.term.FailStepf("unable to create network scanner: %v", err)
+4 -4
View File
@@ -88,10 +88,10 @@ func TestScan(t *testing.T) {
}
scanner := &Scanner{
term: disgo.NewTerminal(disgo.WithDefaultOutput(ioutil.Discard)),
targets: test.targets,
ports: test.ports,
speed: test.speed,
term: disgo.NewTerminal(disgo.WithDefaultOutput(ioutil.Discard)),
targets: test.targets,
ports: test.ports,
scanSpeed: test.speed,
}
result, err := scanner.Scan()
+14 -4
View File
@@ -25,7 +25,8 @@ type Scanner struct {
ports []string
debug bool
verbose bool
speed int
scanSpeed int
attackInterval time.Duration
timeout time.Duration
credentialDictionaryPath 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.
func WithSpeed(speed int) func(s *Scanner) {
func WithScanSpeed(speed int) 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
View File
@@ -22,6 +22,7 @@ func TestNew(t *testing.T) {
customCredentials string
customRoutes string
speed int
attackInterval time.Duration
timeout time.Duration
loadTargetsFail bool
@@ -118,7 +119,8 @@ func TestNew(t *testing.T) {
WithPorts(test.ports),
WithDebug(test.debug),
WithVerbose(test.verbose),
WithSpeed(test.speed),
WithScanSpeed(test.speed),
WithAttackInterval(test.attackInterval),
WithTimeout(test.timeout),
WithCustomCredentials(test.customCredentials),
WithCustomRoutes(test.customRoutes),
@@ -135,7 +137,8 @@ func TestNew(t *testing.T) {
assert.Equal(t, test.ports, scanner.ports)
assert.Equal(t, test.debug, scanner.debug)
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)
}
})