diff --git a/hacktv_updsrv/ServiceDeps/LC2/LC2.tok b/hacktv_updsrv/ServiceDeps/LC2/LC2.tok deleted file mode 100644 index adaab7b4..00000000 --- a/hacktv_updsrv/ServiceDeps/LC2/LC2.tok +++ /dev/null @@ -1,34 +0,0 @@ -ANDY...........r`.{....}..8..".,....}...lIa.;...b..c..d....e...f..g%.c*I.h..i!...j).k.B.lH.m.=C5*@.n -.1].oQ.t..Ip.().{..Isetdtr..(C.);.Idoelay..1>..z..1....rC...}M.q.(..r..R.lIs|...w(...P)e..P;..r..0.t0.u.,~..v.,lIw;..1.v.){.i(.!..D).b;..'.P='.D.o.i(.-.>....j....IUx..y[.za.A..N8.B.=..C.C -.UzN.D..A..y~..:...NC2<..y3.N....}.a....e{2.g.$. -...=.v.[.A{.D..d -(."M.A(.....r..a....f.u...ep.G...PQ...R.."E..F|.UG..H..F..F.....F.E%.r0.-.&.+ F..r-U.I.I.(lIJ..K.......j J|.J.w/C2 -.K.D..R,.%..H#LH"M.!.NM".!progr?esstex7 ....$..percen.tage..6...dGirt.".!')O...*IP.$Q.1*I.R..S -.TF0;?.0..<..U.04..#.."version>P0GC9.|.0. .#....!g..hon}es0tings..|@1n!T.EC8i.r.!...y.1?<.. -.0U..2..v1..3.)1..4.34.44..0.printf.(.STS: cou.ldn't .. .size of CROa..5....+i.z.3( -.9.)< -.R.!R .>@S).4.A.C1S..464?4W>45W5R..6=..F..A."..:f0^.8.. 15..w.9..8.I.;I.x...FON.E@%x, le?n=%d, ....+.,t.+w.,.!.... /Q.AP. ...@.....a.rF..Q>.Z!.. -P.-G.%+..$..e..2'.SV."W@P*I.X..Y... Z..a.a.CIba.[C.40.].aIfl.ush..send.s.QSATI3 -|.R!*SENT ....b..linf1Q.,WC3?..1.Q;.R.....8@.b}+fw .query go.t '%s'.,...i }efirmw.areb6. ..15..]mb..vb.`..c.m.`M.,SV1..001_WEBT.V-K56_DLB.0EDc8.!q..YE....;E.;.....b.?.....U S:.:..:i.sRockwel.l."..."..\....p|....+MR=0............CX. t.est retu.rned......O..`m....e...#S2.20.../..........._ x....+k1....0&.X#..s3&P..t6............Xt..... -Z....&.;2 -.c%a..d....e.C.......g. .O.A....2.p@....Ii...A;61.AcIj...0.#.k#.7#.l5.8.5.mv.^.G.9G.*.InQ0S1.aT.oZ..pb.Iq..r ..s..t..u..=.e.nablemod.em..tflow.controlN../S].baud^.>..pOeIv ...D2GV1E.0.3..3..T...P@..@..@.. -@...@.........d.[[ound v..@ .@jP, di9s..x. 56..]....p.....`.4....F..|!X....!a...+.+MS=11,.....[...,.,SS.51=3*.....R...@ss@.38=0S.30=180S9.5=36;.L3&.Q5&K.c. u ..qVP.5.I &(I...nec..with.videoa..)QN... B.M..e...... 5.S6=101X.r:...4XNr....0GC7o.. x.. ......#1.!....2"..6. .p1.8?.I..d.I.9}.....K.|....,.(./4.cw-.hack@...F.C.., .. S10=S%sS...,.A,.1.,.1,~1e.:.9....+....0$..0=S3...#...2.."./.1.....m......a.."A ...b..,.s.n..Z ......@..m9..1=@..P.'...(.(.1...( -. (.Q.6P...'. P.. .P.C..|..}5.&P.C..-.h.-.b..3..9.2.4.Cetw.indow....;0.~j.Iw.cx,pl.Iy~o~o~o~e..v..@Jc6dA.....bB..g2.cC.g3ndD.I..b8<....V.M..L.H..Y....-J...R.O...&!..g-Us..QLD pref.ix.+W.....S,..%..........5.5..KG9.9.9...!q..r.A.E..F......P.<=.....<...wa.itfo..H..p...),C7;.6....p.fig ....L.b..?: TIMEO.UT f.\qj. OWK (V.=..)=..I...x..G....C..... from .l.,..Y.d..S...T7.B.G..H..I -....statu..C.6F.J..C.B.....:...8.p..._.,S.lp*.*.%.orce.hook.....rt....K>.lIL.5.M|.N...R..=I.|._parser/esul_p@4.0.r5.b....@Ic9..e>.C..#T.NC4?255464...].V. -- %d /%s (..c...p...k....,..j#b{.&x...r..Up...oa -.....%`..: ...7.$..q%..q&.N.O CARRIE.R-.<-...- DI.ALTONE\.5x\.....BUSY...7..{@. ANSW.......G......L.C....C..ed!...e..*.&.*..-.C.p.b....E.E.~..0..2?..3G.b2..9.pm.2>.2.....34<.:<.<...)4...pd..4.......5.55.4....1c...|...i ->.p;#>.N..79>....?'..4s...83. .*5.M.....58....C.&.96.%:.........8.B. .A.jP.1R..9unknown..3..9|.<.<..?.>..6..O..PJ.J.J."J.QJ..@..R..J.uS..:..lIT..qU..0.<.*IV...W..X..\.h.....?,SISP-.R...1.+..,..C1?.u0...b .....e.*......ork..nu.mbeyq......=.IYKaA.....=I9E....,C2#......G....3..a..=.....+0C....>..d.!.&G.&...t....|b.....Z..s....P|...........A.TDP... -9...= v.R.......,:"....x.....Pb....k@P..D.....&.!<4.!b@...B r.c .W. r.r..., .ti.r...x..9B.,>.I.a.ler..SErr...!.: Your. recei.. .can.... to. WebTV. .Please{.t.a..Custom.0.Care at. 1-800-4.69-3288..J.. 3.i(e"...p.......6........ ........&.}.$g..c..#E. .3=..#;....%3L....0]...f.ancy....l..6.:.....S;G...6..Id - .A.O.IIir.G1.CuHlIew....Iw....... z..y......46.MC -...%w.0eL.N.<..D..w..lin...B.A&.@06..H.b.1...E.....U.. @.W...P....`..1eh.8kd...=..Iatoi..Dr...(.B.~)3A...i.@R..Bdela..PC;.S,Pf.12@..n..r.2c...g]0.odd...S..{.\.QNmU........Q..r.q......T.....E.IgoA=.5S.h -...s.dter{at.q, dc...prot..com.p.p.!..h!.......g/'.d.i.@!.l.j.8...9..r,l*I.kb.r..=X.V.T...Q!.P.....XQ.p,.X......al. g.../%sa.x.v...v....7dx..26...@.i.aP.failur.e,.$2...;.....| .s.....,`.....O.....l:.m,.nt....u7.nam.1.....pass#.d@vP*.........o.a.5.2.2..rtpp.4.T.u..Ap.P..)...=.AP/CHA?P auth..0..:0.0.PP ne.?0ia.AI.e_"r.C;0.........O..s.c..)<.....F.WARNING.@{S &. low.3..q6..R5q....rT"..Ys.#t.#u.#.c..[C3y.....0.`)U..8.Iii.>..NT%...,S.#..'....).08..I.1u.tefc.1^..v...V...k.:"p..M...sUs@1.. wi..".A/.D..l$r.". ..cv.dlIJ..J...system_>.`boxfe. ...la.. -.J..55G464b..2..IU.AJ..-a..-a..w........b...n."D.s.uppor.%.6.....u.h.......R..Ag........k.x..RlPyA.sPz..A -.uB..C.SlIDf.cEbUS#...tiyA.C76:7f1#.#....yea..gA:....dl`/.local...I.g.nCk.NC7.;2(.{../.z./._ 7_..../.. 6..c./.. 5 ..........Z.. ..7.........lIS:..L^.Premp<..to 6pl.......a$cVO.}.,=.c...[C8n...SD...%s .@........f.bf.f.f.f.A/.Nj.j...c.......WebTV...8....0.Wai.A...+.1...a.IS..n.swee.].=.\....-...M.....V -O.(..(...yI. ....v..4.4....*....rn ..k@..L(..Tx.bg..af....ebU..V*..W..X..Y.SW..windowsi.z;..u.........r.O.(@......ub.5.badQ(sVx. .(%d) for. Open...`.R8..$.Kr12#..o..t10..L0o..u1.d.<.J.m.i.j.S.-..-.1I...t.s...a...`..o.)....e.......,1.]...!..*...]...%.br..&! P.#. =y#mQ. x....."..Y...... ..........T..).,`+..r1.ZyS.{A.,se..tsf /4 7.7 (ANI=(...et)).uan.i..w.+.#.....I)l....k_.Z..g................n{amt.rvic...9=39==33\o. -.<32..na..IoA.i.=S |....[C6.]...0..9.....p. ).NN.=C6..G.5G....V.{.....7e.6Jt.8t.4J...j.. -.u.f. -.W.4..9....+...8...*...5RK.h ...h..; -..1..6....=C5 9-...6..3...K.U=^.4..;..:[..&.w.....3.w..@o..:.o.I.:..~......,.o.,.........~.I5....>....?...;.Q.{.ev..nlIUa..b..c..d...f..b..g.....!r. -r..y.........O.~........ \ No newline at end of file diff --git a/hacktv_updsrv/ServiceDeps/LC2/LC2_OISP_5555732_56k.tok b/hacktv_updsrv/ServiceDeps/LC2/LC2_OISP_5555732_56k.tok new file mode 100644 index 00000000..a8116c0a Binary files /dev/null and b/hacktv_updsrv/ServiceDeps/LC2/LC2_OISP_5555732_56k.tok differ diff --git a/hacktv_updsrv/ServiceDeps/LC2/LC2_WTV_18006138199_56k.tok b/hacktv_updsrv/ServiceDeps/LC2/LC2_WTV_18006138199_56k.tok new file mode 100644 index 00000000..ee52443d Binary files /dev/null and b/hacktv_updsrv/ServiceDeps/LC2/LC2_WTV_18006138199_56k.tok differ diff --git a/hacktv_updsrv/ServiceVault/htv-update/update.html b/hacktv_updsrv/ServiceVault/htv-update/update.html index 11a29cd0..b07096b7 100644 --- a/hacktv_updsrv/ServiceVault/htv-update/update.html +++ b/hacktv_updsrv/ServiceVault/htv-update/update.html @@ -2,7 +2,7 @@ Retrieving Files diff --git a/hacktv_updsrv/ServiceVault/htv-update/updatemenu.txt b/hacktv_updsrv/ServiceVault/htv-update/updatemenu.txt deleted file mode 100644 index e2aea456..00000000 --- a/hacktv_updsrv/ServiceVault/htv-update/updatemenu.txt +++ /dev/null @@ -1,16 +0,0 @@ -200 OK -Connection: Keep-Alive -wtv-expire-all: wtv-home:/splash -Content-type: text/html - - - - - - - -Check for HackTV Updates
-Unlock Full Client (Options, Goto, etc)
-Splash test - - \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-1800/finish-prereg.js b/hacktv_updsrv/ServiceVault/wtv-1800/finish-prereg.js new file mode 100644 index 00000000..1e607636 --- /dev/null +++ b/hacktv_updsrv/ServiceVault/wtv-1800/finish-prereg.js @@ -0,0 +1,45 @@ +if (socket_session_data[socket.id].ssid != null && !sec_session[socket_session_data[socket.id].ssid]) { + sec_session[socket_session_data[socket.id].ssid] = new WTVNetworkSecurity(); + sec_session[socket_session_data[socket.id].ssid].IssueChallenge(); + sec_session[socket_session_data[socket.id].ssid].set_incarnation(initial_headers['wtv-incarnation']); +} + +var contype = "text/tellyscript"; + +// skip telly for now +var notelly = true; + +// if relogin, skip tellyscript +if (query['relogin']) { + contype = "text/html"; // skip tellyscript + sec_session[socket_session_data[socket.id].ssid].ticket_b64 = null; // clear old ticket +} + +headers = `200 OK +Connection: Keep-Alive +wtv-initial-key: ` + issueWTVInitialKey(socket) + ` +Content-Type: `+ contype + ` +wtv-service: reset +`+getServiceString('wtv-star')+` +`+getServiceString('wtv-head-waiter')+` +`+getServiceString('wtv-flashrom')+` +wtv-boot-url: wtv-1800:/preregister?relogin=true +wtv-visit: wtv-head-waiter:/login? +wtv-client-time-zone: GMT -0000 +wtv-client-time-dst-rule: GMT +wtv-client-date: `+strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString()))+` GMT`; + +// if relogin, skip tellyscript +if (query['relogin'] == false || notelly == false) { + var romtype = getSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type'); + + switch (romtype) { + case "US-LC2-disk-0MB-8MB": + data = getFile("LC2/LC2_OISP_5555732_56k.tok", true); + break; + + default: + data = ''; + break; + } +} \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-1800/mame.jpg b/hacktv_updsrv/ServiceVault/wtv-1800/mame.jpg deleted file mode 100644 index 2c3bdc9d..00000000 Binary files a/hacktv_updsrv/ServiceVault/wtv-1800/mame.jpg and /dev/null differ diff --git a/hacktv_updsrv/ServiceVault/wtv-1800/offer-open-isp-suggest.js b/hacktv_updsrv/ServiceVault/wtv-1800/offer-open-isp-suggest.js deleted file mode 100644 index b61b6fe0..00000000 --- a/hacktv_updsrv/ServiceVault/wtv-1800/offer-open-isp-suggest.js +++ /dev/null @@ -1,37 +0,0 @@ -if (socket_session_data[socket.id].ssid != null && !sec_session[socket_session_data[socket.id].ssid]) { - sec_session[socket_session_data[socket.id].ssid] = new WTVNetworkSecurity(); - sec_session[socket_session_data[socket.id].ssid].IssueChallenge(); - sec_session[socket_session_data[socket.id].ssid].set_incarnation(initial_headers['wtv-incarnation']); -} - -headers = `200 OK -Connection: Close -wtv-initial-key: ` + issueWTVInitialKey(socket) + ` -Content-Type: text/html -wtv-service: reset -wtv-service: name=wtv-* host=` + pubip + ` port=`+port+` flags=0x00000007 -wtv-service: name=wtv-head-waiter host=` + pubip + ` port=`+port+` flags=0x04 flags=0x00000001 connections=1 -wtv-service: name=wtv-flashrom host=` + pubip + ` port=`+port+` flags=0x00000040 -wtv-service: name=htv-update host=` + pubip + ` port=`+port+` flags=0x04 -wtv-boot-url: wtv-head-waiter:/login? -wtv-visit: wtv-head-waiter:/login? -wtv-client-time-zone: GMT -0000 -wtv-client-time-dst-rule: GMT -wtv-client-date: `+strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString()))+` GMT`; - - -/* -var romtype = socket_session_data[socket.id].romtype; - -switch (romtype) { - case "US-LC2-disk-0MB-8MB": - data = getFile("LC2/artemis_18004653537.tok",true); - break; - - default: - data = ''; - break; -} - -*/ -data=''; \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-1800/preregister.js b/hacktv_updsrv/ServiceVault/wtv-1800/preregister.js index ea2b814b..41ef0928 100644 --- a/hacktv_updsrv/ServiceVault/wtv-1800/preregister.js +++ b/hacktv_updsrv/ServiceVault/wtv-1800/preregister.js @@ -1,10 +1,34 @@ -var gourl = "wtv-1800:/offer-open-isp-suggest?"; -if (initial_headers['wtv-ticket']) { - gourl = "wtv-head-waiter:/login-stage-two?"; -} +var gourl = "wtv-1800:/finish-prereg?"; +if (query['relogin']) gourl += "relogin=true"; -headers = `200 OK + +if (query['reconnect']) { + headers = `200 OK Connection: Keep-Alive +wtv-expire-all: wtv- +wtv-expire-all: htv-` + + if (sec_session[initial_headers['wtv-client-serial-number']].ticket_b64) { + headers += "wtv-encrypted: true\n"; + headers += "wtv-ticket: " + sec_session[initial_headers['wtv-client-serial-number']].ticket_b64 + "\n"; + } + + headers += `wtv-client-time-zone: GMT -0000 +wtv-client-time-dst-rule: GMT +wtv-client-date: `+ strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString())) + ` GMT +Content-type: text/html`; +} else { + + if (initial_headers['wtv-ticket']) { + gourl = "wtv-head-waiter:/login-stage-two?"; + } + + headers = `200 OK +Connection: Keep-Alive +wtv-expire-all: wtv- +wtv-expire-all: htv- wtv-open-isp-disabled: false -wtv-visit: wtv-1800:/offer-open-isp-suggest? -Content-type: text/html`; \ No newline at end of file +wtv-visit: `+ gourl + ` +Content-type: text/html`; + +} \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-1800/test.js b/hacktv_updsrv/ServiceVault/wtv-1800/test.js deleted file mode 100644 index 2b1f464b..00000000 --- a/hacktv_updsrv/ServiceVault/wtv-1800/test.js +++ /dev/null @@ -1,9 +0,0 @@ -var wtv = new WTVNetworkSecurity(); -var test = CryptoJS.enc.Utf8.parse("this is a test"); -var test2 = wtv.wordArrayToUint8Array(test); -var test3 = CryptoJS.lib.WordArray.create(test2); -headers = `200 OK -Connection: Close -Content-type: text/plain` - -data = test3.toString(CryptoJS.enc.Utf8); \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-head-waiter/finalize-security.js b/hacktv_updsrv/ServiceVault/wtv-head-waiter/finalize-security.js index 5bb623cb..ea99b6e5 100644 --- a/hacktv_updsrv/ServiceVault/wtv-head-waiter/finalize-security.js +++ b/hacktv_updsrv/ServiceVault/wtv-head-waiter/finalize-security.js @@ -18,6 +18,7 @@ Connection: Keep-Alive wtv-encrypted: true wtv-ticket: `+sec_session[socket_session_data[socket.id].ssid].ticket_b64+` wtv-expire-all: htv- +wtv-home-url: wtv-home:/home? wtv-visit: wtv-home:/splash? Content-Type: text/html `; \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-head-waiter/login-stage-two.js b/hacktv_updsrv/ServiceVault/wtv-head-waiter/login-stage-two.js index bdbecf76..9c2f99be 100644 --- a/hacktv_updsrv/ServiceVault/wtv-head-waiter/login-stage-two.js +++ b/hacktv_updsrv/ServiceVault/wtv-head-waiter/login-stage-two.js @@ -16,11 +16,12 @@ if (socket_session_data[socket.id].ssid !== null) { //if (challenge_response.toString(CryptoJS.enc.Base64).substring(0,85) == client_challenge_response.substring(0,85)) { if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) { console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid); - if (zdebug) console.log("Response Expected:",challenge_response.toString(CryptoJS.enc.Base64)); - if (zdebug) console.log("Response Received:",client_challenge_response) sec_session[socket_session_data[socket.id].ssid].PrepareTicket(); //socket_session_data[socket.id].secure = true; } else { + console.log(" * wtv-challenge-response FAILED for " + socket_session_data[socket.id].ssid); + if (zdebug) console.log("Response Expected:", challenge_response.toString(CryptoJS.enc.Base64)); + if (zdebug) console.log("Response Received:", client_challenge_response) gourl = "wtv-head-waiter:/login?reissue_challenge=true"; } } else { @@ -31,55 +32,55 @@ if (socket_session_data[socket.id].ssid !== null) { } if (gourl) { -headers = `200 OK + headers = `200 OK Connection: Keep-Alive wtv-open-isp-disabled: false -wtv-visit: `+gourl+` +wtv-visit: `+ gourl + ` Content-type: text/html`; data = ''; -} else { - var nickname = 'HackTVUsr_'+Math.floor(Math.random() * 100000); +} +else { + var namerand = Math.floor(Math.random() * 100000); + var nickname = 'HackTVUsr_' + namerand; + var userid = '1'+ Math.floor(Math.random() * 1000000000000000000); + var offline_user_list = CryptoJS.enc.Latin1.parse("\n\t\n").toString(CryptoJS.enc.Base64); + headers = `200 OK Connection: Keep-Alive wtv-encrypted: true -wtv-ticket: `+sec_session[socket_session_data[socket.id].ssid].ticket_b64+` wtv-client-time-zone: GMT -0000 -wtv-client-date: `+strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString()))+` GMT +wtv-client-date: `+ strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString())) + ` GMT wtv-country: US wtv-language-header: en-US,en -wtv-tv-zipcode: 90210 wtv-visit: client:closeallpanels -wtv-messagewatch-checktimeoffset: off wtv-expire-all: client:closeallpanels +wtv-offline-user-list: `+offline_user_list+` +wtv-bypass-proxy: true +wtv-ticket: `+ sec_session[socket_session_data[socket.id].ssid].ticket_b64 + ` +wtv-messagewatch-checktimeoffset: off wtv-input-timeout: 14400 wtv-connection-timeout: 90 wtv-fader-timeout: 900 wtv-ssl-log-url: wtv-log:/log wtv-smartcard-inserted-message: Contacting service -user-id: 1`+Math.floor(Math.random() * 1000000000000000000)+` +user-id: `+userid+` wtv-transition-override: off -wtv-bypass-proxy: true wtv-allow-dsc: true wtv-messenger-enable: 0 wtv-noback-all: wtv- wtv-service: reset -wtv-service: name=wtv-1800 host=` + pubip + ` port=` + port + ` connections=1 -wtv-service: name=wtv-head-waiter host=` + pubip + ` port=` + port + ` flags=0x04 flags=0x00000001 connections=1 -wtv-service: name=htv-update host=` + pubip + ` port=` + port + ` connections=3 -wtv-service: name=wtv-log host=` + pubip + ` port=` + port + ` connections=1 -wtv-service: name=wtv-home host=` + pubip + ` port=` + port + ` flags=0x00000010 -wtv-boot-url: wtv-1800:/preregister -wtv-user-name: `+nickname+` -wtv-human-name: `+nickname+` -wtv-irc-nick: `+nickname+` -wtv-home-url: htv-update:/update? +`+ getServiceString('all') + ` +wtv-boot-url: wtv-1800:/preregister?relogin=true +wtv-user-name: `+ nickname + ` +wtv-human-name: `+ nickname + ` +wtv-irc-nick: `+ nickname + ` +wtv-home-url: wtv-home:/home? wtv-domain: wtv.zefie.com wtv-inactive-timeout: 0 wtv-connection-timeout: 90 wtv-show-time-enabled: true wtv-fader-timeout: 900 wtv-tourist-enabled: true -wtv-boot-url: wtv-head-waiter:/login wtv-connection-timeout: 180 wtv-ssl-timeout: 240 wtv-login-timeout: 7200 @@ -87,9 +88,7 @@ wtv-open-isp-disabled: false wtv-log-url: wtv-log:/log wtv-demo-mode: 0 wtv-wink-deferrer-retries: 3 -wtv-offline-mail-enable: true -wtv-visit: wtv-head-waiter:/finalize-security? +wtv-offline-mail-enable: false +wtv-visit: wtv-home:/splash? Content-Type: text/html`; - -data = ''; } \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-head-waiter/login.js b/hacktv_updsrv/ServiceVault/wtv-head-waiter/login.js index fd40b586..7ae2ae77 100644 --- a/hacktv_updsrv/ServiceVault/wtv-head-waiter/login.js +++ b/hacktv_updsrv/ServiceVault/wtv-head-waiter/login.js @@ -6,17 +6,15 @@ if (socket_session_data[socket.id].ssid !== null) { if (initial_headers['wtv-ticket'].length > 8) { sec_session[socket_session_data[socket.id].ssid].DecodeTicket(initial_headers['wtv-ticket']); sec_session[socket_session_data[socket.id].ssid].ticket_b64 = initial_headers['wtv-ticket']; - //socket_session_data[socket.id].secure = true; } - } + } } else { challenge_response = sec_session[socket_session_data[socket.id].ssid].challenge_response; var client_challenge_response = initial_headers['wtv-challenge-response'] || null; if (challenge_response && client_challenge_response) { if (challenge_response.toString(CryptoJS.enc.Base64).substring(0,85) == client_challenge_response.substring(0,85)) { console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid); - sec_session[socket_session_data[socket.id].ssid].PrepareTicket(); - //socket_session_data[socket.id].secure = true; + sec_session[socket_session_data[socket.id].ssid].PrepareTicket(); } else { challenge_header = "wtv-challenge: "+issueWTVChallenge(socket); } @@ -26,6 +24,7 @@ if (socket_session_data[socket.id].ssid !== null) { } } +/* if (initial_headers) { var cookiedata = {}; Object.keys(initial_headers).forEach(function (k) { @@ -41,14 +40,13 @@ if (initial_headers) { break; } }); - cookie_dat[socket_session_data[socket.id].ssid] = CryptoJS.enc.Utf8.parse(JSON.stringify(cookiedata)).toString(CryptoJS.enc.Base64); } - +*/ headers = `200 OK Connection: Keep-Alive Expires: Wed, 09 Oct 1991 22:00:00 GMT wtv-expire-all: wtv-head-waiter: -wtv-service: name=wtv-log host=` + pubip + ` port=`+port+` connections=1 +`+getServiceString('wtv-log')+` wtv-log-url: wtv-log:/log `+challenge_header+` wtv-relogin-url: wtv-1800:/preregister?relogin=true diff --git a/hacktv_updsrv/ServiceVault/wtv-home/home.js b/hacktv_updsrv/ServiceVault/wtv-home/home.js new file mode 100644 index 00000000..b8abbdb7 --- /dev/null +++ b/hacktv_updsrv/ServiceVault/wtv-home/home.js @@ -0,0 +1,37 @@ +headers =`200 OK +Connection: Keep-Alive +wtv-expire-all: wtv-home:/splash +wtv-expire-all: htv- +Content-type: text/html` + +if (initial_headers['psuedo-encryption']) { + var cryptstatus = "Psuedo-encrypted"; +} else { + var cryptstatus = ((socket_session_data[socket.id].secure === true) ? "Encrypted" : "Not Encrypted") +} + + +data =` + + + + + +

Encryption Status: `+cryptstatus+`

` +if (socket_session_data[socket.id].secure) { + data += 'Encryption Key (Server): ' + sec_session[socket.id].session_key2.toString(CryptoJS.enc.Hex)+'
'; + data += 'Encryption Key (Client): ' + sec_session[socket.id].session_key1.toString(CryptoJS.enc.Hex)+'


'; +} +data += `client:relog (via text/url)
+client:relog (direct)
+HackTV Updater Test
+ + + +` \ No newline at end of file diff --git a/hacktv_updsrv/ServiceVault/wtv-home/splash.txt b/hacktv_updsrv/ServiceVault/wtv-home/splash.txt index ca62b258..c97f3d67 100644 --- a/hacktv_updsrv/ServiceVault/wtv-home/splash.txt +++ b/hacktv_updsrv/ServiceVault/wtv-home/splash.txt @@ -8,7 +8,7 @@ Content-type: text/html diff --git a/hacktv_updsrv/ServiceVault/wtv-log/phone-log.js b/hacktv_updsrv/ServiceVault/wtv-log/phone-log.js new file mode 100644 index 00000000..78cd7415 --- /dev/null +++ b/hacktv_updsrv/ServiceVault/wtv-log/phone-log.js @@ -0,0 +1,10 @@ +// dummy page, we could handle the logs here. + +headers = `200 OK +Connection: Keep-Alive +wtv-visit: wtv-home:/splash? +Content-length: 0`; + +data = ''; + + diff --git a/hacktv_updsrv/app.js b/hacktv_updsrv/app.js index 0f9deb22..40c8a5e3 100644 --- a/hacktv_updsrv/app.js +++ b/hacktv_updsrv/app.js @@ -10,13 +10,30 @@ const mime = require('mime-types'); var WTVNetworkSecurity = require('./wtvsec.js'); var zdebug = true; -var secure_mode = true; var pubip = "192.168.11.8"; -var port = 1615; +var ports = []; +//pubip = getPublicIP(); + +function getServiceString(service) { + if (service === "all") { + var out = ""; + Object.keys(services_configured.services).forEach(function (k) { + out += services_configured.services[k].toString() + "\n"; + }); + return out; + } else { + if (!services_configured.services[service]) { + throw ("SERVICE ERROR: Attempted to provision unconfigured service: " + service) + } else { + return services_configured.services[service].toString(); + } + } +} + +var ssid_data = new Array(); var sec_session = new Array(); -var cookie_dat = new Array(); var socket_buffer = new Array(); var socket_session_data = new Array(); @@ -24,6 +41,19 @@ var overrides = new Array(); //overrides['initial_key'] = "CC5rWmRUE0o="; //overrides['challenge'] = "0kjyqIYAu0ziFBbSERN6DGaZ6S0fT+DBUCtpHCJ4lpuM7CbXdAm+x83BIDoJYztd1Z+5KFZ7ghmb3LJCT/6mhWUYkqqKOyfPRW8ZIdbICK/CV+Kxm8EUjRXZSk/97tsmFpH3hcCJ7C2TBw+TX38uQQ=="; +function getSessionData(ssid, key = null) { + if (typeof (ssid_data[ssid]) === 'undefined') return null; + if (key == null) return ssid_data[ssid]; + else if (ssid_data[ssid][key]) return ssid_data[ssid][key]; + else return null; +} + +function setSessionData(ssid, key, value) { + if (typeof (ssid_data[ssid]) === 'undefined') ssid_data[ssid] = new Array(); + ssid_data[ssid][key] = value; +} + + function getPublicIP() { var options = { host: 'www.planeptune.org', @@ -53,6 +83,7 @@ function getFile(path, deps = false) { return null; } + function issueWTVInitialKey(socket) { if (overrides['initial_key']) { sec_session[socket_session_data[socket.id].ssid].initial_shared_key = CryptoJS.enc.Base64.parse(overrides['initial_key']); @@ -113,14 +144,14 @@ function processPath(socket, path, initial_headers = new Array(), query = new Ar if (request_is_direct_file) { // file exists, read it and return it - console.log(" * Found " + path + " to handle request (Direct File Mode)"); + console.log(" * Found " + path + " to handle request (Direct File Mode) [Socket " + socket.id +"]"); var contype = mime.lookup(path); data = fs.readFileSync(path).buffer; headers = "200 OK\n" headers += "Content-Type: " + contype; } else if (fs.existsSync(path + ".txt")) { // raw text format, entire payload expected (headers and content) - console.log(" * Found " + path + ".txt to handle request (Raw TXT Mode)"); + console.log(" * Found " + path + ".txt to handle request (Raw TXT Mode) [Socket " + socket.id +"]"); var fdat = fs.readFileSync(path + ".txt").toString(); if (fdat.indexOf("\n\n") > 0) { var fdata = fdat.split("\n\n"); @@ -137,12 +168,12 @@ function processPath(socket, path, initial_headers = new Array(), query = new Ar // js scripting, process with vars, must set 'headers' and 'data' appropriately. // loaded script will have r/w access to any JavaScript vars this function does. // any query args are in an array named 'query' - console.log(" * Found " + path + ".js to handle request (JS Interpreter mode)"); + console.log(" * Found " + path + ".js to handle request (JS Interpreter mode) [Socket "+socket.id+"]"); var fdat = fs.readFileSync(path + ".js").toString(); eval(fdat); } else if (fs.existsSync(path + ".html")) { // Standard HTML with no headers, WTV Style - console.log(" * Found " + path + ".html to handle request (HTML Mode)"); + console.log(" * Found " + path + ".html to handle request (HTML Mode) [Socket " + socket.id +"]"); data = fs.readFileSync(path + ".html").toString(); headers = "200 OK\n" headers += "Content-Type: text/html" @@ -216,10 +247,13 @@ function processURL(socket, initial_headers) { if (initial_headers['encrypted'] || initial_headers['secure']) { reqverb = "Encrypted " + reqverb; } + if (initial_headers['psuedo-encryption']) { + reqverb = "Psuedo-encrypted " + reqverb; + } if (ssid != null) { - console.log(" * "+reqverb+" for " + initial_headers['request_url'] + " from WebTV SSID " + ssid); + console.log(" * "+reqverb+" for " + initial_headers['request_url'] + " from WebTV SSID " + ssid, 'on', socket.id); } else { - console.log(" * "+reqverb+" for " + initial_headers['request_url']); + console.log(" * "+reqverb+" for " + initial_headers['request_url'], 'on', socket.id); } // assume webtv since there is a :/ in the GET var urlToPath = __dirname + "/ServiceVault/" + shortURL.split(':/')[0] + "/" + shortURL.split(':/')[1]; @@ -276,6 +310,16 @@ function processURL(socket, initial_headers) { header_obj = headers; } + if (!headers_obj['Connection']) { + headers_obj['Connection'] = "Keep-Alive"; + headers_obj = moveObjectElement('Connection','http_response', headers_obj); + } + + if (initial_headers['psuedo-encryption']) { + headers_obj['wtv-encrypted'] = true; + headers_obj = moveObjectElement('wtv-encrypted', 'Connection', headers_obj); + } + // set wtv-encrypted and put it near the top of the headers (unknown if needed) if (socket_session_data[socket.id].secure == true) { var clen = null; @@ -291,7 +335,7 @@ function processURL(socket, initial_headers) { if (typeof (data) === 'string') { data = CryptoJS.enc.Utf8.parse(data); } - var enc_data = sec_session[socket_session_data[socket.id].ssid].Encrypt(1,data); + var enc_data = sec_session[socket.id].Encrypt(1,data); data = enc_data; } } @@ -316,7 +360,7 @@ function processURL(socket, initial_headers) { socket.write(toClient); } else if (typeof data == 'object') { if (socket_session_data[socket.id].secure_headers == true) { - var enc_headers = sec_session[socket_session_data[socket.id].ssid].Encrypt(1,headers+"\n"); + var enc_headers = sec_session[socket.id].Encrypt(1,headers+"\n"); socket.write(new Uint8Array(concatArrayBuffer(enc_headers, data))); } else { socket.write(new Uint8Array(concatArrayBuffer(Buffer.from(headers + "\n"), data))); @@ -360,14 +404,16 @@ function moveObjectElement(currentKey, afterKey, obj) { if (next !== -1) return result; else return obj; } -function headersAreStandard(string) { +function headersAreStandard(string, verbose) { // the test will see the binary compressed/enrypted data as ASCII, so a generic "isAscii" // is not suffuicent. This checks for characters expected in unecrypted headers, and returns // true only if every character in the string matches the regex. Once we know the string is binary // we can better process it with the raw base64 data in processHeaders() below. var test = /^([A-Za-z0-9\+\/\=\-\.\,\ \;\:\?\&\r\n\(\)\%\<\>\_]{8,})$/.test(string); - if (zdebug) console.log("request is ascii: " + test); - if (zdebug) console.log("request is SECURE ON: " + /^SECURE ON/.test(string)); + if (verbose) { + if (zdebug) console.log("request is ascii: " + test); + if (zdebug) console.log("request is SECURE ON: " + /^SECURE ON/.test(string)); + } return test; } @@ -379,14 +425,12 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc if (typeof data === "string") { if (data.length > 1) { data = data.split("\r\n\r\n")[0]; - if (headersAreStandard(data)) { + if (headersAreStandard(data, (!returnHeadersBeforeSecure && !encryptedRequest))) { data.split('\n').forEach(function (d) { if (d.length > 0) { if (/^SECURE ON/.test(d)) { - secure_mode = true; headers['secure'] = true; - socket_session_data[socket.id].secure = true; - socket_session_data[socket.id].secure_headers = true; + //socket_session_data[socket.id].secure_headers = true; } if (d.indexOf(":") > 0 && d.indexOf(":/") == -1) { headers[d.split(':')[0]] = (d.split(':')[1]).replace("\r", ""); @@ -399,36 +443,43 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc } } }); - } else { + } else if (!returnHeadersBeforeSecure) { if (!encryptedRequest) { // failed the headersAreStandard test, so we think this is a binary blob if (socket_session_data[socket.id].secure != true) { // first time so reroll sessions - sec_session[socket_session_data[socket.id].ssid].SecureOn(); + sec_session[socket.id] = new WTVNetworkSecurity(); + sec_session[socket.id].IssueChallenge(); + console.log(" [ UNEXPECTED BINARY BLOCK ] First sign of encryption, re-creating RC4 sessions for socket id",socket.id); + sec_session[socket.id].SecureOn(); socket_session_data[socket.id].secure = true; } var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2)); if (enc_data.sigBytes > 0) { - var dec_data = CryptoJS.lib.WordArray.create(sec_session[socket_session_data[socket.id].ssid].Decrypt(0,enc_data)); + var dec_data = CryptoJS.lib.WordArray.create(sec_session[socket.id].Decrypt(0,enc_data)); var dec_data_text = dec_data.toString(CryptoJS.enc.Latin1); var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true, true); headers['encrypted'] = true; - console.log("Encrypted Request (Decrypted):", dec_data.toString(CryptoJS.enc.Latin1)); + console.log("Encrypted Request (Decrypted):", dec_data.toString(CryptoJS.enc.Latin1),"on",socket.id); Object.keys(secure_headers).forEach(function (k, v) { headers[k] = secure_headers[k]; }); } } } - if (headers['wtv-client-rom-type'] != null) { - socket_session_data[socket.id].romtype = headers['wtv-client-rom-type']; - } if (headers['wtv-client-serial-number'] != null) { socket_session_data[socket.id].ssid = headers['wtv-client-serial-number']; } + if (headers['wtv-client-rom-type'] != null) { + if (socket_session_data[socket.id].ssid) { + setSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type', headers['wtv-client-rom-type']); + } + } if (headers['wtv-incarnation'] != null) { - if (sec_session[socket_session_data[socket.id].ssid]) { - sec_session[socket_session_data[socket.id].ssid].set_incarnation(headers['wtv-incarnation']); + if (sec_session[socket.id]) { + sec_session[socket.id].set_incarnation(headers['wtv-incarnation']); + } else { + setSessionData(socket_session_data[socket.id].ssid, 'incarnation', headers['wtv-incarnation']) } } @@ -437,21 +488,47 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc } if (headers['secure'] === true) { - if (!sec_session[socket_session_data[socket.id].ssid]) { - sec_session[socket_session_data[socket.id].ssid] = new WTVNetworkSecurity(); - sec_session[socket_session_data[socket.id].ssid].DecodeTicket(headers['wtv-ticket']); - sec_session[socket_session_data[socket.id].ssid].ticket_b64 = headers['wtv-ticket']; - sec_session[socket_session_data[socket.id].ssid].SecureOn(); + if (!sec_session[socket.id]) { + console.log("Starting new WTVNetworkSecurity instance on socket", socket.id); + sec_session[socket.id] = new WTVNetworkSecurity(); + sec_session[socket.id].DecodeTicket(headers['wtv-ticket']); + sec_session[socket.id].ticket_b64 = headers['wtv-ticket']; + if (getSessionData(socket_session_data[socket.id].ssid, 'incarnation')) { + sec_session[socket.id].incarnation = getSessionData(socket_session_data[socket.id].ssid, 'incarnation'); + } + sec_session[socket.id].SecureOn(); + } + if (socket_session_data[socket.id].secure != true) { + // first time so reroll sessions + console.log(" [ SECURE ON BLOCK ("+socket.id+")]"); + socket_session_data[socket.id].secure = true; } if (!headers['request_url']) { - var header_length = data.length + 4; + + if (data_hex.indexOf("0d0a0d0a")) { + // \r\n\r\n + var header_length = data.length + 4; + } else if (data_hex.indexOf("0a0a")) { + // \n\n + var header_length = data.length + 2; + } var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2)); if (enc_data.sigBytes > 0) { - var dec_data = CryptoJS.lib.WordArray.create(sec_session[socket_session_data[socket.id].ssid].Decrypt(0,enc_data)) - //var dec_data_text = dec_data.toString(CryptoJS.enc.Latin1); - var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true); - console.log("Encrypted Request (Decrypted):", secure_headers.toString(CryptoJS.enc.Latin1)); - Object.keys(secure_headers).forEach(function (k,v) { + if (headersAreStandard(enc_data.toString(CryptoJS.enc.Latin1), (!returnHeadersBeforeSecure && !encryptedRequest))) { + // some builds (like our targeted 3833), send SECURE ON but then unencrypted headers + console.log("Psuedo-encrypted Request (SECURE ON)", "on", socket.id); + // don't actually encrypt output + headers['psuedo-encryption'] = true; + socket_session_data[socket.id].secure = false; + var secure_headers = processHeaders(socket, enc_data.toString(CryptoJS.enc.Hex), true); + } else { + // SECURE ON and detected encrypted data + var dec_data = CryptoJS.lib.WordArray.create(sec_session[socket.id].Decrypt(0, enc_data)) + var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true); + console.log("Encrypted Request (SECURE ON)", "on", socket.id); + } + // Merge new headers into existing headers object + Object.keys(secure_headers).forEach(function (k, v) { headers[k] = secure_headers[k]; }); } @@ -466,18 +543,18 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc return null; } -var server = net.createServer(function (socket) { - socket.id = Math.floor(Math.random() * 1000); + +function handleSocket(socket) { + socket.id = Math.floor(Math.random() * 100000); socket_session_data[socket.id] = []; socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64') - socket.on('data', function (data_hex) { socket.setTimeout(300); if (socket_buffer[socket.id]) { socket_buffer[socket.id].concat(CryptoJS.enc.Hex.parse(data_hex)); } else { socket_buffer[socket.id] = CryptoJS.enc.Hex.parse(data_hex); - } + } }); socket.on('timeout', function () { @@ -487,19 +564,57 @@ var server = net.createServer(function (socket) { }); socket.on('error', (err, socket) => { - console.log('client socket error:', err); + console.log(" * Client disconnected unexpectedly"); }); - socket.on('end', function () { - socket_buffer[socket.id] = null; - secure_mode = false; - socket_session_data[socket.id] = null; + socket.on('end', function () { + console.log(" * Destroying old WTVNetworkSecurity instance on socket", socket.id); + delete socket_buffer[socket.id]; + delete socket_session_data[socket.id]; + delete sec_session[socket.id]; }); +} + +var z_version = "0.5.1a"; +var z_title = "zefie's wtv minisrv v" + z_version; +console.log("**** Welcome to " + z_title + " ****"); + +console.log(" *** Reading service configuration..."); +var services_configured = JSON.parse(fs.readFileSync(__dirname + "/services.json")); +Object.keys(services_configured.services).forEach(function (k) { + services_configured.services[k].name = k; + if (!services_configured.services[k].host) { + services_configured.services[k].host = pubip; + } + if (services_configured.services[k].port) { + ports.push(services_configured.services[k].port); + } + services_configured.services[k].toString = function () { + var outstr = "wtv-service: name=" + this.name + " host=" + this.host + " port=" + this.port; + if (this.flags) outstr += " flags=" + this.flags; + if (this.connections) outstr += " flags=" + this.connections; + if (k == "wtv-star") { + outstr += "\nwtv-service: name=wtv-* host=" + this.host + " port=" + this.port; + if (this.flags) outstr += " flags=" + this.flags; + if (this.connections) outstr += " flags=" + this.connections; + } + return outstr; + } + console.log(" * Configured Service", k, "on port", services_configured.services[k].port); +}) + +var initstring = ''; +ports.sort(); +ports.forEach(function (v) { + try { + var server = net.createServer(handleSocket); + server.listen(v, '0.0.0.0'); + initstring += v + ", "; + } catch (e) { + throw ("Could not bind to port", v, e.toString()); + } }); +initstring = initstring.substring(0, initstring.length - 2); -server.listen(port, '0.0.0.0'); -process.stdout.write("Looking up public IP address... "); -//pubip = getPublicIP(); -console.log(pubip + " ..."); +console.log(" * Started server on ports " + initstring + "... Public IP is " + pubip); -console.log('Listening on port ' + port + ' for WebTV Units in Scriptless Mode'); \ No newline at end of file diff --git a/hacktv_updsrv/hacktv_updsrv.njsproj b/hacktv_updsrv/hacktv_updsrv.njsproj index 5758b1e2..0c783daf 100644 --- a/hacktv_updsrv/hacktv_updsrv.njsproj +++ b/hacktv_updsrv/hacktv_updsrv.njsproj @@ -29,11 +29,40 @@ + + Code + + + + + + + + + + + + + + + + + + Code + + + + + + + + + \ No newline at end of file diff --git a/hacktv_updsrv/services.json b/hacktv_updsrv/services.json new file mode 100644 index 00000000..19194250 --- /dev/null +++ b/hacktv_updsrv/services.json @@ -0,0 +1,38 @@ +{ + "services": { + + "wtv-1800": { + "port": 1615, + "connections": 1 + }, + "wtv-star": { + "port": 1603, + "flags": "0x00000007" + }, + "wtv-head-waiter": { + "port": 1601, + "flags": "0x00000001", + "connections": 1 + }, + "htv-update": { + "port": 1619, + "connections": 3 + }, + "wtv-log": { + "port": 1609, + "connections": 1 + }, + "wtv-home": { + "port": 1612, + "flags": "0x00000010" + }, + "wtv-tricks": { + "port": "1602", + "flags": "0x00000004" + }, + "wtv-flashrom": { + "port": 1618, + "flags": "0x00000040" + } + } +} diff --git a/hacktv_updsrv/wtvsec.js b/hacktv_updsrv/wtvsec.js index d95bb684..f4315de7 100644 --- a/hacktv_updsrv/wtvsec.js +++ b/hacktv_updsrv/wtvsec.js @@ -3,6 +3,8 @@ const endianness = require('endianness'); var crypto = require('crypto'); class WTVNetworkSecurity { + //initial_shared_key = CryptoJS.lib.WordArray.random(8); + initial_shared_key_b64 = "CC5rWmRUE0o="; initial_shared_key = null; current_shared_key = null; challenge_key = null; @@ -19,15 +21,13 @@ class WTVNetworkSecurity { zdebug = true; - constructor(wtv_initial_key = CryptoJS.lib.WordArray.random(8), wtv_incarnation = 1) { - var initial_key = wtv_initial_key; - + constructor(wtv_incarnation = 1) { this.zdebug = true; + this.initial_shared_key = CryptoJS.enc.Base64.parse(this.initial_shared_key_b64); - if (initial_key.sigBytes === 8) { + if (this.initial_shared_key.sigBytes === 8) { this.incarnation = wtv_incarnation; - this.initial_shared_key = initial_key; - this.current_shared_key = initial_key; + this.current_shared_key = this.initial_shared_key; } else { throw ("Invalid initial key length"); }