Add environment variables support

This commit is contained in:
Ishan Jain
2017-10-27 06:56:36 +05:30
committed by Brendan Le Glaunec
parent 6d296b84d5
commit df44c7d6f1
6 changed files with 217 additions and 28 deletions
+54
View File
@@ -152,6 +152,60 @@ With the above result, the RTSP URL would be `rtsp://admin:12345@173.16.100.45:5
* **"-l, --log"**: Enable debug logs (nmap requests, curl describe requests, etc.)
* **"-h"** : Display the usage information
## Environment Variables
### `CAMERADAR_TARGET`
This variable is mandatory and specifies the target that cameradar should scan and attempt to access RTSP streams on.
Examples:
* `172.16.100.0/24`
* `192.168.1.1`
* `localhost`
### `CAMERADAR_PORTS`
This variable is optional and allows you to specify the ports on which to run the scans.
Default value: `554,8554`
It is recommended not to change these except if you are certain that cameras have been configured to stream RTSP over a different port. 99.9% of cameras are streaming on these ports.
### `CAMERADAR_NMAP_OUTPUT_FILE`
This variable is optional and allows you to specify on which file nmap will write its output.
Default value: `/tmp/cameradar_scan.xml`
This can be useful only if you want to read the files yourself, if you don't want it to write in your `/tmp` folder, or if you want to use only the RunNmap function in cameradar, and do its parsing manually.
### `CAMERADAR_CUSTOM_ROUTES`, `CAMERADAR_CUSTOM_CREDENTIALS`
These variables are optional, allowing to replace the default dictionaries with custom ones, for the dictionary attack.
Default values: `<CAMERADAR_GOPATH>/dictionaries/routes` and `<CAMERADAR_GOPATH>/dictionaries/credentials.json`
### `CAMERADAR_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).
Default value: `4`
### `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.
Default value: `2000`
### `CAMERADAR_LOGS`
This optional variable allows you to enable a more verbose output to have more information about what is going on.
It will output nmap results, cURL requests, etc.
Default: `false`
## Contribution
### Build
+87 -15
View File
@@ -13,6 +13,7 @@
package main
import (
"errors"
"fmt"
"os"
"strings"
@@ -21,29 +22,82 @@ import (
"github.com/EtixLabs/cameradar"
"github.com/gernest/wow"
"github.com/gernest/wow/spin"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/fatih/color"
"github.com/jessevdk/go-flags"
)
type options struct {
Target string `short:"t" long:"target" description:"The target on which to scan for open RTSP streams - required (ex: 172.16.100.0/24)" required:"true"`
Ports string `short:"p" long:"ports" description:"The ports on which to search for RTSP streams" default:"554,8554"`
OutputFile string `short:"o" long:"nmap-output" description:"The path where nmap will create its XML result file" default:"/tmp/cameradar_scan.xml"`
Routes string `short:"r" long:"custom-routes" description:"The path on which to load a custom routes dictionary" default:"<GOPATH>/src/github.com/EtixLabs/cameradar/dictionaries/routes"`
Credentials string `short:"c" long:"custom-credentials" description:"The path on which to load a custom credentials JSON dictionary" default:"<GOPATH>/src/github.com/EtixLabs/cameradar/dictionaries/credentials.json"`
Speed int `short:"s" long:"speed" description:"The nmap speed preset to use" default:"4"`
Timeout int `short:"T" long:"timeout" description:"The timeout in miliseconds to use for attack attempts" default:"2000"`
EnableLogs bool `short:"l" long:"log" description:"Enable the logs for nmap's output to stdout"`
Target string
Ports string
OutputFile string
Routes string
Credentials string
Speed int
Timeout int
EnableLogs bool
}
func parseArguments() error {
viper.BindEnv("target", "CAMERADAR_TARGET")
viper.BindEnv("ports", "CAMERADAR_PORTS")
viper.BindEnv("nmap-output", "CAMERADAR_NMAP_OUTPUT_FILE")
viper.BindEnv("custom-routes", "CAMERADAR_CUSTOM_ROUTES")
viper.BindEnv("custom-credentials", "CAMERADAR_CUSTOM_CREDENTIALS")
viper.BindEnv("speed", "CAMERADAR_SPEED")
viper.BindEnv("timeout", "CAMERADAR_TIMEOUT")
viper.BindEnv("envlogs", "CAMERADAR_LOGS")
pflag.StringP("target", "t", "", "The target on which to scan for open RTSP streams - required (ex: 172.16.100.0/24)")
pflag.StringP("ports", "p", "554,8554", "The ports on which to search for RTSP streams")
pflag.StringP("nmap-output", "o", "/tmp/cameradar_scan.xml", "The path where nmap will create its XML result file")
pflag.StringP("custom-routes", "r", "<GOPATH>/src/github.com/EtixLabs/cameradar/dictionaries/routes", "The path on which to load a custom routes dictionary")
pflag.StringP("custom-credentials", "c", "<GOPATH>/src/github.com/EtixLabs/cameradar/dictionaries/credentials.json", "The path on which to load a custom credentials JSON dictionary")
pflag.IntP("speed", "s", 4, "The nmap speed preset to use")
pflag.IntP("timeout", "T", 2000, "The timeout in miliseconds to use for attack attempts")
pflag.BoolP("log", "l", false, "Enable the logs for nmap's output to stdout")
pflag.BoolP("help", "h", false, "displays this help message")
viper.AutomaticEnv()
pflag.Parse()
err := viper.BindPFlags(pflag.CommandLine)
if err != nil {
return err
}
if viper.GetBool("help") {
pflag.Usage()
os.Exit(0)
}
if viper.GetString("target") == "" {
return errors.New("target (-t, --target) argument required\n examples:\n - 172.16.100.0/24\n - localhost\n - 8.8.8.8")
}
return nil
}
func main() {
var options options
_, err := flags.ParseArgs(&options, os.Args[1:])
err := parseArguments()
if err != nil {
os.Exit(0)
printErr(err)
}
options.Credentials = viper.GetString("custom-credentials")
options.EnableLogs = viper.GetBool("log") || viper.GetBool("envlogs")
options.OutputFile = viper.GetString("nmap-output")
options.Ports = viper.GetString("ports")
options.Routes = viper.GetString("custom-routes")
options.Speed = viper.GetInt("speed")
options.Timeout = viper.GetInt("timeout")
options.Target = viper.GetString("target")
w := startSpinner(options.EnableLogs)
updateSpinner(w, "Loading dictionaries...", options.EnableLogs)
@@ -64,15 +118,24 @@ func main() {
}
updateSpinner(w, "Scanning the network...", options.EnableLogs)
streams, _ := cmrdr.Discover(options.Target, options.Ports, options.OutputFile, options.Speed, options.EnableLogs)
streams, err := cmrdr.Discover(options.Target, options.Ports, options.OutputFile, options.Speed, options.EnableLogs)
if err != nil && len(streams) > 0 {
printErr(err)
}
// Most cameras will be accessed successfully with these two attacks
updateSpinner(w, "Found "+fmt.Sprint(len(streams))+" streams. Attacking their routes...", options.EnableLogs)
streams, _ = cmrdr.AttackRoute(streams, routes, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
streams, err = cmrdr.AttackRoute(streams, routes, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
if err != nil && len(streams) > 0 {
printErr(err)
}
updateSpinner(w, "Found "+fmt.Sprint(len(streams))+" streams. Attacking their credentials...", options.EnableLogs)
streams, _ = cmrdr.AttackCredentials(streams, credentials, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
streams, err = cmrdr.AttackCredentials(streams, credentials, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
if err != nil && len(streams) > 0 {
printErr(err)
}
// But some cameras run GST RTSP Server which prioritizes 401 over 404 contrary to most cameras.
// For these cameras, running another route attack will solve the problem.
@@ -80,7 +143,10 @@ func main() {
if stream.RouteFound == false || stream.CredentialsFound == false {
updateSpinner(w, "Found "+fmt.Sprint(len(streams))+" streams. Final attack...", options.EnableLogs)
streams, _ = cmrdr.AttackRoute(streams, routes, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
streams, err = cmrdr.AttackRoute(streams, routes, time.Duration(options.Timeout)*time.Millisecond, options.EnableLogs)
if err != nil && len(streams) > 0 {
printErr(err)
}
break
}
}
@@ -135,6 +201,12 @@ func prettyPrint(streams []cmrdr.Stream) {
}
}
func printErr(err error) {
red := color.New(color.FgRed, color.Bold).SprintFunc()
fmt.Printf("%s %v\n", red("\xE2\x9C\x96"), err)
os.Exit(1)
}
func updateSpinner(w *wow.Wow, text string, disabled bool) {
if !disabled {
w.Text(" " + text)
Executable
BIN
View File
Binary file not shown.
+14 -9
View File
@@ -18,6 +18,7 @@ import (
"fmt"
"io/ioutil"
"os/exec"
"strings"
"github.com/pkg/errors"
v "gopkg.in/go-playground/validator.v9"
@@ -51,17 +52,21 @@ func NmapRun(targets, ports, resultFilePath string, nmapSpeed int, enableLogs bo
return fmt.Errorf("invalid nmap speed value '%d'. Should be between '%d' and '%d'", nmapSpeed, PARANOIAC, INSANE)
}
// Prepare nmap command
cmd := execCommand(
"nmap",
fmt.Sprintf("-T%d", nmapSpeed),
"-A",
"-p",
cmdArgs := fmt.Sprintf(
"-T%d -A -p %s -oX %s %s",
nmapSpeed,
ports,
"-oX",
resultFilePath,
targets,
)
targets)
if enableLogs {
fmt.Printf("command: nmap %s\n", cmdArgs)
}
args := strings.Split(cmdArgs, " ")
// Prepare nmap command
cmd := execCommand("nmap", args...)
// Pipe stdout to be able to write the logs in realtime
stdout, err := cmd.StdoutPipe()
Generated
+60 -2
View File
@@ -5,6 +5,8 @@ imports:
version: f8b334df3789fbdf98df3b3b22815e958b956c19
- name: github.com/fatih/color
version: 570b54cabe6b8eb0bc2dfce68d964677d63b5260
- name: github.com/fsnotify/fsnotify
version: 4da3e2cfbabc9f751898f250b49f2439785783a1
- name: github.com/gernest/wow
version: 57298475c6371a5a652e74dcf624c80edfc5ae1a
subpackages:
@@ -15,16 +17,72 @@ imports:
version: b32fa301c9fe55953584134cb6853a13c87ec0a1
- name: github.com/gorilla/websocket
version: ea4d1f681babbce9545c9c5f3d5194a789c89f5b
- name: github.com/jessevdk/go-flags
version: 96dc06278ce32a0e9d957d590bb987c81ee66407
- name: github.com/hashicorp/hcl
version: 23c074d0eceb2b8a5bfdbb271ab780cde70f05a8
subpackages:
- hcl/ast
- hcl/parser
- hcl/scanner
- hcl/strconv
- hcl/token
- json/parser
- json/scanner
- json/token
- name: github.com/magiconair/properties
version: 8d7837e64d3c1ee4e54a880c5a920ab4316fc90a
- name: github.com/mattn/go-colorable
version: 5411d3eea5978e6cdc258b30de592b60df6aba96
repo: https://github.com/mattn/go-colorable
- name: github.com/mattn/go-isatty
version: 57fdcb988a5c543893cc61bce354a6e24ab70022
repo: https://github.com/mattn/go-isatty
- name: github.com/mitchellh/mapstructure
version: 06020f85339e21b2478f756a78e295255ffa4d6a
- name: github.com/pelletier/go-toml
version: 4e9e0ee19b60b13eb79915933f44d8ed5f268bdd
- name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
subpackages:
- difflib
- name: github.com/spf13/afero
version: 5660eeed305fe5f69c8fc6cf899132a459a97064
subpackages:
- mem
- name: github.com/spf13/cast
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
- name: github.com/spf13/jwalterweatherman
version: 12bd96e66386c1960ab0f74ced1362f66f552f7b
- name: github.com/spf13/pflag
version: 97afa5e7ca8a08a383cb259e06636b5e2cc7897f
- name: github.com/spf13/viper
version: 8ef37cbca71638bf32f3d5e194117d4cb46da163
- name: github.com/stretchr/objx
version: cbeaeb16a013161a98496fad62933b1d21786672
- name: github.com/stretchr/testify
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
subpackages:
- mock
- name: golang.org/x/crypto
version: 2509b142fb2b797aa7587dad548f113b2c0f20ce
subpackages:
- ssh/terminal
- name: golang.org/x/sys
version: e24f485414aeafb646f6fca458b0bf869c0880a1
repo: https://go.googlesource.com/sys
subpackages:
- unix
- windows
- name: golang.org/x/text
version: 6eab0e8f74e86c598ec3b6fad4888e0c11482d48
subpackages:
- transform
- unicode/norm
- name: gopkg.in/go-playground/validator.v9
version: a021b2ec9a8a8bb970f3f15bc42617cb520e8a64
- name: gopkg.in/tylerb/graceful.v1
version: 4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb
- name: gopkg.in/yaml.v2
version: eb3733d160e74a9c7e442f435eb3bea458e1d19f
testImports: []
+2 -2
View File
@@ -8,8 +8,6 @@ import:
- spin
- package: github.com/gorilla/websocket
version: ~1.2.0
- package: github.com/jessevdk/go-flags
version: ~1.3.0
- package: github.com/pkg/errors
version: ~0.8.0
- package: github.com/stretchr/testify
@@ -24,3 +22,5 @@ import:
version: ~0.16.0
- package: github.com/go-playground/locales
version: ~0.11.2
- package: github.com/spf13/pflag
- package: github.com/spf13/viper