├── Pwnagotchi_Master.py ├── README.md ├── scripts ├── combine.sh ├── seperate.sh └── ssh.sh └── setup.sh /Pwnagotchi_Master.py: -------------------------------------------------------------------------------- 1 | #################################################### Pwnagotchi Master ######################################################### 2 | ###################################################### By - VixelCode ########################################################## 3 | 4 | # Simple python3 proggram to make interactions with your pwnagotchi easier. This is the first program I have written so the code itself could probably be improved, but hey I'm learning and this is an accomplishment for me. If you have any suggestions or input on how to improve any of the coding please feel free to reach out to me on github! I'm always trying to learn new things. 5 | 6 | 7 | 8 | ## Pwnagotchi's ip - Default is 10.0.0.2 during setup, but if for some reason you changed it, you can change it here 9 | pwn_ip = '10.0.0.2' 10 | 11 | 12 | ## Pwnagotchi's username - root is needed for handshake file trasnfer. Make sure you have root ssh enabledd on your pwnagotchi! 13 | pwn_uname = 'root' 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | # Importing modules needed for program 33 | import subprocess 34 | import os 35 | import paramiko 36 | import sys 37 | import logging 38 | import time 39 | import logging 40 | from datetime import date 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | # Fancy things 58 | print(" ____ _ _ _ _ __ ___ _____ ____ ___ _ _ ____ __ __ __ ___ ____ ____ ____ \n" 59 | "( _ ( \/\/ | \( ) /__\ / __| _ |_ _) __| )_( |_ _) ( \/ ) /__\ / __|_ _| ___| _ \ \n" 60 | " )___/) ( ) ( /(__)( (_-.)(_)( )(( (__ ) _ ( _)(_ ) ( /(__)\\__ \ )( )__) ) / \n" 61 | "(__) (__/\__|_)\_|__)(__)___(_____)(__)\___|_) (_|____) (_/\/\_|__)(__|___/(__)(____|_)\_) \n") 62 | 63 | # Getting local machine variables 64 | local_user = os.getlogin() 65 | local_path = os.getcwd() 66 | date = date.today() 67 | 68 | # Setting bash script variables 69 | seperate_bash = (local_path +'/scripts/seperate.sh') 70 | ssh_bash = (local_path + '/scripts/ssh.sh') 71 | combine_bash = (local_path + '/scripts/combine.sh') 72 | 73 | # Setting path directories on local machine 74 | loot_path = (local_path + '/loot/') 75 | hashcat_loot = (loot_path + 'hashcat/') 76 | backups = (local_path + '/backups/') 77 | 78 | # Hashcat setting 79 | run_hashcat = f'hashcat -m22000' 80 | wordlist = '/usr/share/wordlists/rockyou.txt' 81 | 82 | # Setting default answer 83 | default_answer = 'y' 84 | 85 | # Setting path directories on pwnagotchi 86 | pwn_handshake = '/root/handshakes/' 87 | pwn_config = '/etc/pwnagotchi/config.toml' 88 | 89 | # Redefining settings 90 | ip = pwn_ip 91 | username = pwn_uname 92 | 93 | ################################################################################################################################ 94 | 95 | # Logging information 96 | logging.basicConfig(filename='logs.log', level=logging.INFO) 97 | 98 | ################################################################################################################################ 99 | 100 | # Defining pwnagotchi Interactions 101 | def pwnagotchi_interactions(): 102 | print("1 - SSH into pwnagotchi \n""2 - Download all pcap files \n" "3 - Erase all handshakes on pwnagotchi \n" "0 - Back") 103 | 104 | inter_choice = input("Enter choice : ") 105 | 106 | inter_choice = int(inter_choice) 107 | 108 | if inter_choice == 1: # SSH into pwnagotchi 109 | subprocess.call(ssh_bash, shell=True) 110 | pwnagotchi_interactions() 111 | 112 | if inter_choice == 2: # Download all pcap files 113 | password =input('Please enter your pwnagotchi password : ') 114 | server_path = pwn_handshake 115 | 116 | # Creating SSH connection 117 | ssh = paramiko.SSHClient() 118 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 119 | ssh.connect(ip, username=username, password=password) 120 | print("Connection Successful \n") 121 | 122 | # Open sftp and get file in requested folder 123 | sftp = ssh.open_sftp() 124 | files = sftp.listdir(server_path) 125 | print("Downloading handshakes \n") 126 | 127 | # Downloading Files 128 | for file in files: 129 | sftp.get(server_path + file, loot_path + file) 130 | print("Download completed \n") 131 | logging.info(f' Handshakes downloaded {date}') 132 | pwnagotchi_interactions() 133 | 134 | if inter_choice == 3: # Delete all handshakes on pwnagotchi 135 | password = input('Please enter your pwnagotchi password : ') 136 | server_path = pwn_handshake 137 | 138 | print("WARNING YOUR ABOUT TO DELETE ALL HANDSHAKES ON PWNAGOTCHI - Type y to confirm : ") 139 | 140 | response = str(input()) 141 | 142 | if response == default_answer: 143 | 144 | # Creating SSH connection 145 | ssh = paramiko.SSHClient() 146 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 147 | ssh.connect(ip, username=username, password=password) 148 | print("Connection Successful \n") 149 | 150 | # Open sftp and get file in requested folder 151 | sftp = ssh.open_sftp() 152 | files = sftp.listdir(server_path) 153 | print("Erasing handshakes \n") 154 | 155 | # Erasing Files 156 | for file in files: 157 | sftp.remove(server_path + file) 158 | print("Erased handshakes from pwnagotchi \n") 159 | logging.info(f' Erased handhakes from pwnagotchi {date}') 160 | pwnagotchi_interactions() 161 | 162 | if inter_choice == 0: 163 | main() 164 | 165 | elif inter_choice != 1-3: 166 | pwnagotchi_interactions() 167 | 168 | ################################################################################################################################ 169 | 170 | # Defining Backup Files 171 | def pwnagotchi_backup(): 172 | print("1 - Backup brain.nn & brain.json \n" "2 - Backup config.toml \n" "3 - Download pwnagotchi.log \n" "0 - Back") 173 | 174 | bkfl_choice = input("Enter choice : ") 175 | 176 | bkfl_choice = int(bkfl_choice) 177 | 178 | if bkfl_choice == 1: # Backup brain.nn and brain.json 179 | # Creating SSH connection 180 | password =input('Please enter your pwnagotchi password : ') 181 | ssh = paramiko.SSHClient() 182 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 183 | ssh.connect(ip, username=username, password=password) 184 | print("Connection Succesful \n") 185 | 186 | # Download brain.nn file 187 | server_path = str('/' + '/root/brain.nn') 188 | sftp = ssh.open_sftp() 189 | sftp.get(server_path, str(backups) + "brain.nn") 190 | 191 | # Download brain.json file 192 | server_path = str('/' + '/root/brain.json') 193 | sftp = ssh.open_sftp() 194 | sftp.get(server_path, str(backups) + "brain.json") 195 | print("brain.nn & brain.json downloaded \n") 196 | logging.info(f' Downloaded brain.nn & brain.josn {date}') 197 | pwnagotchi_backup() 198 | 199 | if bkfl_choice == 2: # Download config.toml 200 | 201 | server_path = pwn_config 202 | 203 | # Creating SSH connection 204 | password =input('Please enter your pwnagotchi password : ') 205 | ssh = paramiko.SSHClient() 206 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 207 | ssh.connect(ip, username=username, password=password) 208 | print("Connection Succesful \n") 209 | 210 | # Download config.toml file 211 | sftp = ssh.open_sftp() 212 | sftp.get(server_path, str(backups) + "config.toml") 213 | print("Downloaded config.toml \n") 214 | logging.info(f' Downoaded config.toml {date}') 215 | pwnagotchi_backup() 216 | 217 | if bkfl_choice == 3: # Download pwnagotchi.log 218 | 219 | server_path = pwn_config 220 | 221 | # Creating SSH connection 222 | password =input('Please enter your pwnagotchi password : ') 223 | ssh = paramiko.SSHClient() 224 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 225 | ssh.connect(ip, username=username, password=password) 226 | print("Connection Succesful \n") 227 | 228 | # Download pwnagotchi file 229 | sftp = ssh.open_sftp() 230 | sftp.get(server_path, str(backups) + "pwnagotchi.log") 231 | print("Downloaded pwnagotchi log \n") 232 | logging.info(f' Pwnagotchi.log downloaded {date}') 233 | pwnagotchi_backup() 234 | 235 | if bkfl_choice == 0: 236 | main() 237 | 238 | elif bkfl_choice != 1-3: 239 | pwnagotchi_backup() 240 | ################################################################################################################################ 241 | 242 | # Defining pwnagotchi setup 243 | def pwnagotchi_setup(): 244 | print("1 - Upload backup config.toml file \n" "0 - Back") 245 | 246 | stup_choice = input("Enter your choice : ") 247 | 248 | stup_choice = int(stup_choice) 249 | 250 | if stup_choice == 1: 251 | 252 | server_path = pwn_config 253 | 254 | # Creating SSH connection 255 | password =input('Please enter your pwnagotchi password : ') 256 | ssh = paramiko.SSHClient() 257 | ssh.load_host_keys(os.path.expanduser(os.path.join('~', '.ssh', 'known_hosts'))) 258 | ssh.connect(ip, username=username, password=password) 259 | print("Connection Succesful \n") 260 | 261 | # Uploading config.toml file 262 | config_toml = backups + 'config.toml' 263 | print("\n") 264 | sftp = ssh.open_sftp() 265 | sftp.put(config_toml, server_path) 266 | print("Uploaded config.toml \n") 267 | logging.info(f'config.toml file uploaded {date}') 268 | pwnagotchi_setup() 269 | 270 | if stup_choice == 0: 271 | main() 272 | 273 | elif stup_choice != 1: 274 | pwnagotchi_setup() 275 | ################################################################################################################################ 276 | 277 | def handshake_interactions(): 278 | print("1 - Seperate valid handshakes \n" "2 - Hashcat \n" "3 - Copy and paste to whitelist \n" "0 - Back") 279 | 280 | hndske_choice = input("Enter choice : ") 281 | 282 | hndske_choice = int(hndske_choice) 283 | 284 | if hndske_choice == 1: # Seperating pcap files with good handshakes 285 | subprocess.call(['bash', seperate_bash, loot_path]) 286 | subprocess.call(['bash', combine_bash, hashcat_loot]) 287 | logging.info(f' Seperated valid handshakes {date}') 288 | print("Seperated valid handshake files \n") 289 | handshake_interactions() 290 | 291 | 292 | if hndske_choice == 2: # List files in the hashcat folder and asking for user input for which one to run hashcat against 293 | valid_hashcat = os.listdir(hashcat_loot) 294 | hashcat_log = valid_hashcat.index('hashcat.log') 295 | valid_hashcat.pop(hashcat_log) 296 | for handshake in valid_hashcat: 297 | print(f'{valid_hashcat.index(handshake)} : {handshake}') 298 | hashcat_file = int(input("Select a network : ")) 299 | hashcat_file_name = valid_hashcat[hashcat_file] 300 | os.system(f'{run_hashcat} {hashcat_loot}{hashcat_file_name} {wordlist}') 301 | 302 | if hndske_choice == 3: # Copy and paste for whitelist on pwnagotchi 303 | print("Below network names are all the networks you have a valid handshake for ready to pasted into your config.toml file. \n") 304 | valid_handshakes = os.listdir(hashcat_loot) 305 | if len(valid_handshakes) == 0: 306 | print("No valid handshakes, get out there and capture some! \n") 307 | handshake_interactions() 308 | if "combined.hc22000" in valid_handshakes : 309 | valid_handshakes.remove("combined.hc22000") 310 | if "hashcat.log" in valid_handshakes : 311 | valid_handshakes.remove("hashcat.log") 312 | if valid_handshakes == 0 : 313 | print("No valid handshakes, get out there and capture some! \n") 314 | for file in valid_handshakes : 315 | split_hndske = () 316 | split_hndske = file.split("_") 317 | if len(split_hndske) ==2: 318 | split_hndske.pop(1) 319 | for file in split_hndske : 320 | print('"' + file + '",') 321 | print("\n") 322 | 323 | if hndske_choice == 0: 324 | main() 325 | 326 | elif hndske_choice != 1-3: 327 | handshake_interactions() 328 | 329 | ################################################################################################################################ 330 | 331 | # Main Menu 332 | def main(): 333 | print("1 - Pwnagotchi Interactions \n" "2 - Backup Files \n" "3 - Pwnagotchi Setup \n" "4 - Handshake Interactions \n" "0 - Exit \n") 334 | 335 | choice = input("Enter choice : ") 336 | 337 | choice = int(choice) 338 | 339 | options = [1, 2, 0] 340 | 341 | if choice == 1: 342 | pwnagotchi_interactions() 343 | 344 | if choice == 2: 345 | pwnagotchi_backup() 346 | 347 | if choice == 3: 348 | pwnagotchi_setup() 349 | 350 | if choice == 4: 351 | handshake_interactions() 352 | 353 | if choice == 0: 354 | print("Happy Hunting! \n") 355 | exit() 356 | elif choice != 1-4: 357 | main() 358 | main() 359 | 360 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Simple Python3 program I put together to make interactions with a pwnagotchi easier. This is the first program I have written so please have patience as issues arise and I work on fixing them. If you have any suggestions, or just input on how to make the code more efficient please feel free to let me know! 2 | 3 | 4 | Requirments 5 | All file transfers are completed over ssh, therefore you will have to have root ssh enables in order to transfer files. 6 | Currently only tested on kali VM 7 | 8 | To enable root ssh on your pwnagotchi, first ssh into your pwnagotchi 9 | 10 | sudo su 11 | passwd root 12 | 'yourpassword' 13 | sudo nano /etc/ssh/sshd_config 14 | find the line that says '#PermitRootLogin prohibit-password' 15 | change it to say 'PermitRootLogin yes' 16 | service ssh restart 17 | 18 | Intructions 19 | 20 | cd /path/to/Pwnagotchi_Master 21 | sudo bash setup.sh 22 | sudo python3 Penagotchi_Master.py 23 | 24 | Menu 25 | 26 | Pwnagotchi Interactions 27 | 28 | - SSH into pwnagotchi 29 | - Download handshakes from pwnagotchi 30 | - Erase handshakes from pwnagotchi 31 | 32 | Backup Files 33 | 34 | - Backup AI 35 | download brain.nn & brain.json files from pwnagotchi to backup folder 36 | - Backup config.toml 37 | - Download pwnagotchi.log file 38 | 39 | Setup Pwnagotchi 40 | 41 | - Upload config.toml 42 | 43 | Handshake Interactions 44 | 45 | - Seperates pcap files with valid handshakes using hcxpcapngtool 46 | - Select from list of files to run hashcat on 47 | - Prints in terminal a copy and paste string of all networks you have a valid handshake for to be pasted into your pwnagotchi's config.toml file. 48 | 49 | -------------------------------------------------------------------------------- /scripts/combine.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cd $1 4 | 5 | FILES='*.hc22000' 6 | 7 | for f in $FILES 8 | do 9 | cat $f >> combined.hc22000 10 | 11 | done 12 | -------------------------------------------------------------------------------- /scripts/seperate.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cd $1 4 | 5 | FILES='*.pcap' 6 | 7 | for f in $FILES 8 | do 9 | FileName=$f 10 | hcxpcapngtool $f --all -o $1/hashcat/${f%.pcap}.hc22000 >> ./hashcat/hashcat.log 11 | 12 | done 13 | -------------------------------------------------------------------------------- /scripts/ssh.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | sudo ssh pi@10.0.0.2 -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | sudo mkdir loot 4 | sudo mkdir backups 5 | sudo mkdir loot/hashcat 6 | sudo chmod +x loot 7 | sudo chmod +x backups 8 | sudo chmod +x scripts/ssh.sh 9 | sudo chmod +x scripts/seperate.sh 10 | --------------------------------------------------------------------------------