├── .github └── workflows │ └── release-tag.yml ├── .gitignore ├── LICENSE ├── README.md ├── icon.ico ├── main.py ├── metadata.yml └── requirements.txt /.github/workflows/release-tag.yml: -------------------------------------------------------------------------------- 1 | name: release-tag 2 | 3 | on: 4 | push: 5 | tags: 6 | - v*.*.* 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | permissions: 12 | contents: write 13 | steps: 14 | - 15 | name: Checkout 16 | uses: actions/checkout@v4 17 | - 18 | name: Install Python 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: 3.12 22 | - 23 | name: Install Python packages 24 | run: pip install -r requirements.txt pyinstaller pyinstaller-versionfile 25 | - 26 | name: Create Pyinstaller version file 27 | run: create-version-file metadata.yml --outfile file_version_info.txt --version "${{ github.ref_name }}".Replace("v", "") 28 | - 29 | name: Build executable 30 | run: pyinstaller --noconfirm --clean --onefile --console --version-file file_version_info.txt --distpath .\ --icon icon.ico main.py 31 | - 32 | name: Make release zips 33 | run: | 34 | Compress-Archive -Path .\LICENSE, .\main.exe, .\README.md -CompressionLevel Optimal -DestinationPath .\exe-${{ github.ref_name }}.zip 35 | Compress-Archive -Path .\LICENSE, .\main.py, .\README.md, .\requirements.txt -CompressionLevel Optimal -DestinationPath .\py-${{ github.ref_name }}.zip 36 | - 37 | name: Create release 38 | uses: ncipollo/release-action@v1 39 | with: 40 | artifactErrorsFailBuild: true 41 | artifacts: | 42 | exe-${{ github.ref_name }}.zip 43 | py-${{ github.ref_name }}.zip 44 | draft: true 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | main.exe 3 | main.spec 4 | file_version_info.txt 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023-2024 Al Azif, https://github.com/Al-Azif/exploit-host-cc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exploit Host Connectivity Checker 2 | 3 | ## Synopsis 4 | 5 | Checks various domains, over 400, on both DNS servers I host to see if they are functioning as expected. Intended to be used by end users to see if their ISP is hijacking their DNS requests and if recursive queries are enabled for their IP address. 6 | 7 | ## Usage 8 | 9 | If using the Python script directly, install the required packages with the following command: `pip install -r requirements.txt` 10 | 11 | ```shell 12 | usage: main.py [-h] [--disable-ipv4] [--enable-ipv6] 13 | 14 | Exploit Host Connectivity Checker 15 | 16 | options: 17 | -h, --help show this help message and exit 18 | --disable-ipv4 Disable checking IPv4 servers. Default: True 19 | --enable-ipv6 Enable checking IPv6 servers. Default: False 20 | ``` 21 | 22 | ## Is my ISP Hijacking? 23 | 24 | If everything responds with `FAIL` with the exception of the `Cthugha Forward` and `Ithaqua Forward` sections then your ISP is hijacking your requests. 25 | 26 | ## Notes 27 | 28 | - The Windows exe file is created with Pyinstaller, this may trigger your anti-virus. This is a known issue and is a false positive. If you don't trust it, download Python and run the script that way. 29 | - The code little messy but it works as expected, I don't want to expend a ton of extra effort on this. For what it is, it's good enough. 30 | - Works with Windows (CMD, Powershell, and standalone EXE), Linux, and OSX. 31 | - Python 3.8+ 32 | - If you enable IPv6 checking, but it's not available on your system/network, best case the checks all fail, worse case the script crashes. 33 | - Icon: https://icon-icons.com/icon/services-dns/216293 34 | -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Al-Azif/exploit-host-cc/e62af4f371b994d4a62e941df8d3e2d2a1637d7e/icon.ico -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import argparse 5 | import os 6 | import sys 7 | 8 | import dns.resolver 9 | from termcolor import colored 10 | 11 | # Colors to use for PASS, FAIL, UNAVAILABLE, and DISABLED 12 | PASS = colored("PASS", "green") 13 | FAIL = colored("FAIL", "red") 14 | UNAVAILABLE = colored("UNAVAILABLE", "yellow") 15 | DISABLED = colored("DISABLED", "dark_grey") 16 | 17 | # Initialize option variables 18 | IPV4_ENABLED = True 19 | IPV6_ENABLED = False 20 | 21 | # DNS servers to check 22 | DNS_SERVERS = { 23 | "Cthugha": { 24 | "IPv4": "165.227.83.145", 25 | "IPv4 Redirect": "165.227.83.145", 26 | "IPv6": "2604:a880:400:d0::aa1:7001", 27 | "IPv6 Redirect": "2604:a880:400:d0::aa1:7001", 28 | }, 29 | "Ithaqua": { 30 | "IPv4": "192.241.221.79", 31 | "IPv4 Redirect": "192.241.221.79", 32 | "IPv6": "2604:a880:1:20::58:c001", 33 | "IPv6 Redirect": "2604:a880:1:20::58:c001", 34 | }, 35 | } 36 | 37 | # Domains to check 38 | DOMAINS = { 39 | "Redirect": { 40 | "Landing Domains": [ 41 | "ctest.cdn.nintendo.net", 42 | "conntest.nintendowifi.net", 43 | "cfh.wapp.wii.com", 44 | "www.playstation.com", 45 | "manuals.playstation.net", 46 | ], 47 | "Network Test Domains": [ 48 | "get.net.playstation.net", 49 | "post.net.playstation.net", 50 | "ena.net.playstation.net", 51 | ], 52 | "Generic Update Domains": [ 53 | "update.net.playstation.net", 54 | ], 55 | "PS3 Update PUP Domains": [ 56 | "djp01.ps3.update.playstation.net", 57 | "dus01.ps3.update.playstation.net", 58 | "deu01.ps3.update.playstation.net", 59 | "dkr01.ps3.update.playstation.net", 60 | "duk01.ps3.update.playstation.net", 61 | "dmx01.ps3.update.playstation.net", 62 | "dau01.ps3.update.playstation.net", 63 | "dsa01.ps3.update.playstation.net", 64 | "dtw01.ps3.update.playstation.net", 65 | "dru01.ps3.update.playstation.net", 66 | "dcn01.ps3.update.playstation.net", 67 | "dhk01.ps3.update.playstation.net", 68 | "dbr01.ps3.update.playstation.net", 69 | ], 70 | "PS4 Update PUP Domains": [ 71 | "djp01.ps4.update.playstation.net", 72 | "dus01.ps4.update.playstation.net", 73 | "deu01.ps4.update.playstation.net", 74 | "dkr01.ps4.update.playstation.net", 75 | "duk01.ps4.update.playstation.net", 76 | "dmx01.ps4.update.playstation.net", 77 | "dau01.ps4.update.playstation.net", 78 | "dsa01.ps4.update.playstation.net", 79 | "dtw01.ps4.update.playstation.net", 80 | "dru01.ps4.update.playstation.net", 81 | "dcn01.ps4.update.playstation.net", 82 | "dhk01.ps4.update.playstation.net", 83 | "dbr01.ps4.update.playstation.net", 84 | ], 85 | "PS5 Update PUP Domains": [ 86 | "djp01.ps5.update.playstation.net", 87 | "dus01.ps5.update.playstation.net", 88 | "deu01.ps5.update.playstation.net", 89 | "dkr01.ps5.update.playstation.net", 90 | "duk01.ps5.update.playstation.net", 91 | "dmx01.ps5.update.playstation.net", 92 | "dau01.ps5.update.playstation.net", 93 | "dsa01.ps5.update.playstation.net", 94 | "dtw01.ps5.update.playstation.net", 95 | "dru01.ps5.update.playstation.net", 96 | "dcn01.ps5.update.playstation.net", 97 | "dhk01.ps5.update.playstation.net", 98 | "dbr01.ps5.update.playstation.net", 99 | ], 100 | "Vita Update PUP Domains": [ 101 | "djp01.psp2.update.playstation.net", 102 | "dus01.psp2.update.playstation.net", 103 | "deu01.psp2.update.playstation.net", 104 | "dkr01.psp2.update.playstation.net", 105 | "duk01.psp2.update.playstation.net", 106 | "dmx01.psp2.update.playstation.net", 107 | "dau01.psp2.update.playstation.net", 108 | "dsa01.psp2.update.playstation.net", 109 | "dtw01.psp2.update.playstation.net", 110 | "dru01.psp2.update.playstation.net", 111 | "dcn01.psp2.update.playstation.net", 112 | "dhk01.psp2.update.playstation.net", 113 | "dbr01.psp2.update.playstation.net", 114 | ], 115 | "PS3 Update List Domains": [ 116 | "fjp01.ps3.update.playstation.net", 117 | "fus01.ps3.update.playstation.net", 118 | "feu01.ps3.update.playstation.net", 119 | "fkr01.ps3.update.playstation.net", 120 | "fuk01.ps3.update.playstation.net", 121 | "fmx01.ps3.update.playstation.net", 122 | "fau01.ps3.update.playstation.net", 123 | "fsa01.ps3.update.playstation.net", 124 | "ftw01.ps3.update.playstation.net", 125 | "fru01.ps3.update.playstation.net", 126 | "fcn01.ps3.update.playstation.net", 127 | "fhk01.ps3.update.playstation.net", 128 | "fbr01.ps3.update.playstation.net", 129 | ], 130 | "PS4 Update List Domains": [ 131 | "fjp01.ps4.update.playstation.net", 132 | "fus01.ps4.update.playstation.net", 133 | "feu01.ps4.update.playstation.net", 134 | "fkr01.ps4.update.playstation.net", 135 | "fuk01.ps4.update.playstation.net", 136 | "fmx01.ps4.update.playstation.net", 137 | "fau01.ps4.update.playstation.net", 138 | "fsa01.ps4.update.playstation.net", 139 | "ftw01.ps4.update.playstation.net", 140 | "fru01.ps4.update.playstation.net", 141 | "fcn01.ps4.update.playstation.net", 142 | "fhk01.ps4.update.playstation.net", 143 | "fbr01.ps4.update.playstation.net", 144 | ], 145 | "PS5 Update List Domains": [ 146 | "fjp01.ps5.update.playstation.net", 147 | "fus01.ps5.update.playstation.net", 148 | "feu01.ps5.update.playstation.net", 149 | "fkr01.ps5.update.playstation.net", 150 | "fuk01.ps5.update.playstation.net", 151 | "fmx01.ps5.update.playstation.net", 152 | "fau01.ps5.update.playstation.net", 153 | "fsa01.ps5.update.playstation.net", 154 | "ftw01.ps5.update.playstation.net", 155 | "fru01.ps5.update.playstation.net", 156 | "fcn01.ps5.update.playstation.net", 157 | "fhk01.ps5.update.playstation.net", 158 | "fbr01.ps5.update.playstation.net", 159 | ], 160 | "Vita Update List Domains": [ 161 | "fjp01.psp2.update.playstation.net", 162 | "fus01.psp2.update.playstation.net", 163 | "feu01.psp2.update.playstation.net", 164 | "fkr01.psp2.update.playstation.net", 165 | "fuk01.psp2.update.playstation.net", 166 | "fmx01.psp2.update.playstation.net", 167 | "fau01.psp2.update.playstation.net", 168 | "fsa01.psp2.update.playstation.net", 169 | "ftw01.psp2.update.playstation.net", 170 | "fru01.psp2.update.playstation.net", 171 | "fcn01.psp2.update.playstation.net", 172 | "fhk01.psp2.update.playstation.net", 173 | "fbr01.psp2.update.playstation.net", 174 | ], 175 | "PS4 Update Feature Domains": [ 176 | "hjp01.ps4.update.playstation.net", 177 | "hus01.ps4.update.playstation.net", 178 | "heu01.ps4.update.playstation.net", 179 | "hkr01.ps4.update.playstation.net", 180 | "huk01.ps4.update.playstation.net", 181 | "hmx01.ps4.update.playstation.net", 182 | "hau01.ps4.update.playstation.net", 183 | "hsa01.ps4.update.playstation.net", 184 | "htw01.ps4.update.playstation.net", 185 | "hru01.ps4.update.playstation.net", 186 | "hcn01.ps4.update.playstation.net", 187 | "hhk01.ps4.update.playstation.net", 188 | "hbr01.ps4.update.playstation.net", 189 | ], 190 | "PS5 Update Feature Domains": [ 191 | "hjp01.ps5.update.playstation.net", 192 | "hus01.ps5.update.playstation.net", 193 | "heu01.ps5.update.playstation.net", 194 | "hkr01.ps5.update.playstation.net", 195 | "huk01.ps5.update.playstation.net", 196 | "hmx01.ps5.update.playstation.net", 197 | "hau01.ps5.update.playstation.net", 198 | "hsa01.ps5.update.playstation.net", 199 | "htw01.ps5.update.playstation.net", 200 | "hru01.ps5.update.playstation.net", 201 | "hcn01.ps5.update.playstation.net", 202 | "hhk01.ps5.update.playstation.net", 203 | "hbr01.ps5.update.playstation.net", 204 | ], 205 | }, 206 | "Block": [ 207 | "nintendo.net", 208 | "nintendowifi.net", 209 | "wii.com", 210 | "playstation.com", 211 | "playstation.net", 212 | 213 | "wildcard.nintendo.net", 214 | "wildcard.nintendowifi.net", 215 | "wildcard.wii.com", 216 | "wildcard.playstation.com", 217 | "wildcard.playstation.net", 218 | 219 | "nintendo-europe.com", 220 | "nintendo.at", 221 | "nintendo.be", 222 | "nintendo.ch", 223 | "nintendo.co.jp", 224 | "nintendo.co.kr", 225 | "nintendo.co.nz", 226 | "nintendo.co.uk", 227 | "nintendo.co.za", 228 | "nintendo.com", 229 | "nintendo.com.au", 230 | "nintendo.com.hk", 231 | "nintendo.cz", 232 | "nintendo.de", 233 | "nintendo.dk", 234 | "nintendo.es", 235 | "nintendo.eu", 236 | "nintendo.fi", 237 | "nintendo.fr", 238 | "nintendo.gr", 239 | "nintendo.hu", 240 | "nintendo.it", 241 | "nintendo.jp", 242 | "nintendo.nl", 243 | "nintendo.no", 244 | "nintendo.pt", 245 | "nintendo.ru", 246 | "nintendo.se", 247 | "nintendo.tw", 248 | "nintendoswitch.cn", 249 | "nintendoswitch.com", 250 | "nintendoswitch.com.cn", 251 | "nintendoservicecentre.co.uk", 252 | 253 | "playstation.org", 254 | "scea.com", 255 | "sonyentertainmentnetwork.com", 256 | "sie-rd.com", 257 | 258 | "wildcard.nintendo-europe.com", 259 | "wildcard.nintendo.at", 260 | "wildcard.nintendo.be", 261 | "wildcard.nintendo.ch", 262 | "wildcard.nintendo.co.jp", 263 | "wildcard.nintendo.co.kr", 264 | "wildcard.nintendo.co.nz", 265 | "wildcard.nintendo.co.uk", 266 | "wildcard.nintendo.co.za", 267 | "wildcard.nintendo.com", 268 | "wildcard.nintendo.com.au", 269 | "wildcard.nintendo.com.hk", 270 | "wildcard.nintendo.cz", 271 | "wildcard.nintendo.de", 272 | "wildcard.nintendo.dk", 273 | "wildcard.nintendo.es", 274 | "wildcard.nintendo.eu", 275 | "wildcard.nintendo.fi", 276 | "wildcard.nintendo.fr", 277 | "wildcard.nintendo.gr", 278 | "wildcard.nintendo.hu", 279 | "wildcard.nintendo.it", 280 | "wildcard.nintendo.jp", 281 | "wildcard.nintendo.nl", 282 | "wildcard.nintendo.no", 283 | "wildcard.nintendo.pt", 284 | "wildcard.nintendo.ru", 285 | "wildcard.nintendo.se", 286 | "wildcard.nintendo.tw", 287 | "wildcard.nintendoswitch.cn", 288 | "wildcard.nintendoswitch.com", 289 | "wildcard.nintendoswitch.com.cn", 290 | "wildcard.nintendoservicecentre.co.uk", 291 | 292 | "wildcard.playstation.org", 293 | "wildcard.scea.com", 294 | "wildcard.sonyentertainmentnetwork.com", 295 | "wildcard.sie-rd.com", 296 | ], 297 | "CNAME": { 298 | "b0.ww.np.dl.playstation.net": "sonycoment.vo.llnwd.net.", 299 | "gs.ww.np.dl.playstation.net": "sonycoment.vo.llnwd.net.", 300 | "gs2.ww.prod.dl.playstation.net": "sonycoment.vo.llnwd.net.", 301 | "gst.prod.dl.playstation.net": "sonygst.s.llnwi.net.", 302 | }, 303 | "Forward": [ 304 | "example.com", 305 | "www.google.com", 306 | "www.facebook.com", 307 | "www.wikipedia.org", 308 | ], 309 | } 310 | 311 | # Variables for loading bar 312 | CHECKED = 0 313 | TOTAL_CHECKS = len(DOMAINS["Block"]) + len(DOMAINS["CNAME"]) + len(DOMAINS["Forward"]) 314 | for key, value in DOMAINS["Redirect"].items(): 315 | TOTAL_CHECKS += len(value) 316 | TOTAL_CHECKS = TOTAL_CHECKS * len(DNS_SERVERS) 317 | 318 | 319 | def clear_terminal(): 320 | if os.name == "nt": 321 | os.system("cls") 322 | else: 323 | os.system("clear") 324 | 325 | 326 | def update_progress(): 327 | global CHECKED 328 | 329 | CHECKED += 1 330 | percent = int(CHECKED / TOTAL_CHECKS * 100) 331 | 332 | sys.stdout.write("\r") 333 | sys.stdout.write("[%-50s] %d%%" % ("=" * int(percent / 2), percent)) 334 | sys.stdout.flush() 335 | 336 | 337 | def redirect_check(entries, ipv4, ipv6, expected_ipv4, expected_ipv6): 338 | output = {} 339 | 340 | resolver_ipv4 = dns.resolver.Resolver() 341 | resolver_ipv6 = dns.resolver.Resolver() 342 | resolver_ipv4.nameservers = [ipv4] 343 | resolver_ipv6.nameservers = [ipv6] 344 | 345 | for entry in entries: 346 | output[entry] = {} 347 | 348 | if IPV4_ENABLED: 349 | found = 0 350 | output[entry]["IPv4"] = {"A": FAIL, "AAAA": FAIL} 351 | try: 352 | for rdata in resolver_ipv4.resolve(entry, "A"): 353 | if str(rdata) == str(expected_ipv4): 354 | output[entry]["IPv4"]["A"] = PASS 355 | found += 1 356 | if found != 1: 357 | output[entry]["IPv4"]["A"] = FAIL 358 | except: 359 | output[entry]["IPv4"]["A"] = FAIL 360 | 361 | found = 0 362 | try: 363 | for rdata in resolver_ipv4.resolve(entry, "AAAA"): 364 | if str(rdata) == str(expected_ipv6): 365 | output[entry]["IPv4"]["AAAA"] = PASS 366 | found += 1 367 | if found != 1: 368 | output[entry]["IPv4"]["AAAA"] = FAIL 369 | except: 370 | output[entry]["IPv4"]["AAAA"] = FAIL 371 | else: 372 | output[entry]["IPv4"] = DISABLED 373 | 374 | if IPV6_ENABLED: 375 | found = 0 376 | output[entry]["IPv6"] = {"A": FAIL, "AAAA": FAIL} 377 | try: 378 | for rdata in resolver_ipv6.resolve(entry, "A"): 379 | if str(rdata) == str(expected_ipv4): 380 | output[entry]["IPv6"]["A"] = PASS 381 | found += 1 382 | if found != 1: 383 | output[entry]["IPv6"]["A"] = FAIL 384 | except: 385 | output[entry]["IPv6"]["A"] = FAIL 386 | 387 | found = 0 388 | try: 389 | for rdata in resolver_ipv6.resolve(entry, "AAAA"): 390 | if str(rdata) == str(expected_ipv6): 391 | output[entry]["IPv6"]["AAAA"] = PASS 392 | found += 1 393 | if found != 1: 394 | output[entry]["IPv6"]["AAAA"] = FAIL 395 | except: 396 | output[entry]["IPv6"]["AAAA"] = FAIL 397 | else: 398 | output[entry]["IPv6"] = DISABLED 399 | 400 | update_progress() 401 | 402 | return output 403 | 404 | 405 | def cname_check(entries, ipv4, ipv6): 406 | output = {} 407 | 408 | resolver_ipv4 = dns.resolver.Resolver() 409 | resolver_ipv6 = dns.resolver.Resolver() 410 | resolver_ipv4.nameservers = [ipv4] 411 | resolver_ipv6.nameservers = [ipv6] 412 | 413 | for key, value in entries.items(): 414 | output[key] = {} 415 | 416 | if IPV4_ENABLED: 417 | found = 0 418 | output[key]["IPv4"] = FAIL 419 | try: 420 | for rdata in resolver_ipv4.resolve(key, "CNAME"): 421 | if str(rdata) == str(value): 422 | output[key]["IPv4"] = PASS 423 | found += 1 424 | if found != 1: 425 | output[key]["IPv4"] = FAIL 426 | except: 427 | output[key]["IPv4"] = FAIL 428 | else: 429 | output[key]["IPv4"] = DISABLED 430 | 431 | if IPV6_ENABLED: 432 | found = 0 433 | output[key]["IPv6"] = FAIL 434 | try: 435 | for rdata in resolver_ipv6.resolve(key, "CNAME"): 436 | if str(rdata) == str(value): 437 | output[key]["IPv6"] = PASS 438 | found += 1 439 | if found != 1: 440 | output[key]["IPv6"] = FAIL 441 | except: 442 | output[key]["IPv6"] = FAIL 443 | else: 444 | output[key]["IPv6"] = DISABLED 445 | 446 | update_progress() 447 | 448 | return output 449 | 450 | 451 | def forward_check(entries, ipv4, ipv6): 452 | output = {} 453 | 454 | resolver_ipv4 = dns.resolver.Resolver() 455 | resolver_ipv6 = dns.resolver.Resolver() 456 | resolver_ipv4.nameservers = [ipv4] 457 | resolver_ipv6.nameservers = [ipv6] 458 | 459 | for entry in entries: 460 | output[entry] = {} 461 | 462 | if IPV4_ENABLED: 463 | output[entry]["IPv4"] = {"A": FAIL, "AAAA": FAIL} 464 | try: 465 | for rdata in resolver_ipv4.resolve(entry, "A"): 466 | if str(rdata) != str(""): 467 | output[entry]["IPv4"]["A"] = PASS 468 | break 469 | except: 470 | output[entry]["IPv4"]["A"] = FAIL 471 | 472 | try: 473 | for rdata in resolver_ipv4.resolve(entry, "AAAA"): 474 | if str(rdata) != str(""): 475 | output[entry]["IPv4"]["AAAA"] = PASS 476 | break 477 | except: 478 | output[entry]["IPv4"]["AAAA"] = FAIL 479 | else: 480 | output[entry]["IPv4"] = DISABLED 481 | 482 | if IPV6_ENABLED: 483 | output[entry]["IPv6"] = {"A": FAIL, "AAAA": FAIL} 484 | try: 485 | for rdata in resolver_ipv6.resolve(entry, "A"): 486 | if str(rdata) != str(""): 487 | output[entry]["IPv6"]["A"] = PASS 488 | break 489 | except: 490 | output[entry]["IPv6"]["A"] = FAIL 491 | 492 | try: 493 | for rdata in resolver_ipv6.resolve(entry, "AAAA"): 494 | if str(rdata) != str(""): 495 | output[entry]["IPv6"]["AAAA"] = PASS 496 | break 497 | except: 498 | output[entry]["IPv6"]["AAAA"] = FAIL 499 | else: 500 | output[entry]["IPv6"] = DISABLED 501 | 502 | update_progress() 503 | 504 | return output 505 | 506 | 507 | def generate_data(): 508 | output = {} 509 | 510 | for key, value in DNS_SERVERS.items(): 511 | output[key] = {} 512 | output[key]["Redirect"] = {} 513 | for key2, value2 in DOMAINS["Redirect"].items(): 514 | output[key]["Redirect"][key2] = redirect_check(value2, value["IPv4"], value["IPv6"], value["IPv4 Redirect"], value["IPv6 Redirect"]) 515 | output[key]["Block"] = redirect_check(DOMAINS["Block"], value["IPv4"], value["IPv6"], "0.0.0.0", "::") # nosec B104 516 | output[key]["CNAME"] = cname_check(DOMAINS["CNAME"], value["IPv4"], value["IPv6"]) 517 | output[key]["Forward"] = forward_check(DOMAINS["Forward"], value["IPv4"], value["IPv6"]) 518 | 519 | return output 520 | 521 | 522 | def print_section_header(title, header_type=""): 523 | print(f"+--- {title} {''.ljust(80 - len(title), '-')}+") 524 | print("| DNS Protocol: | IPv4 | IPv6 |") 525 | if header_type == "CNAME": 526 | print("| DNS Record Type: | CNAME | CNAME |") 527 | else: 528 | print("| DNS Record Type: | A | AAAA | A | AAAA |") 529 | print("| Domain(s): |") 530 | 531 | 532 | def print_section_footer(): 533 | print("+-------------------------------------------------------------------------------------+") 534 | print("") 535 | 536 | 537 | def print_sponsor_footer(): 538 | print("+-------------------------------------------------------------------------------------+") 539 | print(f"| These should {FAIL} unless you are a sponsor. For more info you can visit: |") 540 | print("| https://github.com/sponsors/Al-Azif/ |") 541 | print("+-------------------------------------------------------------------------------------+") 542 | print("") 543 | 544 | 545 | def print_section(data, server, section): 546 | if section == "Redirect": 547 | for key, value in data[server][section].items(): 548 | print_section_header(str(server) + " " + str(section) + " " + str(key), str(section)) 549 | for key2, value2 in data[server][section][key].items(): 550 | if IPV4_ENABLED and not IPV6_ENABLED: 551 | print(f"| {key2.ljust(54, ' ')}| {value2['IPv4']['A']} | {value2['IPv4']['AAAA']} | {value2['IPv6']} |") 552 | elif not IPV4_ENABLED and IPV6_ENABLED: 553 | print(f"| {key2.ljust(54, ' ')}| {value2['IPv4']} | {value2['IPv6']['A']} | {value2['IPv6']['AAAA']} |") 554 | else: 555 | print(f"| {key2.ljust(54, ' ')}| {value2['IPv4']['A']} | {value2['IPv4']['AAAA']} | {value2['IPv6']['A']} | {value2['IPv6']['AAAA']} |") 556 | print_section_footer() 557 | elif section == "Block": 558 | print_section_header(str(server) + " " + str(section), str(section)) 559 | for key, value in data[server][section].items(): 560 | if IPV4_ENABLED and not IPV6_ENABLED: 561 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']['A']} | {value['IPv4']['AAAA']} | {value['IPv6']} |") 562 | elif not IPV4_ENABLED and IPV6_ENABLED: 563 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']} | {value['IPv6']['A']} | {value['IPv6']['AAAA']} |") 564 | else: 565 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']['A']} | {value['IPv4']['AAAA']} | {value['IPv6']['A']} | {value['IPv6']['AAAA']} |") 566 | print_section_footer() 567 | elif section == "CNAME": 568 | print_section_header(str(server) + " " + str(section), str(section)) 569 | for key, value in data[server][section].items(): 570 | if IPV4_ENABLED and not IPV6_ENABLED: 571 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']} | {value['IPv6']} |") 572 | elif not IPV4_ENABLED and IPV6_ENABLED: 573 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']} | {value['IPv6']} |") 574 | else: 575 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']} | {value['IPv6']} |") 576 | print_section_footer() 577 | elif section == "Forward": 578 | print_section_header(str(server) + " " + str(section), str(section)) 579 | for key, value in data[server][section].items(): 580 | if IPV4_ENABLED and not IPV6_ENABLED: 581 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']['A']} | {value['IPv4']['AAAA']} | {value['IPv6']} |") 582 | elif not IPV4_ENABLED and IPV6_ENABLED: 583 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']} | {value['IPv6']['A']} | {value['IPv6']['AAAA']} |") 584 | else: 585 | print(f"| {key.ljust(54, ' ')}| {value['IPv4']['A']} | {value['IPv4']['AAAA']} | {value['IPv6']['A']} | {value['IPv6']['AAAA']} |") 586 | print_sponsor_footer() 587 | 588 | 589 | def print_data(data): 590 | for key in DNS_SERVERS.keys(): 591 | print_section(data, key, "Redirect") 592 | print_section(data, key, "Block") 593 | print_section(data, key, "CNAME") 594 | print_section(data, key, "Forward") 595 | 596 | 597 | def main(): 598 | global IPV4_ENABLED 599 | global IPV6_ENABLED 600 | 601 | clear_terminal() 602 | 603 | parser = argparse.ArgumentParser( 604 | description="Exploit Host Connectivity Checker", 605 | usage="%(prog)s [-h] [--disable-ipv4] [--enable-ipv6]" 606 | ) 607 | parser.add_argument( 608 | "--disable-ipv4", 609 | action="store_false", 610 | help="Disable checking IPv4 servers. Default: True" 611 | ) 612 | parser.add_argument( 613 | "--enable-ipv6", 614 | action="store_true", 615 | help="Enable checking IPv6 servers. Default: False" 616 | ) 617 | args = parser.parse_args() 618 | 619 | IPV4_ENABLED = args.disable_ipv4 620 | IPV6_ENABLED = args.enable_ipv6 621 | 622 | if not IPV4_ENABLED and not IPV6_ENABLED: 623 | print("Must have either IPv4 or IPv6 enabled. Both are currently disabled.") 624 | sys.exit(1) 625 | 626 | if os.name == "nt": 627 | os.system("color") 628 | 629 | data = generate_data() 630 | clear_terminal() 631 | print_data(data) 632 | input("Press Enter to exit...") 633 | 634 | 635 | if __name__ == "__main__": 636 | main() 637 | -------------------------------------------------------------------------------- /metadata.yml: -------------------------------------------------------------------------------- 1 | FileDescription: Exploit Host Connectivity Checker 2 | LegalCopyright: Copyright © 2023 Al Azif. All rights reserved. 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Al-Azif/exploit-host-cc/e62af4f371b994d4a62e941df8d3e2d2a1637d7e/requirements.txt --------------------------------------------------------------------------------