├── INSTALL.txt ├── README.md ├── dns.txt └── dnsenum.pl /INSTALL.txt: -------------------------------------------------------------------------------- 1 | ##You need Perl, it's installed on KALI Linux and on most other Linux's by default. 2 | 3 | ##To install missing Perl modules, first install cpanminus (as root): 4 | 5 | debian: apt-get install cpanminus 6 | centos: yum install cpan 7 | curl -L http://cpanmin.us | perl - App::cpanminus 8 | 9 | ##Then: 10 | 11 | root@kali:~# cpanm String::Random 12 | --> Working on String::Random 13 | Fetching http://www.cpan.org/authors/id/S/SH/SHLOMIF/String-Random-0.25.tar.gz . 14 | .. OK 15 | Configuring String-Random-0.25 ... OK 16 | Building and testing String-Random-0.25 ... OK 17 | Successfully installed String-Random-0.25 18 | 1 distribution installed 19 | 20 | Mac Os X 21 | ======== 22 | perl -MCPAN -e shell 23 | 24 | ## and then type something like: 25 | 26 | install String::Random 27 | 28 | ANd just type enter when you're asked something ;) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README - dnsenum.pl VERSION: 1.2.4 2 | 3 | multithreaded perl script to enumerate DNS information of a domain 4 | and to discover non-contiguous ip blocks. 5 | 6 | OPERATIONS: 7 | 8 | 1) Get the host's addresse (A record). 9 | 10 | 2) Get the namservers (threaded). 11 | 12 | 3) Get the MX record (threaded). 13 | 14 | 4) Perform axfr queries on nameservers and get BIND VERSION (threaded). 15 | 16 | 5) Get extra names and subdomains via google scraping 17 | (google query = "allinurl: -www site:domain"). 18 | 19 | 6) Brute force subdomains from file, can also perform recursion 20 | on subdomain that have NS records (all threaded). 21 | 22 | 7) Calculate C class domain network ranges and perform whois 23 | queries on them (threaded). 24 | 25 | 8) Perform reverse lookups on netranges 26 | ( C class or/and whois netranges) (threaded). 27 | 28 | 9) Write to domain_ips.txt file ip-blocks. 29 | 30 | Changelog from version 1.2.2 31 | 32 | - Fixed GoogleScraping 33 | - Fixed wildcard issues 34 | - Changed output function to get rid of errors with new Net::DNS version 35 | - A bit of cleanup here and there 36 | - Removed Bind Version detection 37 | 38 | PREREQUISITES: 39 | 40 | Modules that are included in perl 5.10.0: 41 | Getopt::Long 42 | IO::File 43 | Thread::Queue 44 | 45 | Other Necessary modules: 46 | Must have: 47 | Net::IP 48 | Net::DNS 49 | Net::Netmask 50 | Optional: 51 | Net::Whois::IP 52 | HTML::Parser 53 | WWW::Mechanize 54 | XML::Writer 55 | 56 | To install a module, simply run (as root): 57 | 58 | perl -MCPAN -e shell 59 | 60 | and then type: install 61 | eg: 62 | cpan[1]> install XML::Writer 63 | 64 | Perl ithreads support: 65 | perl version must be compliled with ithreads support. 66 | threads 67 | threads::shared 68 | 69 | 70 | OPTIONS: run "perldoc dnsenum.pl". 71 | 72 | 73 | 74 | Special thanks to all Perl developers. 75 | 76 | Filip Waeytens 77 | tix tixxDZ 78 | -------------------------------------------------------------------------------- /dns.txt: -------------------------------------------------------------------------------- 1 | * 2 | 1003 3 | 1025 4 | 1027 5 | 1029 6 | 1037 7 | 1044 8 | 1066 9 | 1070 10 | 1071 11 | 1075 12 | 1082 13 | 1088 14 | 11 15 | 1106 16 | 1107 17 | 1108 18 | 1114 19 | 1115 20 | 1116 21 | 112sos 22 | 1167 23 | 1168 24 | 1178 25 | 1180 26 | 1184 27 | 1187 28 | 1189 29 | 1198 30 | 1203 31 | 1204 32 | 121 33 | 1211 34 | 1216 35 | 131 36 | 132 37 | 133 38 | 134 39 | 135 40 | 154 41 | 155 42 | 198 43 | 2005 44 | 214 45 | 223 46 | 226 47 | 228 48 | 232 49 | 25 50 | 265 51 | 27 52 | 270 53 | 28 54 | 29 55 | 30 56 | 30days 57 | 33 58 | 34 59 | 36 60 | 37 61 | 417 62 | 419 63 | 434 64 | 437 65 | 448 66 | 45 67 | 453 68 | 46 69 | 475 70 | 479 71 | 486 72 | 491 73 | 50 74 | 502 75 | 51 76 | 517 77 | 528 78 | 53 79 | 532 80 | 54 81 | 541 82 | 557 83 | 56 84 | 561 85 | 593 86 | 595 87 | 598 88 | 599 89 | 605 90 | 607 91 | 616 92 | 624 93 | 625 94 | 629 95 | 630 96 | 648 97 | 664 98 | 669 99 | 67 100 | 684 101 | 7 102 | 714 103 | 727 104 | 729 105 | 731 106 | 75 107 | 763 108 | 775 109 | 79 110 | 805 111 | 806 112 | 859 113 | 861 114 | 881 115 | 925 116 | 948 117 | 951 118 | 953 119 | 958 120 | 959 121 | 96 122 | 969 123 | 97 124 | 976 125 | 977 126 | 980 127 | 99 128 | 992 129 | 996 130 | 997 131 | 999 132 | a 133 | a-servers 134 | abc 135 | about 136 | accept 137 | accept-kbo-bce-select 138 | accept-kbo-bce-wi 139 | access 140 | accountrequest 141 | accounts 142 | acg 143 | aco 144 | acp1 145 | act 146 | adl 147 | admin 148 | administrador 149 | administrator 150 | ads 151 | adserver 152 | adsl 153 | afa 154 | afcn 155 | affaires-etrangeres 156 | affaires-sociales 157 | affairesetrangeres 158 | affairessociales 159 | afigp 160 | afnorth 161 | africa 162 | afs-nafsd 163 | afsca 164 | afsca-favv 165 | afsca2006 166 | afsouth 167 | agencedespensions 168 | agent 169 | ags3 170 | aigpol 171 | aiiz 172 | air 173 | aircraft 174 | airiz 175 | airn 176 | airramstein 177 | airtest 178 | alaune 179 | albert-2 180 | albert-deux 181 | albert-II 182 | albert-twee 183 | albert2 184 | albertdeux 185 | albertii 186 | alberttwee 187 | allocationsfamiliales 188 | ambtenaar 189 | ambtenaren 190 | ambtenarenzaken 191 | america 192 | animal-diseases 193 | animaldiseases 194 | antartica 195 | anthrax 196 | antiracisme 197 | aoot-servers 198 | aoss 199 | ap 200 | apod-kaia 201 | apps 202 | arbeid 203 | archive 204 | arcweb 205 | arp 206 | arrc 207 | arthur 208 | asc 209 | asia 210 | atlantic 211 | attest 212 | attest-acc 213 | attest-test 214 | auditinternetresorerie 215 | australia 216 | av 217 | avatar 218 | b-fast 219 | b-servers 220 | bacillusanthracis 221 | backup 222 | badc 223 | banquecarrefour 224 | bart 225 | bc 226 | bc1 227 | bce 228 | bcss 229 | bcss-ksz 230 | bdsrvns01 231 | be 232 | belac 233 | beldonor 234 | belgacom 235 | belgica 236 | belgie 237 | belgien 238 | belgique 239 | belgium 240 | belgoeurop 241 | belgopocket 242 | bellis 243 | belmed 244 | belmed-acc 245 | belmed-dev 246 | belspo 247 | beroepsziekten 248 | beschaeftigung 249 | bestat 250 | beta 251 | betula 252 | bfab 253 | bfast 254 | bihdr 255 | bijzonderbeschermingsfonds 256 | binnenland 257 | binnenlandse-zaken 258 | binnenlandsezaken 259 | biodiversity 260 | biosafety 261 | birb 262 | birbdev 263 | birbtest 264 | blog 265 | boite-postale 266 | boitepostale 267 | boot-servers 268 | border1 269 | br 270 | bram 271 | brite 272 | britetw 273 | britetwais 274 | bse 275 | budget 276 | budget-federal 277 | budgetenbeheerscontrole 278 | budgetfederal 279 | bugs 280 | buildingsagency 281 | buitenland 282 | buitenlandse-handel 283 | buitenlandse-zaken 284 | buitenlandsehandel 285 | buitenlandsezaken 286 | c 287 | caami 288 | caami-hziv 289 | cabinet 290 | cadps-login 291 | cadps-nt 292 | cadpsdev-login 293 | cadpsdev-nt 294 | caoc-find 295 | caoc1 296 | caoc5 297 | caoc7 298 | caoc8 299 | caocbalk 300 | caocf 301 | caocpr 302 | cap 303 | capac 304 | capac-hvw 305 | capelo 306 | captest 307 | ccdd 308 | ccdd-ccdv 309 | ccdv 310 | ccecrb 311 | ccvd 312 | cdvupensioenen 313 | census 314 | census2011 315 | centredexpertise 316 | cepma 317 | cerva 318 | cfdd 319 | cfdd-frdo 320 | cgs2 321 | cgs4 322 | cgs5 323 | channel 324 | cidd 325 | cidh 326 | cimicgs 327 | cimire 328 | cipal 329 | cisgr 330 | cisteam1 331 | cisteam3 332 | citrix 333 | civielebescherming 334 | civilservice 335 | class 336 | classical-swine-fever 337 | classicalswinefever 338 | claude 339 | cld 340 | client 341 | climat 342 | climateregistry 343 | clo 344 | clubdevenise 345 | clubofvenice 346 | cmlag 347 | cmn-bw-bru 348 | cnrcsa 349 | coda 350 | coda-cerva 351 | codacerva 352 | coedat 353 | coeurnelle-mail 354 | combuysse 355 | cominformatics 356 | commerce-exterieur 357 | commerceexterieur 358 | commissionjeuxhasard 359 | communication 360 | communications 361 | commz 362 | conformity 363 | conseil-etat 364 | conseildetat 365 | consetat 366 | conventioneu 367 | conventionue 368 | cooperation 369 | coot-servers 370 | copieconforme 371 | councilofstate 372 | cpas 373 | cprr 374 | csf 375 | csipme 376 | csl-uncl-pdc 377 | cslo 378 | cspm 379 | ctc 380 | customs 381 | cvts 382 | cwid 383 | d 384 | dau 385 | dav 386 | davo 387 | deambachten 388 | deambachten-acc 389 | debtagency 390 | demadelief 391 | developpement 392 | dfi 393 | di 394 | diehandwerker 395 | diehandwerker-acc 396 | dienstenrichtlijn 397 | dienstleistungsrichtlinie 398 | dierenziekten 399 | dioxin 400 | dioxine 401 | dioxines 402 | diplobel 403 | diplomatie 404 | directiveservices 405 | directory 406 | dmz 407 | dmz-2 408 | dns 409 | dns0 410 | dns1 411 | dns1w 412 | dns2 413 | dns3 414 | dnsintera 415 | dnsinterb 416 | dnsmaster 417 | docufin 418 | documentadministratifunique 419 | dofi 420 | doot-servers 421 | dosz 422 | dosz-ossom 423 | doszserver 424 | doteu 425 | drupal 426 | dummy 427 | dwti 428 | e 429 | e2e 430 | e3a 431 | ebr 432 | ebr-acc 433 | ecodata 434 | ecodoc 435 | ecolabel 436 | economie 437 | economie2 438 | economiesociale 439 | ecops 440 | ed 441 | ed-dau 442 | edateng 443 | edatenq 444 | edatenq-acc 445 | eddau 446 | eensluidendverklaring 447 | ehealth 448 | ehealth-it 449 | eiss 450 | eisz 451 | eiz7iu9g 452 | election 453 | electionresults 454 | elections 455 | electionssociales 456 | elisabeth 457 | emc 458 | emetro 459 | emetro-acc 460 | emploi 461 | employment 462 | energie 463 | eng-tx 464 | engtx2 465 | enigdocument 466 | enquete 467 | environment 468 | eoot-servers 469 | epatras 470 | eportal 471 | era-nova 472 | eranova 473 | ere-nova 474 | erenova 475 | erhebung 476 | es 477 | esb 478 | esp 479 | espacenet 480 | etudiantautravail 481 | eu2010 482 | euconventie 483 | euconvention 484 | eudir 485 | eurdir 486 | euro 487 | europe 488 | exbmy 489 | exc 490 | exctest 491 | ext 492 | ext1 493 | ext2 494 | extern 495 | extranet 496 | f 497 | fanc 498 | fanc2 499 | fao 500 | faofat 501 | fat 502 | fatfao 503 | favv 504 | favv-afsca 505 | favv2006 506 | fbk 507 | fbz 508 | fbz-fmp 509 | fchd 510 | fcmd 511 | fdsrvns02 512 | fedasil 513 | fedasilantartica 514 | fedict 515 | fedpol 516 | fedpolfed 517 | femmeetpension 518 | fernandez 519 | ffe 520 | file 521 | fin 522 | finance 523 | finances 524 | financien 525 | finanzen 526 | finderup 527 | finform 528 | fisconet 529 | fiscus 530 | flr-stat 531 | fmp 532 | fmp-fbz 533 | fonction-publique 534 | fonctionnaire 535 | fonctionnaires 536 | fonctionpublique 537 | fondsdevieillissement 538 | fondsspecialdeprotection 539 | foodsafety 540 | foot-servers 541 | foracs 542 | forensic 543 | forensics 544 | forfeit 545 | form 546 | fortar3 547 | fortar3-acc 548 | forum 549 | forums 550 | fr 551 | fra 552 | frdo 553 | frdo-cfdd 554 | fso 555 | fsoffe 556 | ftp 557 | ftps 558 | ftpserver 559 | fugazi 560 | fytoweb 561 | g 562 | g01 563 | g02 564 | galahad 565 | gamingcommission 566 | gas2020gaz 567 | gaz2020 568 | ge-nl 569 | gehaelter 570 | gehalter 571 | geh\228lter 572 | gemsz 573 | genootschap 574 | gesundheit 575 | gezondheid 576 | gfmd-fmmd 577 | gimli 578 | globalisatindebate 579 | goot-servers 580 | gr 581 | grc 582 | griep 583 | grippe 584 | grippeaviaire 585 | guideweb 586 | gwydion 587 | handicap 588 | haw 589 | hawk 590 | headlines 591 | health 592 | hermes 593 | hfa 594 | hkiv 595 | hms 596 | hog-cholera 597 | hogcholera 598 | hoot-servers 599 | horizon 600 | host 601 | hq 602 | hrf 603 | hrf-m 604 | hrf-mobile 605 | hrf-mobile-main 606 | hrf-stat 607 | hrf-static 608 | hrfd 609 | hrfd-main 610 | hrfl 611 | hrzkmo 612 | http 613 | https 614 | hvkz 615 | hvkz-cspm 616 | hvw 617 | hvw-capac 618 | hziv 619 | hziv-caami 620 | ia 621 | ib 622 | ibz 623 | ibzbb 624 | ibzdgip 625 | ibzkcl 626 | icdo 627 | ichr 628 | icn-inr 629 | icops 630 | ict-ssl 631 | ictc 632 | ictctest 633 | icte 634 | ida 635 | idav 636 | ids 637 | iefa 638 | iefh 639 | ies 640 | iev 641 | iev-ivk 642 | ievivk 643 | iewm 644 | ifa 645 | ifa-ofo 646 | ifaofo 647 | igvm 648 | ijhq 649 | illegale-arbeid 650 | imail 651 | imcd1 652 | imcd2 653 | imcd3 654 | inami 655 | inami-riziv 656 | inasti 657 | inasti-rsvz 658 | incc 659 | ine 660 | info-shop 661 | infogsm 662 | infomail 663 | infosec 664 | infoshop 665 | infoshopping 666 | infrastructure 667 | infrastructuur 668 | inig 669 | inpectiondesfinances 670 | inr-icn 671 | inrct 672 | inspectievanfinancien 673 | inspectiondesfinances 674 | install 675 | interieur 676 | intern 677 | interneauditthesaurie 678 | intranet 679 | investinbelgium 680 | ioot-servers 681 | ipcbel130 682 | ipcbel140 683 | iph 684 | irc 685 | iroigwy 686 | isaf 687 | isaf-hq 688 | isav 689 | ism 690 | issue-tracker 691 | issuetracker 692 | it 693 | itdel 694 | iv-inig 695 | iv-niooo 696 | ivk 697 | ivk-iev 698 | ivkiev 699 | jallc 700 | jcs 701 | jcsc 702 | jcse 703 | jcsw 704 | jemm 705 | jenner 706 | jewcs 707 | jfc-nafs 708 | jfc-napl 709 | jfcbs 710 | jfclb 711 | jfcna 712 | jfcnaples 713 | jfcnp 714 | jfnp 715 | jftc 716 | jhlb 717 | jhnsgda 718 | jobs 719 | jobsdev 720 | joot-servers 721 | juridict 722 | jurion 723 | just 724 | justice 725 | justine 726 | justitie 727 | jwc 728 | jwctf 729 | kafka 730 | kansspel 731 | kansspelcommissie 732 | kbo 733 | kbo-acc 734 | kbo-bce 735 | kbo-bce-private 736 | kbo-bce-ps 737 | kbo-bce-select 738 | kbo-bce-wi 739 | kbo-test 740 | kbopub 741 | kbopub-acc 742 | kce 743 | kce2 744 | kcenet 745 | kcetools 746 | kenniscentrum 747 | kfor 748 | kim 749 | kinderbijslag 750 | klassieke-varkenspest 751 | klassiekevarkenspest 752 | kleinkasteeltje 753 | klimaat 754 | koen 755 | kommissionsglucksspiele 756 | konings-palast 757 | koningspalast 758 | koninklijk-paleis 759 | koninklijkpaleis 760 | koot-servers 761 | krantenkoppen 762 | kruispuntbank 763 | ksz 764 | ksz-bcss 765 | lab 766 | lahd 767 | lahd2 768 | lamd 769 | lancelot 770 | laruelle 771 | laurette-onkelinckx 772 | laurette-onkelinx 773 | lauretteonkelinckx 774 | lauretteonkelinx 775 | lcc14 776 | ldk 777 | lebensmittel 778 | lebensmittelsicherheit 779 | leefloon 780 | leefmilieu 781 | lesartisans 782 | lesartisans-acc 783 | likiv 784 | limosa 785 | linpha 786 | linux 787 | lists 788 | live 789 | live2 790 | lju 791 | lnc01 792 | lnc02 793 | lnc03 794 | lnc04 795 | lnc05 796 | lnc06 797 | lnc07 798 | lnc08 799 | lnc09 800 | lnc11 801 | lnc12 802 | lnc13 803 | lnc14 804 | lnc15 805 | lnc16 806 | lnc17 807 | lnc18 808 | lo 809 | log 810 | logo 811 | logos 812 | lokal-polizei 813 | lokale-politie 814 | lokalepolitie 815 | lokalpolizei 816 | loot-servers 817 | lss 818 | lssplv 819 | madeliefjes 820 | magnette 821 | mail 822 | mail1 823 | mail2 824 | mailhost 825 | mailin 826 | mailsync 827 | main 828 | mainguard 829 | maladies-animales 830 | maladies-professionnelles 831 | maladiesanimales 832 | manp 833 | manw 834 | map 835 | margrietjes 836 | margueritebelge 837 | marguerites 838 | marketing 839 | mas 840 | masecu 841 | masp-be 842 | mathilde 843 | max 844 | maxima 845 | maximiliaan 846 | mazfp 847 | mcug 848 | me262 849 | meads 850 | medex 851 | mediateur-pensions 852 | mediateurpensions 853 | mediation-pension 854 | mediation-pensions 855 | mediationpension 856 | mediationpensions 857 | member 858 | members 859 | merelbeke 860 | meta 861 | metrologie 862 | metrology 863 | mibz 864 | mijnsocialezekerheid 865 | milieu 866 | miltvuur 867 | mim 868 | mineco 869 | minfin 870 | minsoc 871 | mistr 872 | mittelstand 873 | mlink1 874 | mlink2 875 | mlm-moscow 876 | mlo-belgrade 877 | mnc-ne-pl 878 | mobile 879 | mobilit 880 | mobilitaetswoche 881 | mobilitatswoche 882 | mobility 883 | mobilityweek 884 | monarchie 885 | monarchy 886 | moniteur 887 | moot-servers 888 | morello 889 | msiac 890 | msz 891 | mtwg 892 | mx 893 | mx1 894 | mx11 895 | mx12 896 | mx2 897 | mx3 898 | mykce 899 | naa 900 | nacesearch 901 | nacma 902 | nacmo 903 | naewfc 904 | nagsma 905 | nahema 906 | naissance 907 | naissance2 908 | nama 909 | name 910 | namsa 911 | namsacell-npc 912 | naples 913 | napma 914 | nationalregister 915 | natoschool 916 | nav 917 | navtest 918 | nc 919 | nc1s 920 | nc2s 921 | nc3a 922 | ncags 923 | ncas 924 | ncbs 925 | nchd 926 | ncirc 927 | nciss 928 | nciz 929 | nclb 930 | ncmd 931 | ncnf 932 | ncnp 933 | ncnp-dpr 934 | ncnw 935 | ncnw-fcs 936 | ncrn 937 | ncsa 938 | ncsa-1sb 939 | ndc 940 | ndss 941 | nehap 942 | net 943 | netma 944 | news 945 | ng3 946 | nhqb-mail 947 | nhqc3s 948 | nhqs 949 | nhqsa 950 | niapc 951 | nic 952 | nicc 953 | nicolas-aymeric 954 | nihdi 955 | nima 956 | nio-moscow 957 | niooo 958 | nitcdsa 959 | nitcdsa2rev2 960 | nitcdsarev2 961 | nitcnpki2rev2 962 | nitcnpkirev2 963 | nitcpki 964 | nl 965 | nlctst 966 | nmiotc 967 | nms 968 | nncc 969 | nnmc 970 | nos 971 | nova 972 | npc 973 | nr 974 | nra 975 | nrflb 976 | ns 977 | ns01 978 | ns02 979 | ns1 980 | ns2 981 | nsa 982 | nshq 983 | nss 984 | ntmi-gtt 985 | ntmi-hq 986 | ntp 987 | ntserver 988 | nurc 989 | nvr 990 | obel 991 | ocamocad 992 | ocde-principesdirecteurs 993 | ocmw 994 | ocs 995 | oecd-guidelines 996 | oeffentlichendienst 997 | oeso-richtlijnen 998 | offentlichendienst 999 | offentlichendienstespensionen 1000 | office 1001 | ofo 1002 | ofo-ifa 1003 | ofoifa 1004 | old 1005 | oldphpfarm 1006 | oldphpfarm-stag 1007 | ombudsdienst-pensioen 1008 | ombudsdienst-pensioenen 1009 | ombudsdienst-pension 1010 | ombudsdienst-pensionen 1011 | ombudsdienstpensioen 1012 | ombudsdienstpensioenen 1013 | ombudsdienstpension 1014 | ombudsdienstpensionen 1015 | ombudsman 1016 | ombudsman-pensioen 1017 | ombudsman-pensioenen 1018 | ombudsman-pensionen 1019 | ombudsman-pensions 1020 | ombudsman-pesion 1021 | ombudsmann-pensionen 1022 | ombudsmann-pensions 1023 | ombudsmannpensionen 1024 | ombudsmannpensions 1025 | ombudsmanpensioen 1026 | ombudsmanpensioenen 1027 | ombudsmanpension 1028 | ombudsmanpensionen 1029 | ombudsmanpensions 1030 | ombudsmanpesion 1031 | onafts 1032 | onafts-rkw 1033 | onem 1034 | onem-rva 1035 | onerva 1036 | onkelinckx 1037 | onkelinx 1038 | onp 1039 | onp-rvp 1040 | onprvp 1041 | onss 1042 | onssapl 1043 | onssrszlss 1044 | ontwikkeling 1045 | ontwikkelings-samenwerking 1046 | ontwikkelingssamenwerking 1047 | onva 1048 | onva-rjv 1049 | osone 1050 | ossom 1051 | ossom-dosz 1052 | otan 1053 | outpost 1054 | outsite 1055 | overheidspensioenen 1056 | owa 1057 | p-o 1058 | p51 1059 | pacific 1060 | palais-royal 1061 | palaisroyal 1062 | pan 1063 | paquerette 1064 | paquerettes 1065 | pasteur 1066 | patrimoniumdiensten 1067 | pdasync 1068 | pdod 1069 | pdoed 1070 | pdos 1071 | pdos-sdpsp 1072 | pegase 1073 | pensioenagentschap 1074 | pensioenen 1075 | pensionen 1076 | pensions 1077 | pensionsagentur 1078 | pensionspubliques 1079 | peste-aviaire 1080 | peste-porcine 1081 | pesteaviaire 1082 | pesteporcine 1083 | petitchateau 1084 | petrel35 1085 | pgr 1086 | phimail 1087 | phone 1088 | phpbalancer 1089 | phpbalancer-stag 1090 | phpwf 1091 | phytoweb 1092 | plan 1093 | plan2004 1094 | plda 1095 | po 1096 | polfed 1097 | police 1098 | police-locale 1099 | policelocale 1100 | politie 1101 | polizei 1102 | pop 1103 | pophost 1104 | portaalserver 1105 | portal 1106 | postbox 1107 | postbus 1108 | postfach 1109 | ppp1 1110 | ppp10 1111 | ppp11 1112 | ppp12 1113 | ppp13 1114 | ppp14 1115 | ppp15 1116 | ppp16 1117 | ppp17 1118 | ppp18 1119 | ppp19 1120 | ppp2 1121 | ppp20 1122 | ppp21 1123 | ppp3 1124 | ppp4 1125 | ppp5 1126 | ppp6 1127 | ppp7 1128 | ppp8 1129 | ppp9 1130 | pptp 1131 | premier 1132 | presscenter 1133 | presscentre 1134 | pressreview 1135 | princess-elisabeth 1136 | princesse-elisabeth 1137 | princesseelisabeth 1138 | princesselisabeth 1139 | princesselouise 1140 | princesslouise 1141 | prinses-elisabeth 1142 | prinseselisabeth 1143 | prinseslouise 1144 | print 1145 | printer 1146 | prinzessin-elisabeth 1147 | prinzessinelisabeth 1148 | prinzessinlouise 1149 | privacy 1150 | private-security 1151 | private-sicherheit 1152 | private-veilligheid 1153 | privatesecurity 1154 | privatesicherheit 1155 | privateveilligheid 1156 | prodcom 1157 | projects 1158 | protectioncivile 1159 | pub 1160 | public 1161 | publichealth 1162 | publicweb 1163 | quetelet 1164 | raadvanstate 1165 | raadvst 1166 | raadvst-consetat 1167 | rac-restaurants-cae 1168 | ranva 1169 | ras 1170 | raven 1171 | rcc 1172 | rce 1173 | rcn 1174 | rcs 1175 | rcw 1176 | rdb 1177 | rdb-rdg 1178 | rdg 1179 | rdg-rdb 1180 | reach 1181 | reactricity 1182 | recensement 1183 | recensement2011 1184 | recherche 1185 | reflex 1186 | regie 1187 | regiedergebouwen 1188 | regiedesbatiment 1189 | regiedesbatiments 1190 | register 1191 | registrenational 1192 | relay 1193 | relay1 1194 | reno 1195 | repository 1196 | residencepalace 1197 | resultatselectoraux 1198 | revenu-d-integration 1199 | revenu-dintegration 1200 | revenudintegration 1201 | rfid 1202 | rfid-test 1203 | rfidtest 1204 | rijksregister 1205 | riziv 1206 | riziv-inami 1207 | rjv 1208 | rjv-onva 1209 | rkw 1210 | rkw-onafts 1211 | RKW-ONAFTS-TEST 1212 | root 1213 | route 1214 | router 1215 | royal-palace 1216 | royalpalace 1217 | rrn 1218 | rss 1219 | rssdirectory 1220 | rsvz 1221 | rsvz-inasti 1222 | rsz 1223 | rszppo 1224 | rta 1225 | rto 1226 | ruling 1227 | rva 1228 | rva-onem 1229 | rvp 1230 | rvp-onp 1231 | rvponp 1232 | saclant 1233 | saclantc 1234 | saclantcen 1235 | salmonella 1236 | salmonellose 1237 | salmonellosis 1238 | samenwerking 1239 | saml 1240 | sant01 1241 | sante 1242 | sante-publique 1243 | santepublique 1244 | saso 1245 | sav 1246 | sbib03 1247 | scdfpensions 1248 | scha01 1249 | schweinepest 1250 | sdpsp 1251 | sdpsp-pdos 1252 | search 1253 | secal 1254 | secure 1255 | secure2 1256 | securite-prive 1257 | securite-privee 1258 | securitealimentaire 1259 | securiteprive 1260 | securiteprivee 1261 | securitesociale 1262 | selor 1263 | semainedelamobilite 1264 | server 1265 | server-lnmail 1266 | serverex 1267 | services-stag 1268 | servicesdirective 1269 | servicespatrimoniaux 1270 | seveso 1271 | sfn 1272 | sgen01 1273 | sgt4 1274 | shape 1275 | shipping 1276 | shop 1277 | shop-info 1278 | shopinfo 1279 | sibelius 1280 | sigedis 1281 | silberfonds 1282 | simplification 1283 | siod 1284 | sirs 1285 | siskin 1286 | sist 1287 | sjam01 1288 | skab01 1289 | slab01 1290 | slem02 1291 | slem03 1292 | sleu01 1293 | slgs01 1294 | slice 1295 | smee01 1296 | smee03 1297 | smtp 1298 | sng302 1299 | sng3lnmail1 1300 | sng3lnmail2 1301 | sng3lnmail3 1302 | sng3lnmail4 1303 | sng3lnmail5 1304 | sngslnmail1 1305 | snislnmail1 1306 | snislnmail2 1307 | snislnmail3 1308 | snislnmail4 1309 | snislnmail5 1310 | snmg1 1311 | snpl01 1312 | sobane 1313 | sociaaltarief 1314 | sociaaltarief-acc 1315 | social-assistance 1316 | socialassistance 1317 | sociale-zaken 1318 | socialeconomy 1319 | socialeeconomie 1320 | socialeverkiezingen 1321 | socialezekerheid 1322 | socialsecurity 1323 | soctar 1324 | soctar-acc 1325 | sof 1326 | sos 1327 | sos112 1328 | sozialesicherheit 1329 | sozialtarif 1330 | sp 1331 | spam 1332 | spp 1333 | sql 1334 | ssc 1335 | ssh 1336 | staatsblad 1337 | staatsrat 1338 | starfighter 1339 | statbel 1340 | stats 1341 | stcw95 1342 | stis 1343 | stor01 1344 | studentaanhetwerk 1345 | studentatwork 1346 | style 1347 | suche 1348 | supremeadministrativecourt 1349 | survey 1350 | surveykce 1351 | sw 1352 | swtc02 1353 | sylvie 1354 | ta 1355 | taalnet 1356 | taccp 1357 | taggingmanager 1358 | tarifsocial 1359 | tarifsocial-acc 1360 | tax-on-web 1361 | tax-web 1362 | taxonweb 1363 | taxweb 1364 | tct 1365 | tedc 1366 | telcobel 1367 | telerad 1368 | telnet 1369 | temporary 1370 | temporary-acc 1371 | test 1372 | test-kbo-bce-select 1373 | test2 1374 | test3 1375 | testdiv 1376 | testmark2 1377 | testncsa 1378 | tewerkstelling 1379 | tipsentrics 1380 | tmd 1381 | tourstat 1382 | tr 1383 | training 1384 | traitements 1385 | tralal 1386 | transis 1387 | transport 1388 | travail 1389 | treasury 1390 | trends 1391 | tse 1392 | tu 1393 | tularemia 1394 | tularemie 1395 | upload 1396 | urbain 1397 | urbainacc 1398 | var 1399 | varkenspest 1400 | vbv 1401 | vbv-cprr 1402 | vbvcprr 1403 | veniceclub 1404 | vereenvoudiging 1405 | verkeer 1406 | verkiezingen 1407 | verkiezingsuitslagen 1408 | vervoer 1409 | vetera 1410 | veterans 1411 | veteransandvictims 1412 | vici 1413 | victims 1414 | vigilis 1415 | voedselveiligheid 1416 | vogelgriep 1417 | vogelpest 1418 | voip 1419 | volksgesundheit 1420 | volksgezondheid 1421 | volkstelling 1422 | volkstelling2011 1423 | vpn 1424 | vpn1 1425 | vpn2 1426 | vps 1427 | vrouwenpensioen 1428 | vsp 1429 | vspp 1430 | w 1431 | wahlen 1432 | warveterans 1433 | warvictims 1434 | web 1435 | web2 1436 | webaccess 1437 | webadmin 1438 | webcache 1439 | webdev 1440 | webdiv 1441 | webgids 1442 | webguide 1443 | webibz 1444 | webinterface 1445 | webmail 1446 | webmittelstand 1447 | webserver 1448 | website 1449 | websurveys 1450 | webtranslation 1451 | webtranslations 1452 | wedden 1453 | weekvandevervoering 1454 | weekvanvervoering 1455 | werk 1456 | westlant 1457 | win 1458 | windows 1459 | workinginbelgium 1460 | ww 1461 | www 1462 | www2 1463 | wwww 1464 | xbrl 1465 | xbrl-acc 1466 | xbrl-tst 1467 | xml 1468 | xmmxprod1 1469 | zdfagehaelter 1470 | zdfagehalter 1471 | zdfageh\228lter 1472 | zdfapensionen 1473 | zensus 1474 | zensus2011 1475 | zfa 1476 | zilverfonds 1477 | zoek 1478 | _sip 1479 | _spf 1480 | _tls 1481 | -------------------------------------------------------------------------------- /dnsenum.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # 4 | # dnsenum.pl VERSION 1.2.4 5 | # This version: - changed version number to the correct one 6 | # 7 | # dnsenum.pl: multithread script to enumerate information on 8 | # a domain and to discover non-contiguous ip blocks. 9 | # 10 | # 1) Get the host's addresse. 11 | # 2) Get the nameservers (threaded). 12 | # 3) get the MX record (threaded). 13 | # 4) Perform axfr queries on nameservers (threaded). 14 | # 5) Get extra names via google scraping. 15 | # 6) Brute force subdomains from file (threaded). 16 | # 7) Calculate C class domain network ranges and perform whois 17 | # queries on them (threaded). 18 | # 8) Perform reverse lookups on C class or/and whois 19 | # network ranges (threaded). 20 | # 9) Write to domain_ips.txt file non-contiguous ip-blocks results. 21 | # 22 | # run perldoc on this script for help. 23 | # 24 | # To install needed modules: 25 | # sudo perl -MCPAN -e shell 26 | # and then e.g.: cpan[1]> install XML::Writer 27 | # 28 | # Copyright (C) 2014 - Filip Waeytens, tixxDZ 29 | # 30 | # This program is free software; you can redistribute it and/or 31 | # modify it under the terms of the GNU General Public License as 32 | # published by the Free Software Foundation; either version 2 of 33 | # the License, or (at your option) any later version. 34 | # 35 | # This program is distributed in the hope that it will be useful, but 36 | # WITHOUT ANY WARRANTY; without even the implied warranty of 37 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 38 | # General Public License for more details. 39 | # 40 | # You should have received a copy of the GNU General Public License along 41 | # with this program; if not, write to the Free Software Foundation, 42 | # Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 43 | # 44 | # 45 | # Special thanks to all perl developers. 46 | # 47 | # please see perldoc dnsenum.pl for options and arguments 48 | 49 | use strict; 50 | use warnings;#it complains about uninitialized values when it doesn't find address in RR; need to fix later 51 | use Config; 52 | use Term::ANSIColor; 53 | use Getopt::Long; 54 | use IO::File; 55 | use Net::IP; 56 | use Net::DNS; 57 | use Net::Netmask; 58 | use XML::Writer; 59 | use Socket; 60 | use String::Random; 61 | 62 | my ($ithreads_support, $whois_support, $mech_support, $html_support,$xml_support); 63 | 64 | my (%nameservers, %allsubs, %googlesubs); 65 | my (%filesubs, %netranges, %recursubs); 66 | my (@mxservers, @results, @ipblocks, @privateips); 67 | my ($enum, $exp, $help, $noreverse, $nocolor, $update, $whois, $dnsserver); 68 | my ($private, $recursion, $scrap, $threads, $verbose); 69 | my ($dnsfile, $subfile, $dns_tmp, $sub_tmp, $fileips); 70 | my ($domain, $recur, $table, $extend_b, $extend_r); 71 | my ($timeout, $delay, $pages, $ipcount, $ipvalid) = (10, 3, 5, 0, 0); 72 | my ($output); 73 | my $writer; 74 | my $program = 'dnsenum.pl'; 75 | my $string_gen = String::Random->new; 76 | my $wildcards = $string_gen->randpattern("cccccccccccc"); 77 | my @wildcardaddress; 78 | my @wildcardcname; 79 | my $VERSION = '1.2.4'; 80 | 81 | #load threads modules (perl must be compiled with ithreads support) 82 | BEGIN { 83 | if ($Config{useithreads}){ 84 | eval(" use threads; 85 | use threads::shared; 86 | use Thread::Queue; 87 | "); 88 | $ithreads_support = 1 unless $@; 89 | } 90 | } 91 | 92 | eval("use Net::Whois::IP qw(whoisip_query);"); 93 | $whois_support = 1 unless $@; 94 | 95 | eval("use WWW::Mechanize;"); 96 | $mech_support = 1 unless $@; 97 | 98 | eval("use HTML::Parser;"); 99 | $html_support = 1 unless $@; 100 | 101 | eval("use XML::Writer;"); 102 | $xml_support = 1 unless $@; 103 | 104 | 105 | print STDOUT $program, " VERSION:", $VERSION, "\n"; 106 | 107 | GetOptions ( 'dnsserver=s' => \$dnsserver, 108 | 'enum' => \$enum, 109 | 'd|delay=i' => \$delay, 110 | 'e|exclude=s' => \$exp, 111 | 'f|file=s' => \$dnsfile, 112 | 'h|help' => \$help, 113 | 'noreverse' => \$noreverse, 114 | 'nocolor' => \$nocolor, 115 | 'p|pages=i' => \$pages, 116 | 'private' => \$private, 117 | 'r|recursion' => \$recursion, 118 | 's|scrap=i' => \$scrap, 119 | 'subfile=s' => \$subfile, 120 | 'threads=i' => \$threads, 121 | 't|timeout=i' => \$timeout, 122 | 'u|update=s' => \$update, 123 | 'v|verbose' => \$verbose, 124 | 'w|whois' => \$whois, 125 | 'o|out=s' => \$output); 126 | 127 | usage() if $help || @ARGV == 0; 128 | 129 | $domain = lc $ARGV[0]; 130 | $fileips = $domain.'_ips.txt'; 131 | 132 | #DEFAULT options --threads 5 -s 15 -w 133 | if ($enum) { 134 | $threads = 5; 135 | $scrap = 15;# Google scraping default to 15 to avoid Google Blocking us with captcha's 136 | $whois = 1; 137 | } 138 | 139 | #module support 140 | if ($threads) { 141 | 142 | if ((!defined $ithreads_support and 143 | warn "Warning: can't use threads, check ithreads support, and ". 144 | "(threads, threads::shared, Thread::Queue) modules.\n") || 145 | $threads <= 0) { 146 | $threads = undef; 147 | } 148 | else { 149 | #to handle different ips that belongs to the domain 150 | share(@results); 151 | 152 | #number of ips that will be queried in reverse lookup 153 | share($ipcount); 154 | 155 | #number of valid ips (taken from reverse lookup responses) 156 | share($ipvalid); 157 | 158 | #will contain all valid subdomains 159 | share(%allsubs); 160 | 161 | if ($recursion) { 162 | share(%recursubs); 163 | share(%nameservers); 164 | } 165 | 166 | #to save whois netblocks 167 | share($table); 168 | 169 | #whois and reverse lookup results 170 | share(%netranges); 171 | } 172 | } 173 | 174 | if ($whois && !defined $whois_support) { 175 | warn "Warning: can't load Net::Whois::IP module, ". 176 | "whois queries disabled.\n"; 177 | $whois = undef; 178 | } 179 | if ($whois && !defined $whois_support) { 180 | warn "Warning: can't load Net::Whois::IP module, ". 181 | "whois queries disabled.\n"; 182 | $whois = undef; 183 | } 184 | if ($output && !defined $xml_support) { 185 | warn "Warning: can't load XML::Writer module, ". 186 | "xml output disabled.\n"; 187 | $output = undef; 188 | } 189 | if(defined($output)) { 190 | my $out = new IO::File(">$output"); 191 | $writer = new XML::Writer(OUTPUT=>$out); 192 | $writer->xmlDecl("UTF-8"); 193 | $writer->startTag("magictree", "class"=>"MtBranchObject"); 194 | $writer->startTag("testdata", "class"=>"MtBranchObject"); 195 | } 196 | 197 | $scrap = undef 198 | if $scrap && ((not defined $mech_support and 199 | warn "Warning: can't load WWW::Mechanize module". 200 | ", Google scraping desabled.\n") || 201 | (not defined $html_support and 202 | warn "Warning: can't load HTML::Parser module". 203 | ", Google scraping desabled.\n") || 204 | $scrap <= 0 || $pages <= 0); 205 | 206 | $timeout = 10 if $timeout < 0 || $timeout > 128; 207 | $delay = 3 if $delay < 0; 208 | 209 | $update = undef if $update && !$dnsfile; 210 | unless ($nocolor) { 211 | print color 'bold blue'; 212 | } 213 | print STDOUT "\n----- ", $domain ," -----\n"; 214 | unless ($nocolor) { 215 | print color 'reset'; 216 | } 217 | ################START##################### 218 | 219 | # (1) get the host's addresses 220 | printheader ("Host's addresses:\n"); 221 | my $res = Net::DNS::Resolver->new( tcp_timeout => $timeout, 222 | udp_timeout => $timeout, 223 | defnames => 0); 224 | 225 | $res->nameservers($dnsserver) if $dnsserver; 226 | 227 | my $packet = $res->query($domain); 228 | if ($packet) { 229 | foreach my $rr (grep { $_->type eq 'A' } $packet->answer) { 230 | printrr($rr->string); 231 | xml_host($rr); 232 | push @results, $rr->address 233 | if $rr->name =~ /$domain$/; 234 | } 235 | } 236 | elsif ($verbose) { 237 | warn " ", $domain ," A query failed: ", $res->errorstring, "\n"; 238 | } 239 | 240 | # wildcards test - I guess it can be cleaner, but it seems to be working 241 | # tested with opendns servers and ubuntu.org domain 242 | 243 | print STDOUT "\n"."-" x 16 ."\nWildcards test:\n"."-" x 16 ."\n" 244 | if $verbose; 245 | my $wildcardpacket=$res->query($wildcards.".".$domain); 246 | # if we get a response resolving our random hostname, it can be a A or a CNAME 247 | if ($wildcardpacket) { 248 | printheader ("Wildcard detection using: ".$wildcards."\n"); 249 | foreach my $rr ($wildcardpacket->answer) { 250 | 251 | if ($rr->type eq 'A') 252 | { 253 | printrr($rr->string); 254 | #wildcardaddress will hold the IP that's used as a string 255 | my @wcheck= split('\s+',$rr->string); 256 | push @wildcardaddress, $wcheck[4]; 257 | 258 | } 259 | if ($rr->type eq 'CNAME') 260 | { 261 | printrr($rr->string); 262 | #wildcardcname will hold CNAME that's used as a string 263 | my @wcheck= split('\s+',$rr->string); 264 | push @wildcardcname, $wcheck[4]; 265 | 266 | } 267 | } 268 | 269 | unless ($nocolor) { 270 | print color 'bold red'; 271 | } 272 | print "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"; 273 | print STDOUT " Wildcards detected, all subdomains will point to the same IP address\n"; 274 | print STDOUT " Omitting results containing ".join(', ', @wildcardaddress).".\n Maybe you are using OpenDNS servers.\n"; 275 | print "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; 276 | 277 | unless ($nocolor) { 278 | print color 'reset'; 279 | } 280 | 281 | #exit(1);#we don't exit when wildcards are detected, because we will miss existing hosts 282 | } 283 | 284 | elsif ($verbose) { 285 | print STDOUT " good\n"; 286 | } 287 | 288 | # (2) get the namservers for the domain 289 | printheader ("Name Servers:\n"); 290 | $packet = $res->query($domain, 'NS'); 291 | if ($packet) { 292 | 293 | foreach my $rr (grep { $_->type eq 'NS' } $packet->answer) { 294 | $nameservers{$rr->nsdname} = 1; 295 | } 296 | 297 | die " Error: can't continue no NS record for " , $domain ,"\n" 298 | unless %nameservers; 299 | 300 | #read the A record from the additional section 301 | if ($packet->header->arcount) { 302 | my @remain = additionalrecord($packet, keys %nameservers); 303 | #do nslookup on nameservers that are not present in the 304 | #additional section 305 | launchqueries(\&nslookup, @remain) 306 | if scalar @remain; 307 | } 308 | #perform the nslookup on the nameservers 309 | else { 310 | launchqueries(\&nslookup, keys %nameservers); 311 | } 312 | } 313 | #exit if there is no NS record. 314 | else { 315 | die " ", $domain ," NS record query failed: ", 316 | $res->errorstring , "\n"; 317 | } 318 | 319 | # (3) get the MX record 320 | printheader ("Mail (MX) Servers:\n"); 321 | $packet = $res->query($domain, 'MX'); 322 | if ($packet) { 323 | 324 | foreach my $rr (grep { $_->type eq 'MX' } $packet->answer) { 325 | push @mxservers, $rr->exchange; 326 | } 327 | if (scalar @mxservers) { 328 | if ($packet->header->arcount) { 329 | my @remain = additionalrecord($packet, @mxservers); 330 | launchqueries(\&nslookup, @remain) 331 | if scalar @remain; 332 | } 333 | else { 334 | launchqueries(\&nslookup, @mxservers); 335 | } 336 | } 337 | } 338 | elsif ($verbose) { 339 | warn " ", $domain ," MX record query failed: ", 340 | $res->errorstring, "\n"; 341 | } 342 | 343 | # (4) perform zonetransfers on nameservers 344 | printheader ("Trying Zone Transfers and getting Bind Versions:\n"); 345 | launchqueries(\&zonetransfer, keys %nameservers); 346 | 347 | 348 | # (5) scrap additional names from google search and do nslookup on them 349 | if ($scrap) { 350 | printheader ("Scraping ".$domain." subdomains from Google:\n"); 351 | my @tmp = googlescraping(); 352 | if (scalar @tmp) { 353 | #print STDOUT "\n Performing nslookups:\n"; 354 | launchqueries(\&nslookup, map { $_ .= '.'.$domain } @tmp); 355 | } 356 | } 357 | 358 | #exit if the brute force file is not specified 359 | unless ($dnsfile) { 360 | print STDOUT "\nbrute force file not specified, bay.\n"; 361 | if(defined($output)) { 362 | $writer->endTag('testdata'); 363 | $writer->endTag('magictree'); 364 | } 365 | exit(0); 366 | } 367 | 368 | $extend_b = 1 if ($update && $update eq 'a') || $subfile || $recursion; 369 | 370 | # (6) brute force subdomains from a file 371 | 372 | printheader ("Brute forcing with ".$dnsfile.":\n"); 373 | bruteforce('f'); 374 | 375 | #updating dnsfile with zonetransfer or googlescraping subdomains results 376 | if ($update) { 377 | 378 | if ($dns_tmp = IO::File->new_tmpfile()) { 379 | if ($update eq 'z') { 380 | print $dns_tmp $_, "\n" 381 | for uniq_hosts(grep { 382 | $allsubs{$_} eq $update 383 | } keys %allsubs); 384 | } 385 | elsif ($update eq 'g') { 386 | print $dns_tmp $_, "\n" 387 | for uniq_hosts(keys %googlesubs); 388 | } 389 | } 390 | else { 391 | die "Error can't create a temporary file: $!, ". 392 | "to update ", $dnsfile ," file\n"; 393 | } 394 | } 395 | 396 | undef %googlesubs if %googlesubs; 397 | 398 | #launch recursion 399 | if ($recursion) { 400 | if (%allsubs) { 401 | printheader("Performing recursion:\n"); 402 | 403 | print STDOUT "\n ---- Checking subdomains NS records ----\n"; 404 | 405 | #select subdomains that are able to recursion 406 | launchqueries(\&selectsubdomains, 407 | map { $_ .= '.'.$domain } sort keys %allsubs); 408 | 409 | if (%recursubs) { 410 | my @tmp = keys %recursubs; 411 | undef %recursubs; 412 | 413 | #brute force from a list using recursion 414 | bruteforce('l', \@tmp); 415 | } 416 | else { 417 | print STDERR "\n Can't perform recursion ". 418 | "no NS records.\n"; 419 | } 420 | } 421 | else { 422 | print STDERR "\n Can't perform recursion no subdomains.\n"; 423 | } 424 | undef %filesubs; 425 | } 426 | 427 | #updating the brute force file (-u a switch) 428 | if ($update && ($update eq 'a' || $update eq 'all')) { 429 | 430 | #save ns and mx servers 431 | my @tmp = keys %nameservers; 432 | push @tmp, @mxservers if scalar @mxservers; 433 | 434 | print $dns_tmp $_, "\n" 435 | for uniq_hosts(grep { s/\.$domain// } @tmp); 436 | print $dns_tmp $_, "\n" for uniq_hosts(keys %allsubs); 437 | } 438 | 439 | #write subdomains to the subfile 440 | if ($subfile) { 441 | if ($sub_tmp = IO::File->new_tmpfile()) { 442 | my %uniq; 443 | @uniq{keys %nameservers} = (); 444 | @uniq{@mxservers} = () if scalar @mxservers; 445 | 446 | print $sub_tmp $_, "\n" 447 | for grep { s/\.$domain// } keys %uniq; 448 | 449 | print $sub_tmp $_, "\n" for keys %allsubs; 450 | } 451 | else { 452 | die "Error can't create a temporary file: $!, ". 453 | " to save results to ", $subfile ," file\n"; 454 | } 455 | } 456 | 457 | undef @mxservers; 458 | undef %allsubs; 459 | 460 | # (7) get domain network ranges from brute force results and whois queries 461 | @results = networkranges(@results); 462 | undef %netranges; 463 | 464 | # (8) perform reverse lookups on netranges (class C or whois netranges) 465 | unless ($noreverse) { 466 | 467 | #to save all valid subdomains discovred in 468 | #the reverse lookup process 469 | $extend_r = 1 470 | if ($update && ($update eq 'r' || $update eq 'a' || 471 | $update eq 'all')) || $subfile; 472 | printheader("Performing reverse lookup on ".$ipcount." ip addresses:\n"); 473 | launchqueries(\&reverselookup, @results); 474 | 475 | print STDOUT "\n", $ipvalid ," results out of ", 476 | $ipcount ," IP addresses.\n"; 477 | } 478 | else { 479 | #calculate ip blocks 480 | @ipblocks = finalvalidips(sort_by_ip_address(@results)); 481 | } 482 | 483 | #save final IP blocks to the domain_ips.txt file 484 | writetofile($fileips, "w", @ipblocks); 485 | 486 | #show private ips 487 | if ($private && scalar @privateips) { 488 | 489 | print STDOUT "\n"."-" x 26 ."\n", 490 | $domain ," private ips:\n". 491 | "-" x 26 ."\n"; 492 | print STDOUT " ", $_ , "\n" for @privateips; 493 | 494 | #save private ips to domain_ips.txt file 495 | writetofile($fileips, "a+", @privateips); 496 | } 497 | 498 | # (9) show non-contiguous IP blocks 499 | printheader($domain." ip blocks:\n"); 500 | print STDOUT " ", $_ , "\n" for @ipblocks; 501 | 502 | #clean the brute force file 503 | cleanfile($dnsfile, $dns_tmp) if $update; 504 | 505 | #clean the subfile 506 | cleanfile($subfile, $sub_tmp) if $subfile; 507 | 508 | if(defined($output)) { 509 | $writer->endTag('testdata'); 510 | $writer->endTag('magictree'); 511 | } 512 | 513 | 514 | print STDOUT "\ndone.\n"; 515 | 516 | exit(0); 517 | 518 | #-------------------------------------------------- 519 | 520 | #subroutine that will launch different queries 521 | #(nslookup, zonetransfer, whoisip, reverselookup) 522 | sub launchqueries { 523 | 524 | my $querytype = shift; 525 | 526 | if ($querytype != \&reverselookup) { 527 | 528 | if ($threads) { 529 | my $stream = new Thread::Queue; 530 | $stream->enqueue(@_); 531 | my $thrs = $threads; #don't create unused threads 532 | $thrs = scalar @_ if $threads > scalar @_; 533 | 534 | for (1 .. $thrs) { 535 | threads->new($querytype, \$stream); 536 | } 537 | #wait all threads 538 | foreach (threads->list) { 539 | $_->join 540 | if ($_->tid && 541 | !threads::equal($_, threads->self)); 542 | } 543 | } 544 | else { 545 | foreach (@_) { 546 | &$querytype($_); 547 | } 548 | } 549 | } 550 | else { 551 | foreach (@_) { 552 | my $block = new2 Net::Netmask($_); 553 | unless ($block) { 554 | print STDERR " Can't perform reverse lookup: " 555 | , $Net::Netmask::error ,"\n"; 556 | next; 557 | } 558 | 559 | if ($threads) { 560 | my $stream = new Thread::Queue; 561 | $stream->enqueue($block->enumerate); 562 | 563 | for (1 .. $threads) { 564 | threads->new($querytype, \$stream); 565 | } 566 | #wait all threads 567 | foreach (threads->list) { 568 | $_->join 569 | if ($_->tid && 570 | !threads::equal($_, threads->self)); 571 | } 572 | } 573 | else { 574 | &$querytype($block->enumerate); 575 | } 576 | 577 | #calculate IP blocks results 578 | if (%netranges) { 579 | my @tmp = finalvalidips( 580 | sort_by_ip_address(keys %netranges)); 581 | undef %netranges; 582 | 583 | #get final valid ip blocks 584 | push @ipblocks, @tmp; 585 | } 586 | 587 | #write reverse lookup hostnames results to files 588 | if ($extend_r && %allsubs) { 589 | 590 | if ($update && ($update eq 'r' || 591 | $update eq 'a' || $update eq 'all')) { 592 | print $dns_tmp $_, "\n" 593 | for uniq_hosts(keys %allsubs); 594 | } 595 | if ($subfile) { 596 | print $sub_tmp $_, "\n" 597 | for keys %allsubs; 598 | } 599 | undef %allsubs; 600 | } 601 | } 602 | } 603 | } 604 | 605 | #subroutine to perform reverse lookups 606 | sub reverselookup { 607 | 608 | my $stream = shift if $threads; 609 | 610 | my $res = Net::DNS::Resolver->new( 611 | tcp_timeout => $timeout, 612 | udp_timeout => $timeout, 613 | persistent_udp => 1); 614 | 615 | $res->nameservers(keys %nameservers); 616 | 617 | while (defined(my $ip = $threads ? $$stream->dequeue_nb : shift)) { 618 | 619 | my $query = $res->query($ip); 620 | if ($query) { 621 | foreach my $rr ( grep { $_->type eq 'PTR' } 622 | $query->answer) { 623 | 624 | #exclude non PTR types answers or unwanted hostnames 625 | next if $exp && $rr->ptrdname =~ /$exp/; 626 | 627 | if ($rr->ptrdname =~ /(.*)(\.$domain$)/i) { 628 | 629 | $allsubs{$1} = 1 630 | if $extend_r && !$allsubs{$1}; 631 | 632 | #to calculate last valid ip blocks 633 | unless ($netranges{$ip}) { 634 | $netranges{$ip} = 1; 635 | $ipvalid++; 636 | } 637 | printrr($rr->string); 638 | xml_host($rr); 639 | } 640 | #show all answers even if the hostname don't match the domain 641 | elsif ($verbose) { 642 | printrr($rr->string); 643 | xml_host($rr); 644 | } 645 | } 646 | } 647 | #this part is just to check progress 648 | elsif ($verbose) { 649 | print STDOUT " ", $ip ," ...\n"; 650 | } 651 | } 652 | } 653 | 654 | sub xml_host { 655 | if(defined $output) { 656 | my $rr = shift; 657 | my $ip; 658 | if($rr->type eq 'A') { 659 | $ip = $rr->address; 660 | } else { 661 | my $packed_ip = gethostbyname($rr->name); 662 | if (defined $packed_ip) { 663 | $ip = inet_ntoa($packed_ip); 664 | } 665 | } 666 | if(defined($ip)) { 667 | $writer->startTag("host"); 668 | $writer->characters($ip); 669 | $writer->startTag("hostname"); 670 | $writer->characters($rr->name); 671 | $writer->endTag("hostname"); 672 | $writer->endTag("host"); 673 | } 674 | $writer->startTag("fqdn"); 675 | $writer->characters($rr->name . '.'); 676 | $writer->endTag("fqdn"); 677 | } 678 | } 679 | 680 | #subroutine for nslookups (A record) 681 | sub nslookup { 682 | 683 | my $stream = shift if $threads; 684 | 685 | my $res = Net::DNS::Resolver->new( tcp_timeout => $timeout, 686 | udp_timeout => $timeout, 687 | persistent_udp => 1, 688 | dnsrch => 0); 689 | $res->nameservers($dnsserver) if $dnsserver; 690 | 691 | while (defined(my $host = $threads ? $$stream->dequeue_nb : shift)) { 692 | 693 | my $query = $res->search($host); 694 | 695 | if ($query) { 696 | foreach my $rr ($query->answer) { 697 | ##we only print / add the result if it doesn't match the wildcardaddress 698 | if (!($rr->can('address') && $rr->address ~~ @wildcardaddress) && !($rr->name ~~ @wildcardcname)) 699 | { 700 | printrr($rr->string); 701 | xml_host($rr); 702 | 703 | #check if it match the domain 704 | if ($rr->name =~ /(.*)(\.$domain$)/i) { 705 | 706 | #save valid subdomains 707 | if ($extend_b) { 708 | $allsubs{$1} = 1 709 | unless $allsubs{$1}; 710 | 711 | #recursion results 712 | $recursubs{$1} = 1 713 | if $recur && 714 | !$recursubs{$1}; 715 | } 716 | #save ip address 717 | push @results, $rr->address 718 | if $rr->type eq 'A'; 719 | } 720 | } 721 | 722 | } 723 | } 724 | 725 | elsif ($verbose) { 726 | warn " ", $host ," A record query failed: ", 727 | $res->errorstring, "\n"; 728 | } 729 | } 730 | } 731 | 732 | #subroutine to select subdomains that have NS records 733 | sub selectsubdomains { 734 | 735 | my $stream = shift if $threads; 736 | 737 | my $res = Net::DNS::Resolver->new( tcp_timeout => $timeout, 738 | udp_timeout => $timeout, 739 | persistent_udp => 1); 740 | 741 | $res->nameservers($dnsserver) if $dnsserver; 742 | 743 | while (defined(my $host = $threads ? $$stream->dequeue_nb : shift)) { 744 | my $packet = $res->query($host, 'NS'); 745 | 746 | if ($packet) { 747 | 748 | foreach my $rr (grep { $_->type eq 'NS' } 749 | $packet->answer) { 750 | 751 | #show all results 752 | #print STDOUT " ", $rr->string ,"\n"; 753 | printrr($rr->string); 754 | xml_host($rr); 755 | 756 | if ($rr->name =~ /(.*)(\.$domain$)/i) { 757 | 758 | if (!$allsubs{$1} || 759 | $allsubs{$1} ne 'r') { 760 | 761 | #bookmark this hostname to 762 | #perform recursion on it and 763 | #to avoid repetition, because 764 | #some domains will use CNAME 765 | #types that point to subs 766 | #that we have already 767 | #processed in a previous 768 | #recursion levels 769 | $allsubs{$1} = 'r'; 770 | 771 | #select this subdomain 772 | #for recursion 773 | $recursubs{$rr->name} = 1; 774 | } 775 | 776 | #perhaps for future additions we save 777 | #ns servers for each domain or 778 | #subdomain, this will be very 779 | #useful in reverse lookup 780 | 781 | # --- begin --- 782 | #check if we already have this 783 | #NS server 784 | #next if $nameservers{$rr->nsdname}; 785 | 786 | #$nameservers{$rr->nsdname} = 1; 787 | #push @tmp, $rr->nsdname; 788 | # --- end --- 789 | } 790 | } 791 | 792 | #perhaps for future additions to perform an extrem 793 | #recursion to get the IP addresse of the NS servers 794 | 795 | # --- begin --- 796 | #next unless scalar @tmp; 797 | 798 | #get the NS servers A record 799 | #if ($packet->header->arcount) { 800 | # @tmp = additionalrecord($packet,@tmp); 801 | # next unless scalar @tmp; 802 | #} 803 | 804 | #foreach my $nshost (@tmp) { 805 | # $packet = $res->query($nshost); 806 | # if ($packet) { 807 | # foreach my $rr \ 808 | # (grep { $_->type eq 'A' } 809 | # $packet->answer) { 810 | # print STDOUT " ", 811 | # $rr->string , "\n"; 812 | # push @results, $rr->address 813 | # if ($rr->name =~ /$domain$/); 814 | # } 815 | # } 816 | # elsif ($verbose) { 817 | # warn " ", $nshost , 818 | # " A record query failed: ", 819 | # $res->errorstring , "\n"; 820 | # } 821 | #} 822 | # --- end --- 823 | } 824 | elsif ($verbose) { 825 | warn " ", $host ," NS record query failed: ", 826 | $res->errorstring , "\n"; 827 | } 828 | } 829 | } 830 | 831 | #subroutine for zonetransfers 832 | #I got rid of the Bind Versions search...doesn't really add anything and clutters output 833 | sub zonetransfer { 834 | 835 | my $stream = shift if $threads; 836 | 837 | my $res = Net::DNS::Resolver->new( tcp_timeout => $timeout, 838 | udp_timeout => $timeout); 839 | 840 | while (defined(my $ns = $threads ? $$stream->dequeue_nb : shift)) { 841 | $res->nameservers($ns); 842 | 843 | my @zone = $res->axfr($domain); 844 | #my $version_query = $res->search("version.bind","TXT","CH"); 845 | print STDOUT "\nTrying Zone Transfer for ", $domain , 846 | " on ", $ns ," ... \n"; 847 | 848 | if (@zone) { 849 | foreach my $rr (@zone) { 850 | #print all results 851 | printrr($rr->string); 852 | xml_host($rr); 853 | 854 | #save data if the record's domain name 855 | #match the domain 856 | if ($rr->name =~ /(.*)(\.$domain$)/i) { 857 | 858 | #save hostname 859 | $allsubs{$1} = 'z' 860 | unless $allsubs{$1}; 861 | 862 | #save the IP address 863 | push @results, $rr->address 864 | if $rr->type eq 'A'; 865 | 866 | #save new mx servers hostnames 867 | push @mxservers, $rr->exchange 868 | if $rr->type eq 'MX'; 869 | 870 | #perhaps for future additions 871 | #save NS servers for reverse lookups 872 | # --- begin --- 873 | #$nameservers{$rr->nsdname} = 1 874 | # if ($rr->type eq 'NS' && 875 | # !$nameservers{$rr->nsdname}); 876 | # --- end --- 877 | } 878 | } 879 | } 880 | else { 881 | warn "AXFR record query failed: ", 882 | $res->errorstring, "\n"; 883 | } 884 | } 885 | } 886 | 887 | #subroutine for scraping domains from google 888 | sub googlescraping { 889 | 890 | my ($response, $browser, $form, $parser, $nextpage); 891 | my ($count, $mypage) = (0,1); 892 | my $query = qq[allinurl: -www site:$domain]; 893 | my $nexturl = qq[/search?.*q=.*$domain.*start]; 894 | 895 | #on errors the mech object will call die 896 | $browser = WWW::Mechanize->new( autocheck => 1, 897 | stack_depth => 1, 898 | cookie_jar => undef); 899 | #uncomment for debugging with BURP 900 | #$browser->proxy(['http'], 'http://127.0.0.1:8080'); 901 | #setup the browser config 902 | my @agents = $browser->known_agent_aliases(); 903 | my $agent = $agents[rand(scalar @agents)]; 904 | $browser->agent_alias($agent); 905 | $browser->timeout($timeout); 906 | 907 | #get the first page 908 | $response = $browser->get("http://www.google.com/ncr"); 909 | 910 | $form = $browser->form_number(1) 911 | or return; 912 | 913 | $form->find_input('q')->value($query); 914 | $response = $browser->submit_form( form_number => 1, 915 | form_name => 'f'); 916 | do { 917 | $nextpage = undef; 918 | print STDOUT "\n ---- Google search page: ", 919 | $mypage ," ---- \n\n"; 920 | 921 | $parser = HTML::Parser->new( 922 | api_version => 3, 923 | start_h => [sub { 924 | my $attr = shift; 925 | 926 | #end of parsing 927 | #(we have enough subdomains) 928 | $parser->eof 929 | unless $count < $scrap; 930 | 931 | return unless $attr->{href}; 932 | 933 | #subdomains checks - if shit goes wrong with googlescraping it's prolly the regex 934 | if ($attr->{href} =~ 935 | /(\/url\?q\=http:\/\/)([\w\.-]+)(\.$domain\/)/) { 936 | 937 | $allsubs{$2} = 'g' 938 | unless $allsubs{$2}; 939 | 940 | $googlesubs{$2} = 1 941 | unless $googlesubs{$2}; 942 | 943 | print STDOUT " ", $2 ,"\n"; 944 | $count++; 945 | } 946 | #the next page 947 | elsif ($attr->{href} =~ 948 | /^$nexturl=$mypage\d.*/ && 949 | !defined $nextpage) { 950 | $nextpage = $attr->{href}; 951 | } 952 | },'attr'] 953 | ); 954 | 955 | $parser->parse($response->decoded_content); 956 | 957 | if ($nextpage) { 958 | $response = $browser->get($nextpage); 959 | $mypage++; 960 | } 961 | 962 | } while ($count < $scrap && $mypage <= $pages && $nextpage); 963 | 964 | #print STDOUT "\n Google results: ", $count ,"\n"; 965 | printheader("Google Results:\n"); 966 | if ($count) { 967 | return grep { $allsubs{$_} eq 'g' } keys %allsubs; 968 | } 969 | else { 970 | print STDERR " perhaps Google is blocking our queries.\n Check manually.\n"; 971 | return; 972 | } 973 | } 974 | 975 | #subroutine to query a whois server for an IP address to get the correct netrange 976 | sub whoisip { 977 | 978 | my $stream = shift if $threads; 979 | 980 | while (defined(my $ip = $threads ? $$stream->dequeue_nb : shift)) { 981 | my ($inetnum, $block); 982 | 983 | #search in the network blocks table to find 984 | #if any of them contains the IP address 985 | next if (findAllNetblock($ip, $table)); 986 | 987 | #this is very useful on whois servers 988 | #that limit the number of connections 989 | sleep rand $delay; 990 | 991 | #catch different exceptions 992 | #(on exceptions netrange will be a class C /24) 993 | eval { 994 | my $response = whoisip_query($ip); 995 | foreach (keys %{$response}) { 996 | 997 | next if ($_ !~ /^(inetnum|netrange)$/i); 998 | 999 | $inetnum = $response->{$_}; 1000 | 1001 | #handle all whois netrange format 1002 | if ($inetnum =~ /([\d.\.]+)\/(\d{1,2})/) { 1003 | #whois.lacnic.net format 1004 | $block = new2 Net::Netmask (qq[$1/$2]); 1005 | } 1006 | else { 1007 | $inetnum =~ s/\s//g; 1008 | $block = new2 Net::Netmask ($inetnum); 1009 | } 1010 | 1011 | if ($block) { 1012 | 1013 | # this is useful when threads are enabled to eliminate 1014 | # the processing of same netranges 1015 | next if $threads && 1016 | $netranges{$block->desc}; 1017 | 1018 | $block->storeNetblock($table); 1019 | 1020 | #this is a simple workaround to 1021 | #save netblocks in a hash 1022 | #because we will lost all data 1023 | #in $table after threads exit 1024 | #(see Net::Netmask and 1025 | #threads::shared and threads safe) 1026 | #i am soure that there is a beter 1027 | #solution please excuse my ignorance 1028 | $netranges{$block->desc} = 1; 1029 | 1030 | $ipcount += $block->size(); 1031 | printf STDOUT " whois ip result:". 1032 | " %-15s -> %s\n", 1033 | $ip, $block->desc; 1034 | } 1035 | else { 1036 | print STDERR " Netmask error: ", 1037 | $Net::Netmask::error ,"\n" 1038 | if $verbose; 1039 | $inetnum = undef; 1040 | } 1041 | } 1042 | }; 1043 | if ($@) { 1044 | #catch any invalid results 1045 | #assume that the network range is a class C 1046 | print STDERR " Error: ", $@ 1047 | if $verbose; 1048 | $inetnum = undef; 1049 | } 1050 | 1051 | #can't get the netrange form the whois server 1052 | #so we assume that is a class C range (/24) 1053 | unless (defined $inetnum) { 1054 | $block = new Net::Netmask (qq[$ip/24]); 1055 | next if $threads && $netranges{$block->desc}; 1056 | 1057 | $block->storeNetblock($table); 1058 | $netranges{$block->desc} = 1; 1059 | $ipcount += 256; 1060 | printf STDOUT " c class default: ". 1061 | "%-15s -> %s ". 1062 | " (whois netrange operation failed)\n", 1063 | $ip, $block->desc; 1064 | } 1065 | } 1066 | } 1067 | 1068 | #subroutine to brute force subdomains 1069 | sub bruteforce { 1070 | 1071 | #recursion on valid subdomains brute force from a list 1072 | if (shift eq 'l') { 1073 | my ($level, $hosts, @tmp) = 1; 1074 | my $res = Net::DNS::Resolver->new( 1075 | tcp_timeout => $timeout, 1076 | udp_timeout => $timeout, 1077 | persistent_udp => 1, 1078 | dnsrch => 0); 1079 | 1080 | $res->nameservers($dnsserver) if $dnsserver; 1081 | 1082 | #signal to nslookup to save all recursive subdomains 1083 | $recur = 1; 1084 | 1085 | RECURSION: 1086 | $hosts = shift; 1087 | 1088 | print STDOUT "\n ---- Recursion level ", 1089 | $level ," ---- \n"; 1090 | foreach my $host (@$hosts) { 1091 | my (@words, %uniq); 1092 | print STDOUT "\n Recursion on ", $host ," ...\n"; 1093 | 1094 | #wildcards test 1095 | if ($res->search($wildcards.$host)) { 1096 | print STDERR " ", $host , 1097 | ": Wildcards detected.\n"; 1098 | next; 1099 | } 1100 | 1101 | #perform brute force using all hostnames and include the new one 1102 | #(discovered from previous brute forces) 1103 | foreach (sort keys %allsubs, 1104 | grep { not $allsubs{$_} } keys %filesubs) { 1105 | push @words, $_.'.'.$host; 1106 | 1107 | #split hostnames that contain dots 1108 | foreach (split /\./) { 1109 | unless ($allsubs{$_} || 1110 | $filesubs{$_} || $uniq{$_}) { 1111 | $uniq{$_} = 1; 1112 | push @words, $_.'.'.$host; 1113 | } 1114 | } 1115 | } 1116 | launchqueries(\&nslookup, @words); 1117 | } 1118 | 1119 | #can't find new hostnames 1120 | return 1121 | unless @tmp = grep { $allsubs{$_} ne 'r' } keys %recursubs; 1122 | undef %recursubs; 1123 | 1124 | #select subdomains 1125 | printheader("Checking subdomains NS records:\n" ); 1126 | 1127 | launchqueries(\&selectsubdomains, 1128 | map { $_ .= '.'.$domain } sort @tmp); 1129 | 1130 | unless (%recursubs) { 1131 | print STDOUT "\n Can't perform recursion, ". 1132 | "no new NS records.\n" if $verbose; 1133 | return; 1134 | } 1135 | 1136 | @tmp = keys %recursubs; 1137 | undef %recursubs; 1138 | 1139 | $level++; 1140 | @_ = \@tmp; 1141 | goto RECURSION; 1142 | } 1143 | #brute force subdomains from dnsfile 1144 | else { 1145 | my @words; 1146 | die "Error: make sure that the file ", $dnsfile , 1147 | " exists and has a size greater than zero.\n" 1148 | unless -s $dnsfile; 1149 | 1150 | my $input = new IO::File $dnsfile, "r" 1151 | or die "Could not open ", $dnsfile ," file: $!\n"; 1152 | while (<$input>) { 1153 | chomp; 1154 | 1155 | #save subdomains found in the file to use them 1156 | #in the recursion process 1157 | $filesubs{$_} = 1 if $recursion; 1158 | 1159 | #select all subdomains that have not been listed 1160 | push @words, $_.'.'.$domain 1161 | unless $allsubs{$_}; 1162 | } 1163 | $input->close; 1164 | 1165 | scalar @words ? launchqueries(\&nslookup, @words) : 1166 | print STDOUT " Can't find new subdomains.\n"; 1167 | #the names have already been found by zonetransfer, ... 1168 | } 1169 | } 1170 | 1171 | #subroutine to get the domain's network ranges 1172 | sub networkranges { 1173 | my (@cnets, %ips, %seen); 1174 | 1175 | #uniq IP's 1176 | @ips{@_} = (); 1177 | 1178 | foreach my $ip (sort_by_ip_address(keys %ips)) { 1179 | my @octets = split /\./, $ip; 1180 | 1181 | #private IP's 1182 | if ($octets[0] == 10 1183 | || $octets[0] == 127 1184 | || ($octets[0] == 169 && $octets[1] == 254) 1185 | || ($octets[0] == 172 && ($octets[1] > 15 && 1186 | $octets[1] < 32 )) 1187 | || ($octets[0] == 192 && $octets[1] == 168 )) { 1188 | 1189 | #save private ips 1190 | push @privateips, $ip if $private; 1191 | 1192 | delete $ips{$ip}; 1193 | next; 1194 | } 1195 | 1196 | #to get unique class C netranges 1197 | my $net = join("\.",$octets[0],$octets[1],$octets[2]); 1198 | unless ($seen{$net}) { 1199 | $seen{$net} = 1; 1200 | push @cnets, $net.".0"; 1201 | } 1202 | } 1203 | 1204 | #launch whois queries on IP's to get the correct netranges 1205 | if ($whois) { 1206 | printheader("Launching Whois Queries:\n"); 1207 | #shutdown warns the whois ip will catch exceptions with eval 1208 | $SIG{__WARN__} = sub {} ; 1209 | launchqueries(\&whoisip, @cnets); 1210 | $SIG{__WARN__} = 'DEFAULT'; 1211 | 1212 | printheader($domain ," whois netranges:\n"); 1213 | print STDOUT " ", $_ , "\n" for keys %netranges; 1214 | } 1215 | #default class C netrange 1216 | else { 1217 | 1218 | printheader($domain." class C netranges:\n"); 1219 | grep { $_ .= "/24"; print STDOUT " ",$_,"\n"; } @cnets; 1220 | $ipcount = scalar @cnets * 256; 1221 | } 1222 | 1223 | defined $noreverse ? return keys %ips : 1224 | (defined $whois ? return keys %netranges : 1225 | return @cnets); 1226 | } 1227 | 1228 | #subroutine that calculate and return non-contiguous IP blocks 1229 | sub finalvalidips { 1230 | 1231 | my $firstip = shift; 1232 | 1233 | #one single IP address 1234 | return $firstip."/32" unless scalar @_; 1235 | 1236 | my ($lastip, @tmp); 1237 | my $broadcast = $_[$#_]; 1238 | my $tmpip = new Net::IP(qq[$firstip - $broadcast]); 1239 | foreach my $thisip (@_) { 1240 | # increment the previous tmp IP address to compare it with the current 1241 | # IP address taken from the array 1242 | ++$tmpip; 1243 | 1244 | if ($broadcast ne $thisip) { 1245 | #this IP belongs to the current netrange 1246 | if ($tmpip->ip() eq $thisip) { 1247 | $lastip = $thisip; 1248 | } 1249 | #new netrange 1250 | else { 1251 | defined $lastip ? 1252 | push @tmp, range2cidrlist($firstip, $lastip): 1253 | push @tmp, $firstip."/32"; 1254 | 1255 | #update data 1256 | $firstip = $thisip; 1257 | $lastip = undef; 1258 | $tmpip = new Net::IP(qq[$firstip - $broadcast]); 1259 | } 1260 | } 1261 | #we have reached the last valid IP address in the network range 1262 | else { 1263 | #this IP belongs to the current range 1264 | if ($tmpip->ip() eq $broadcast) { 1265 | push @tmp, 1266 | range2cidrlist($firstip, $broadcast); 1267 | } 1268 | #this IP is the start of a new range 1269 | else { 1270 | defined $lastip ? 1271 | push @tmp, range2cidrlist($firstip, $lastip): 1272 | push @tmp, $firstip."/32"; 1273 | 1274 | #save the current new ip 1275 | push @tmp, $broadcast."/32"; 1276 | } 1277 | } 1278 | } 1279 | return @tmp; 1280 | } 1281 | 1282 | 1283 | #subroutine that reads the A record from the additional section 1284 | sub additionalrecord { 1285 | 1286 | my ($packet, @servers, %seen) = @_; 1287 | 1288 | foreach my $rr (grep { $_->type eq 'A' } $packet->additional) { 1289 | foreach (grep {$_ eq $rr->name} @servers) { 1290 | 1291 | $seen{$rr->name} = 1; 1292 | printrr($rr->string); 1293 | xml_host($rr); 1294 | push @results, $rr->address 1295 | if $rr->name =~ /$domain$/; 1296 | 1297 | } 1298 | } 1299 | 1300 | #get the nameservers that have not been found in the additional section 1301 | keys %seen == @servers ? return : 1302 | return grep { not $seen{$_} } @servers; 1303 | } 1304 | 1305 | #subroutine to get uniq splited subdomains 1306 | sub uniq_hosts { 1307 | my %uniq; 1308 | grep { !$uniq{$_} && $uniq{$_}++ for split /\./ } @_; 1309 | return keys %uniq; 1310 | } 1311 | 1312 | #subroutine to write valid subdomains to files 1313 | sub writetofile { 1314 | my $file = shift; 1315 | my $output = new IO::File $file, shift 1316 | or die "Could not open ", $file ," file: $!\n"; 1317 | print $output $_, "\n" for @_; 1318 | $output->close; 1319 | } 1320 | 1321 | #subroutine to update and clean files 1322 | sub cleanfile { 1323 | 1324 | my ($file,$tmpfile,%uniq) = @_; 1325 | 1326 | seek($tmpfile,0,0) 1327 | or die "Error: seek failed on the temporary file: $!\n". 1328 | "can't update ", $file ,"\n"; 1329 | 1330 | @uniq{<$tmpfile>} = (); 1331 | 1332 | if (-s $file) { 1333 | my $input = new IO::File $file, "r" 1334 | or die "Unable to update ", $file ," file: $!\n"; 1335 | @uniq{<$input>} = (); 1336 | $input->close; 1337 | } 1338 | 1339 | writetofile($file,"w", 1340 | sort {uc($a) cmp uc($b)} grep {chomp} keys %uniq); 1341 | } 1342 | 1343 | #broken 1344 | 1345 | sub printrr { 1346 | 1347 | my $output = shift; 1348 | my @outputA = split('\s+',$output); 1349 | printf("%-40s %-8s %-5s %-8s %10s\n", $outputA[0], $outputA[1], $outputA[2], $outputA[3], $outputA[4]); 1350 | 1351 | } 1352 | sub printheader{ 1353 | my ($header) = @_; 1354 | unless ($nocolor) { 1355 | print color 'bold red'; 1356 | } 1357 | print STDOUT "\n\n".$header."_" x length($header) ."\n\n"; 1358 | unless ($nocolor) { 1359 | print color 'reset'; 1360 | } 1361 | } 1362 | 1363 | #the usage subroutine 1364 | sub usage { 1365 | print STDOUT 1366 | qq{Usage: $program [Options] 1367 | [Options]: 1368 | Note: the brute force -f switch is obligatory. 1369 | GENERAL OPTIONS: 1370 | --dnsserver 1371 | Use this DNS server for A, NS and MX queries. 1372 | --enum Shortcut option equivalent to --threads 5 -s 15 -w. 1373 | -h, --help Print this help message. 1374 | --noreverse Skip the reverse lookup operations. 1375 | --nocolor Disable ANSIColor output. 1376 | --private Show and save private ips at the end of the file domain_ips.txt. 1377 | --subfile Write all valid subdomains to this file. 1378 | -t, --timeout The tcp and udp timeout values in seconds (default: 10s). 1379 | --threads The number of threads that will perform different queries. 1380 | -v, --verbose Be verbose: show all the progress and all the error messages. 1381 | GOOGLE SCRAPING OPTIONS: 1382 | -p, --pages The number of google search pages to process when scraping names, 1383 | the default is 5 pages, the -s switch must be specified. 1384 | -s, --scrap The maximum number of subdomains that will be scraped from Google (default 15). 1385 | BRUTE FORCE OPTIONS: 1386 | -f, --file Read subdomains from this file to perform brute force. 1387 | -u, --update 1388 | Update the file specified with the -f switch with valid subdomains. 1389 | a (all) Update using all results. 1390 | g Update using only google scraping results. 1391 | r Update using only reverse lookup results. 1392 | z Update using only zonetransfer results. 1393 | -r, --recursion Recursion on subdomains, brute force all discovred subdomains that have an NS record. 1394 | WHOIS NETRANGE OPTIONS: 1395 | -d, --delay The maximum value of seconds to wait between whois queries, the value is defined randomly, default: 3s. 1396 | -w, --whois Perform the whois queries on c class network ranges. 1397 | **Warning**: this can generate very large netranges and it will take lot of time to performe reverse lookups. 1398 | REVERSE LOOKUP OPTIONS: 1399 | -e, --exclude 1400 | Exclude PTR records that match the regexp expression from reverse lookup results, useful on invalid hostnames. 1401 | OUTPUT OPTIONS: 1402 | -o --output Output in XML format. Can be imported in MagicTree (www.gremwell.com) 1403 | }; 1404 | exit(1); 1405 | } 1406 | 1407 | __END__ 1408 | 1409 | 1410 | =head1 NAME 1411 | 1412 | dnsenum.pl: multithread script to enumerate information on a domain and to discover non-contiguous IP blocks. 1413 | 1414 | =head1 VERSION 1415 | 1416 | dnsenum.pl version 1.2.4 1417 | 1418 | =head1 SYNOPSIS 1419 | 1420 | dnsenum.pl [options] -f dns.txt 1421 | 1422 | =head1 DESCRIPTION 1423 | 1424 | Supported operations: 1425 | nslookup, zonetransfer, google scraping, domain brute force 1426 | (support also recursion), whois ip and reverse lookups. 1427 | 1428 | 1429 | Operations: 1430 | 1431 | =over 5 1432 | 1433 | =item 1434 | 1435 | 1) Get the host's addresse (A record). 1436 | 1437 | =item 1438 | 1439 | 2) Get the nameservers (threaded). 1440 | 1441 | =item 1442 | 1443 | 3) Get the MX record (threaded). 1444 | 1445 | =item 1446 | 1447 | 4) Perform AXFR queries on nameservers (threaded). 1448 | 1449 | =item 1450 | 1451 | 5) Get extra names and subdomains via google scraping 1452 | (google query = "allinurl: -www site:domain"). 1453 | 1454 | =item 1455 | 1456 | 6) Brute force subdomains from (REQUIRED), can also perform recursion on 1457 | subdomain that have NS records (all threaded). 1458 | 1459 | =item 1460 | 1461 | 7) Calculate Class C IP network ranges from the results and perform whois queries on them (threaded). 1462 | 1463 | =item 1464 | 1465 | 8) Perform reverse lookups on netranges (class C or/and whois netranges)(threaded). 1466 | 1467 | =item 1468 | 1469 | 9) Write to domain_ips.txt file non-contiguous ip-blocks results. 1470 | 1471 | =back 1472 | 1473 | =head1 OPTIONS 1474 | 1475 | The brute force -f switch is obligatory. 1476 | 1477 | =head2 GENERAL OPTIONS: 1478 | 1479 | =over 1480 | 1481 | =over 30 1482 | 1483 | =item B<--dnsserver> B<> 1484 | 1485 | Use this DNS server to perform all A, NS and MX queries, 1486 | the AXFR and PTR queries are sent to the domain's NS servers. 1487 | 1488 | =item B<--enum> 1489 | 1490 | Shortcut option equivalent to --threads 5 -s 20 -w. 1491 | 1492 | =item B<-h>, B<--help> 1493 | 1494 | Print the help message. 1495 | 1496 | =item B<--noreverse> 1497 | 1498 | Skip the reverse lookup operations. 1499 | Reverse lookups can take long time on big netranges. 1500 | 1501 | =item B<--nocolor> 1502 | 1503 | Disable ANSIColor output. 1504 | This option is only intended to be used on consoles that do not support 1505 | color output. 1506 | 1507 | =item B<--private> 1508 | 1509 | Show and save private ips at the end of the file domain_ips.txt. 1510 | 1511 | =item B<--subfile> B<> 1512 | 1513 | Write all valid subdomains to this file. 1514 | Subdomains are taken from NS and MX records, zonetransfer, 1515 | google scraping, brute force and reverse lookup hostnames. 1516 | 1517 | =item B<-t>, B<--timeout> B<> 1518 | 1519 | The tcp and udp timeout values in seconds (default: 10s). 1520 | 1521 | =item B<--threads> B<, B<--verbose> 1527 | 1528 | Be verbose (show all the progress and all the error messages). 1529 | 1530 | =back 1531 | 1532 | =back 1533 | 1534 | =over 3 1535 | 1536 | B 1537 | neither the default domain nor the resolver search list are 1538 | appended to domains that don't contain any dots. 1539 | 1540 | =back 1541 | 1542 | =head2 GOOGLE SCRAPING OPTIONS: 1543 | 1544 | =over 3 1545 | 1546 | This function will scrap subdomains from google search, 1547 | using query: allinurl: -www site:domain. 1548 | 1549 | =back 1550 | 1551 | =over 1552 | 1553 | =over 30 1554 | 1555 | =item B<-p>, B<--pages> B<> 1556 | 1557 | The number of google search pages to process when scraping names, 1558 | the -s switch must be specified, (default: 20 pages). 1559 | 1560 | =item B<-s>, B<--scrap> B<> 1561 | 1562 | The maximum number of subdomains that will be scraped from google. 1563 | 1564 | =back 1565 | 1566 | =back 1567 | 1568 | =over 3 1569 | 1570 | B 1571 | Google can block our queries with the malware detection. 1572 | Http proxy options for google scraping are automatically loaded from 1573 | the environment if the vars http_proxy or HTTP_PROXY are present. 1574 | "http_proxy=http://127.0.0.1:8118/" or "HTTP_PROXY=http://127.0.0.1:8118/". 1575 | On IO errors the mechanize browser object will automatically call die. 1576 | 1577 | =back 1578 | 1579 | =head2 BRUTE FORCE OPTIONS: 1580 | 1581 | =over 1582 | 1583 | =over 30 1584 | 1585 | =item B<-f>, B<--file> B<> 1586 | 1587 | Read subdomains from this file to perform brute force. 1588 | 1589 | =item B<-u>, B<--update> B<> 1590 | 1591 | Update the file specified with the -f switch with vaild subdomains. 1592 | 1593 | =back 1594 | 1595 | =back 1596 | 1597 | =over 35 1598 | 1599 | B<-u> a Update using all results. 1600 | 1601 | B<-u> g Update using only google scraping results. 1602 | 1603 | B<-u> r Update using only reverse lookup results. 1604 | 1605 | B<-u> z Update using only zonetransfer results. 1606 | 1607 | =back 1608 | 1609 | =over 1610 | 1611 | =over 30 1612 | 1613 | =item B<-r>, B<--recursion> 1614 | 1615 | Recursion on subdomains, brute force all discovred subdomains 1616 | that have an NS record. 1617 | 1618 | =back 1619 | 1620 | =back 1621 | 1622 | =over 3 1623 | 1624 | B 1625 | To perform recursion first we must check previous subdomains results (zonetransfer, google scraping and brute force) for NS 1626 | records after that we perform brute force on valid subdomains that have NS records and so on. NS, MX and reverse lookup results are 1627 | not concerned. 1628 | 1629 | =back 1630 | 1631 | =head2 WHOIS IP OPTIONS: 1632 | 1633 | Perform whois ip queries on c class netanges discovred from 1634 | previous operations. 1635 | 1636 | =over 1637 | 1638 | =over 30 1639 | 1640 | =item B<-d>, B<--delay> B<> 1641 | 1642 | The maximum value of seconds to wait between whois queries, 1643 | the value is defined randomly, (default: 3s). 1644 | 1645 | =back 1646 | 1647 | =back 1648 | 1649 | =over 3 1650 | 1651 | B 1652 | whois servers will limit the number of connections. 1653 | 1654 | =back 1655 | 1656 | =over 1657 | 1658 | =over 30 1659 | 1660 | =item B<-w>, B<--whois> 1661 | 1662 | Perform the whois queries on c class network ranges. 1663 | B: this can generate very large netranges and it 1664 | will take lot of time to performe reverse lookups. 1665 | 1666 | =back 1667 | 1668 | =back 1669 | 1670 | =over 3 1671 | 1672 | B 1673 | The whois query should recursively query the various whois 1674 | providers untile it gets the more detailed information including 1675 | either TechPhone or OrgTechPhone by default. See: perldoc Net::Whois::IP. 1676 | On errors the netrange will be a default c class /24. 1677 | 1678 | =back 1679 | 1680 | =head2 REVERSE LOOKUP OPTIONS: 1681 | 1682 | =over 1683 | 1684 | =over 30 1685 | 1686 | =item B<-e>, B<--exclude> B<> 1687 | 1688 | Exclude PTR records that match the regexp expression from reverse 1689 | lookup results, useful on invalid hostnames. 1690 | 1691 | =back 1692 | 1693 | =back 1694 | 1695 | =over 3 1696 | 1697 | B 1698 | PTR records that not match the domain are also excluded. 1699 | Verbose mode will show all results. 1700 | 1701 | =back 1702 | 1703 | =head1 OUTPUT FILES 1704 | 1705 | Final non-contiguous ip blocks are writen to domain_ips.txt file. 1706 | 1707 | B 1708 | Final non-contiguous ip blocks are calculated : 1709 | 1710 | =over 5 1711 | 1712 | =item 1713 | 1714 | 1) From reverse lookups that were performed on netranges 1715 | ( c class network ranges or whois netranges ). 1716 | 1717 | =item 1718 | 1719 | 2) If the noreverse switch is used then they are calculated from 1720 | previous operations results (nslookups, zonetransfers, 1721 | google scraping and brute forcing). 1722 | 1723 | =back 1724 | 1725 | =head1 README 1726 | 1727 | dnsenum.pl: multithread script to enumerate information on a domain 1728 | and to discover non-contiguous ip blocks. 1729 | 1730 | =head1 PREREQUISITES 1731 | 1732 | Modules that are included in perl 5.10.0: 1733 | Getopt::Long, IO::File, Thread::Queue. 1734 | 1735 | Other Necessary modules: 1736 | Must have: Net::DNS, Net::IP, Net::Netmask. 1737 | Optional: Net::Whois::IP, HTML::Parser, WWW::Mechanize. 1738 | 1739 | Perl ithreads modules (perl must be compiled with ithreads support): 1740 | threads, threads::shared. 1741 | 1742 | =head1 AUTHORS 1743 | 1744 | Filip Waeytens 1745 | 1746 | tix tixxDZ 1747 | 1748 | =head1 COPYRIGHT 1749 | 1750 | This program is free software; you can redistribute it and/or 1751 | modify it under the terms of the GNU General Public License as 1752 | published by the Free Software Foundation; either version 2 of 1753 | the License, or (at your option) any later version. 1754 | 1755 | =head1 SCRIPT CATEGORIES 1756 | 1757 | Networking 1758 | DNS 1759 | 1760 | =cut 1761 | --------------------------------------------------------------------------------