proper encryption sessions to maintain working RC4 stream

This commit is contained in:
zefie
2021-07-13 23:24:33 -04:00
parent 6229567272
commit 06dd3d7ebf
20 changed files with 397 additions and 197 deletions

View File

@@ -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.<C38l.,.A..C>..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....<z.>....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(.{.<b...e.L....av.Pt./.a...,M...%..........(b......,.x....A...yofwee.[AN...hr...U....min{0'.`...l..
.i.*...F*.*I.G..H..hrJ..K.........#.].....?rycoun.Qy.8"..tM.=Iq..n..
.nex..seq.Len.....T.qC.==.f(..=..;R..<....Pu.....=IL...u,..[z..]Z.K.,@....s..c..rMG.-....y.|..E..-7.r.%.]..qe$...W.mQ00.E.:.%.as..J..I........!r.r.r..r.r.r .1....ma.i..?.?.*..=@rA.4.DL.[C5.T.T...lINp.ti.ck~.le#
.!.7. g..v.O*..Q......+<C9..PU...qc..A...rog3..s.iJ.fullp.op....S.......r..E....,C2.....o.Q.+L...s.:'.&!z...?.....R.)..~...+.su{cc.., in.@.]0A..(..-..)./C3<..:. ..?...:.. #..d.;.@i.i........1Y..X. u...i(Z.[PP.]&.8V...2..0...3..)|~././. >./.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<y.....q..SERROR. 0.......pue.od)....u:@..0..".u<..3..u>#..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.~........

Binary file not shown.

View File

@@ -2,7 +2,7 @@
<head> <head>
<meta <meta
http-equiv=refresh http-equiv=refresh
content="0;url=client:Fetch?source=htv-update:/upd?diskmap=update&root=file://Disk/Browser&group=hacktv" content="0;url=client:Fetch?source=htv-update:/upd?diskmap=update&root=file://Disk/Browser/&group=hacktv"
> >
<display downloadsuccess="client:ShowAlert?message=HackTV%20Update%20was%20successful%21&buttonlabel2=Go%20to%20HackTV&action2=file%3A%2F%2FDisk%2FBrowser%2FGames%2FGames.html&buttonlabel1=Okay&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true" downloadfail="client:ShowAlert?message=HackTV%20Update%20failed...&buttonlabel1=Okay...&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true"> <display downloadsuccess="client:ShowAlert?message=HackTV%20Update%20was%20successful%21&buttonlabel2=Go%20to%20HackTV&action2=file%3A%2F%2FDisk%2FBrowser%2FGames%2FGames.html&buttonlabel1=Okay&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true" downloadfail="client:ShowAlert?message=HackTV%20Update%20failed...&buttonlabel1=Okay...&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true">
<title>Retrieving Files</title> <title>Retrieving Files</title>

View File

@@ -1,16 +0,0 @@
200 OK
Connection: Keep-Alive
wtv-expire-all: wtv-home:/splash
Content-type: text/html
<html>
<head>
<DISPLAY showwhencomplete noscroll>
</head>
<body bgcolor="black" link="gold" vlink="gold" alink="gold" text="gold">
<a href="htv-update:/update">Check for HackTV Updates</a><br>
<a href="wtv-home:/unlock">Unlock Full Client (Options, Goto, etc)</a><br>
<a href="wtv-home:/splash">Splash test</a>
</body>
</html>

View File

@@ -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;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -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='';

View File

@@ -1,10 +1,34 @@
var gourl = "wtv-1800:/offer-open-isp-suggest?"; var gourl = "wtv-1800:/finish-prereg?";
if (initial_headers['wtv-ticket']) { if (query['relogin']) gourl += "relogin=true";
gourl = "wtv-head-waiter:/login-stage-two?";
}
headers = `200 OK
if (query['reconnect']) {
headers = `200 OK
Connection: Keep-Alive Connection: Keep-Alive
wtv-open-isp-disabled: false wtv-expire-all: wtv-
wtv-visit: wtv-1800:/offer-open-isp-suggest? 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`; 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: `+ gourl + `
Content-type: text/html`;
}

View File

@@ -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);

View File

@@ -18,6 +18,7 @@ Connection: Keep-Alive
wtv-encrypted: true wtv-encrypted: true
wtv-ticket: `+sec_session[socket_session_data[socket.id].ssid].ticket_b64+` wtv-ticket: `+sec_session[socket_session_data[socket.id].ssid].ticket_b64+`
wtv-expire-all: htv- wtv-expire-all: htv-
wtv-home-url: wtv-home:/home?
wtv-visit: wtv-home:/splash? wtv-visit: wtv-home:/splash?
Content-Type: text/html Content-Type: text/html
`; `;

View File

@@ -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).substring(0,85) == client_challenge_response.substring(0,85)) {
if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) { if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) {
console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid); 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(); sec_session[socket_session_data[socket.id].ssid].PrepareTicket();
//socket_session_data[socket.id].secure = true; //socket_session_data[socket.id].secure = true;
} else { } 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"; gourl = "wtv-head-waiter:/login?reissue_challenge=true";
} }
} else { } else {
@@ -31,55 +32,55 @@ if (socket_session_data[socket.id].ssid !== null) {
} }
if (gourl) { if (gourl) {
headers = `200 OK headers = `200 OK
Connection: Keep-Alive Connection: Keep-Alive
wtv-open-isp-disabled: false wtv-open-isp-disabled: false
wtv-visit: `+gourl+` wtv-visit: `+ gourl + `
Content-type: text/html`; Content-type: text/html`;
data = ''; 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("<user-list>\n\t<user userid=\"" + userid + " user-name=\"" + nickname + "\" first-name=\"HackTV\" last-name=\"User \"" + namerand + "\" password=\"\" mail-enabled=\"true\" />\n</user-list>").toString(CryptoJS.enc.Base64);
headers = `200 OK headers = `200 OK
Connection: Keep-Alive Connection: Keep-Alive
wtv-encrypted: true wtv-encrypted: true
wtv-ticket: `+sec_session[socket_session_data[socket.id].ssid].ticket_b64+`
wtv-client-time-zone: GMT -0000 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-country: US
wtv-language-header: en-US,en wtv-language-header: en-US,en
wtv-tv-zipcode: 90210
wtv-visit: client:closeallpanels wtv-visit: client:closeallpanels
wtv-messagewatch-checktimeoffset: off
wtv-expire-all: client:closeallpanels 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-input-timeout: 14400
wtv-connection-timeout: 90 wtv-connection-timeout: 90
wtv-fader-timeout: 900 wtv-fader-timeout: 900
wtv-ssl-log-url: wtv-log:/log wtv-ssl-log-url: wtv-log:/log
wtv-smartcard-inserted-message: Contacting service wtv-smartcard-inserted-message: Contacting service
user-id: 1`+Math.floor(Math.random() * 1000000000000000000)+` user-id: `+userid+`
wtv-transition-override: off wtv-transition-override: off
wtv-bypass-proxy: true
wtv-allow-dsc: true wtv-allow-dsc: true
wtv-messenger-enable: 0 wtv-messenger-enable: 0
wtv-noback-all: wtv- wtv-noback-all: wtv-
wtv-service: reset wtv-service: reset
wtv-service: name=wtv-1800 host=` + pubip + ` port=` + port + ` connections=1 `+ getServiceString('all') + `
wtv-service: name=wtv-head-waiter host=` + pubip + ` port=` + port + ` flags=0x04 flags=0x00000001 connections=1 wtv-boot-url: wtv-1800:/preregister?relogin=true
wtv-service: name=htv-update host=` + pubip + ` port=` + port + ` connections=3 wtv-user-name: `+ nickname + `
wtv-service: name=wtv-log host=` + pubip + ` port=` + port + ` connections=1 wtv-human-name: `+ nickname + `
wtv-service: name=wtv-home host=` + pubip + ` port=` + port + ` flags=0x00000010 wtv-irc-nick: `+ nickname + `
wtv-boot-url: wtv-1800:/preregister wtv-home-url: wtv-home:/home?
wtv-user-name: `+nickname+`
wtv-human-name: `+nickname+`
wtv-irc-nick: `+nickname+`
wtv-home-url: htv-update:/update?
wtv-domain: wtv.zefie.com wtv-domain: wtv.zefie.com
wtv-inactive-timeout: 0 wtv-inactive-timeout: 0
wtv-connection-timeout: 90 wtv-connection-timeout: 90
wtv-show-time-enabled: true wtv-show-time-enabled: true
wtv-fader-timeout: 900 wtv-fader-timeout: 900
wtv-tourist-enabled: true wtv-tourist-enabled: true
wtv-boot-url: wtv-head-waiter:/login
wtv-connection-timeout: 180 wtv-connection-timeout: 180
wtv-ssl-timeout: 240 wtv-ssl-timeout: 240
wtv-login-timeout: 7200 wtv-login-timeout: 7200
@@ -87,9 +88,7 @@ wtv-open-isp-disabled: false
wtv-log-url: wtv-log:/log wtv-log-url: wtv-log:/log
wtv-demo-mode: 0 wtv-demo-mode: 0
wtv-wink-deferrer-retries: 3 wtv-wink-deferrer-retries: 3
wtv-offline-mail-enable: true wtv-offline-mail-enable: false
wtv-visit: wtv-head-waiter:/finalize-security? wtv-visit: wtv-home:/splash?
Content-Type: text/html`; Content-Type: text/html`;
data = '';
} }

View File

@@ -6,7 +6,6 @@ if (socket_session_data[socket.id].ssid !== null) {
if (initial_headers['wtv-ticket'].length > 8) { 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].DecodeTicket(initial_headers['wtv-ticket']);
sec_session[socket_session_data[socket.id].ssid].ticket_b64 = 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 { } else {
@@ -16,7 +15,6 @@ 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).substring(0,85) == client_challenge_response.substring(0,85)) {
console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid); console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid);
sec_session[socket_session_data[socket.id].ssid].PrepareTicket(); sec_session[socket_session_data[socket.id].ssid].PrepareTicket();
//socket_session_data[socket.id].secure = true;
} else { } else {
challenge_header = "wtv-challenge: "+issueWTVChallenge(socket); challenge_header = "wtv-challenge: "+issueWTVChallenge(socket);
} }
@@ -26,6 +24,7 @@ if (socket_session_data[socket.id].ssid !== null) {
} }
} }
/*
if (initial_headers) { if (initial_headers) {
var cookiedata = {}; var cookiedata = {};
Object.keys(initial_headers).forEach(function (k) { Object.keys(initial_headers).forEach(function (k) {
@@ -41,14 +40,13 @@ if (initial_headers) {
break; break;
} }
}); });
cookie_dat[socket_session_data[socket.id].ssid] = CryptoJS.enc.Utf8.parse(JSON.stringify(cookiedata)).toString(CryptoJS.enc.Base64);
} }
*/
headers = `200 OK headers = `200 OK
Connection: Keep-Alive Connection: Keep-Alive
Expires: Wed, 09 Oct 1991 22:00:00 GMT Expires: Wed, 09 Oct 1991 22:00:00 GMT
wtv-expire-all: wtv-head-waiter: 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 wtv-log-url: wtv-log:/log
`+challenge_header+` `+challenge_header+`
wtv-relogin-url: wtv-1800:/preregister?relogin=true wtv-relogin-url: wtv-1800:/preregister?relogin=true

View File

@@ -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 = "<a href='client:showalert?message=Your%20WebTV%20Unit%20sent%20us%20a%20request%20for%20SECURE%20ON%2C%20but%20did%20not%20encrypt%20any%20data%2C%20nor%20will%20accept%20it.%20However%2C%20we%20send%20the%20wtv-encryption%20flag%20to%20roll%20with%20it%2C%20enabling%20%27psuedo-encryption%27.%20Nothing%20is%20encrypted%2C%20but%20the%20box%20trusts%20us.%20This%20will%20probably%20go%20away%20if%20you%20reload%20or%20change%20pages.&buttonaction1=client:donothing&buttonlabel1=Oh%2C%20okay...'>Psuedo-encrypted</a>";
} else {
var cryptstatus = ((socket_session_data[socket.id].secure === true) ? "Encrypted" : "Not Encrypted")
}
data =`<html>
<head>
<DISPLAY showwhencomplete noscroll>
</head>
<body bgcolor="black" link="gold" vlink="gold" alink="gold" text="gold">
<script>
function ax(a) {
document.open("text/url");
document.write(a);
document.close();
}
</script>
<h2>Encryption Status: `+cryptstatus+`</h2>`
if (socket_session_data[socket.id].secure) {
data += '<span size="-1">Encryption Key (Server): ' + sec_session[socket.id].session_key2.toString(CryptoJS.enc.Hex)+'<br>';
data += 'Encryption Key (Client): ' + sec_session[socket.id].session_key1.toString(CryptoJS.enc.Hex)+'</span><br><br>';
}
data += `<a href="javascript:ax('client:relog')" selected>client:relog (via text/url)</a><br>
<a href="client:relog">client:relog (direct)</a><br>
<a href="htv-update:/update">HackTV Updater Test</a><br>
<!-- <a href="wtv-home:/unlock">Unlock Full Client (Options, Goto, etc)</a><br> -->
</body>
</html>`

View File

@@ -8,7 +8,7 @@ Content-type: text/html
<display nooptions nostatus skipback clearback fontsize=medium> <display nooptions nostatus skipback clearback fontsize=medium>
<meta <meta
http-equiv=refresh http-equiv=refresh
content="5; url=htv-update:/updatemenu" content="5; url=wtv-home:/home?"
> >
</head> </head>

View File

@@ -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 = '';

View File

@@ -10,13 +10,30 @@ const mime = require('mime-types');
var WTVNetworkSecurity = require('./wtvsec.js'); var WTVNetworkSecurity = require('./wtvsec.js');
var zdebug = true; var zdebug = true;
var secure_mode = true;
var pubip = "192.168.11.8"; 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 sec_session = new Array();
var cookie_dat = new Array();
var socket_buffer = new Array(); var socket_buffer = new Array();
var socket_session_data = new Array(); var socket_session_data = new Array();
@@ -24,6 +41,19 @@ var overrides = new Array();
//overrides['initial_key'] = "CC5rWmRUE0o="; //overrides['initial_key'] = "CC5rWmRUE0o=";
//overrides['challenge'] = "0kjyqIYAu0ziFBbSERN6DGaZ6S0fT+DBUCtpHCJ4lpuM7CbXdAm+x83BIDoJYztd1Z+5KFZ7ghmb3LJCT/6mhWUYkqqKOyfPRW8ZIdbICK/CV+Kxm8EUjRXZSk/97tsmFpH3hcCJ7C2TBw+TX38uQQ=="; //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() { function getPublicIP() {
var options = { var options = {
host: 'www.planeptune.org', host: 'www.planeptune.org',
@@ -53,6 +83,7 @@ function getFile(path, deps = false) {
return null; return null;
} }
function issueWTVInitialKey(socket) { function issueWTVInitialKey(socket) {
if (overrides['initial_key']) { if (overrides['initial_key']) {
sec_session[socket_session_data[socket.id].ssid].initial_shared_key = CryptoJS.enc.Base64.parse(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) { if (request_is_direct_file) {
// file exists, read it and return it // 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); var contype = mime.lookup(path);
data = fs.readFileSync(path).buffer; data = fs.readFileSync(path).buffer;
headers = "200 OK\n" headers = "200 OK\n"
headers += "Content-Type: " + contype; headers += "Content-Type: " + contype;
} else if (fs.existsSync(path + ".txt")) { } else if (fs.existsSync(path + ".txt")) {
// raw text format, entire payload expected (headers and content) // 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(); var fdat = fs.readFileSync(path + ".txt").toString();
if (fdat.indexOf("\n\n") > 0) { if (fdat.indexOf("\n\n") > 0) {
var fdata = fdat.split("\n\n"); 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. // 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. // loaded script will have r/w access to any JavaScript vars this function does.
// any query args are in an array named 'query' // 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(); var fdat = fs.readFileSync(path + ".js").toString();
eval(fdat); eval(fdat);
} else if (fs.existsSync(path + ".html")) { } else if (fs.existsSync(path + ".html")) {
// Standard HTML with no headers, WTV Style // 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(); data = fs.readFileSync(path + ".html").toString();
headers = "200 OK\n" headers = "200 OK\n"
headers += "Content-Type: text/html" headers += "Content-Type: text/html"
@@ -216,10 +247,13 @@ function processURL(socket, initial_headers) {
if (initial_headers['encrypted'] || initial_headers['secure']) { if (initial_headers['encrypted'] || initial_headers['secure']) {
reqverb = "Encrypted " + reqverb; reqverb = "Encrypted " + reqverb;
} }
if (initial_headers['psuedo-encryption']) {
reqverb = "Psuedo-encrypted " + reqverb;
}
if (ssid != null) { 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 { } 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 // assume webtv since there is a :/ in the GET
var urlToPath = __dirname + "/ServiceVault/" + shortURL.split(':/')[0] + "/" + shortURL.split(':/')[1]; var urlToPath = __dirname + "/ServiceVault/" + shortURL.split(':/')[0] + "/" + shortURL.split(':/')[1];
@@ -276,6 +310,16 @@ function processURL(socket, initial_headers) {
header_obj = 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) // set wtv-encrypted and put it near the top of the headers (unknown if needed)
if (socket_session_data[socket.id].secure == true) { if (socket_session_data[socket.id].secure == true) {
var clen = null; var clen = null;
@@ -291,7 +335,7 @@ function processURL(socket, initial_headers) {
if (typeof (data) === 'string') { if (typeof (data) === 'string') {
data = CryptoJS.enc.Utf8.parse(data); 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; data = enc_data;
} }
} }
@@ -316,7 +360,7 @@ function processURL(socket, initial_headers) {
socket.write(toClient); socket.write(toClient);
} else if (typeof data == 'object') { } else if (typeof data == 'object') {
if (socket_session_data[socket.id].secure_headers == true) { 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))); socket.write(new Uint8Array(concatArrayBuffer(enc_headers, data)));
} else { } else {
socket.write(new Uint8Array(concatArrayBuffer(Buffer.from(headers + "\n"), data))); 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; 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" // 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 // 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 // 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. // we can better process it with the raw base64 data in processHeaders() below.
var test = /^([A-Za-z0-9\+\/\=\-\.\,\ \;\:\?\&\r\n\(\)\%\<\>\_]{8,})$/.test(string); var test = /^([A-Za-z0-9\+\/\=\-\.\,\ \;\:\?\&\r\n\(\)\%\<\>\_]{8,})$/.test(string);
if (verbose) {
if (zdebug) console.log("request is ascii: " + test); if (zdebug) console.log("request is ascii: " + test);
if (zdebug) console.log("request is SECURE ON: " + /^SECURE ON/.test(string)); if (zdebug) console.log("request is SECURE ON: " + /^SECURE ON/.test(string));
}
return test; return test;
} }
@@ -379,14 +425,12 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc
if (typeof data === "string") { if (typeof data === "string") {
if (data.length > 1) { if (data.length > 1) {
data = data.split("\r\n\r\n")[0]; data = data.split("\r\n\r\n")[0];
if (headersAreStandard(data)) { if (headersAreStandard(data, (!returnHeadersBeforeSecure && !encryptedRequest))) {
data.split('\n').forEach(function (d) { data.split('\n').forEach(function (d) {
if (d.length > 0) { if (d.length > 0) {
if (/^SECURE ON/.test(d)) { if (/^SECURE ON/.test(d)) {
secure_mode = true;
headers['secure'] = 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) { if (d.indexOf(":") > 0 && d.indexOf(":/") == -1) {
headers[d.split(':')[0]] = (d.split(':')[1]).replace("\r", ""); 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) { if (!encryptedRequest) {
// failed the headersAreStandard test, so we think this is a binary blob // failed the headersAreStandard test, so we think this is a binary blob
if (socket_session_data[socket.id].secure != true) { if (socket_session_data[socket.id].secure != true) {
// first time so reroll sessions // 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; socket_session_data[socket.id].secure = true;
} }
var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2)); var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2));
if (enc_data.sigBytes > 0) { 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 dec_data_text = dec_data.toString(CryptoJS.enc.Latin1);
var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true, true); var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true, true);
headers['encrypted'] = 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) { Object.keys(secure_headers).forEach(function (k, v) {
headers[k] = secure_headers[k]; 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) { if (headers['wtv-client-serial-number'] != null) {
socket_session_data[socket.id].ssid = headers['wtv-client-serial-number']; 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 (headers['wtv-incarnation'] != null) {
if (sec_session[socket_session_data[socket.id].ssid]) { if (sec_session[socket.id]) {
sec_session[socket_session_data[socket.id].ssid].set_incarnation(headers['wtv-incarnation']); 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 (headers['secure'] === true) {
if (!sec_session[socket_session_data[socket.id].ssid]) { if (!sec_session[socket.id]) {
sec_session[socket_session_data[socket.id].ssid] = new WTVNetworkSecurity(); console.log("Starting new WTVNetworkSecurity instance on socket", socket.id);
sec_session[socket_session_data[socket.id].ssid].DecodeTicket(headers['wtv-ticket']); sec_session[socket.id] = new WTVNetworkSecurity();
sec_session[socket_session_data[socket.id].ssid].ticket_b64 = headers['wtv-ticket']; sec_session[socket.id].DecodeTicket(headers['wtv-ticket']);
sec_session[socket_session_data[socket.id].ssid].SecureOn(); 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']) { if (!headers['request_url']) {
if (data_hex.indexOf("0d0a0d0a")) {
// \r\n\r\n
var header_length = data.length + 4; 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)); var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2));
if (enc_data.sigBytes > 0) { if (enc_data.sigBytes > 0) {
var dec_data = CryptoJS.lib.WordArray.create(sec_session[socket_session_data[socket.id].ssid].Decrypt(0,enc_data)) if (headersAreStandard(enc_data.toString(CryptoJS.enc.Latin1), (!returnHeadersBeforeSecure && !encryptedRequest))) {
//var dec_data_text = dec_data.toString(CryptoJS.enc.Latin1); // 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); var secure_headers = processHeaders(socket, dec_data.toString(CryptoJS.enc.Hex), true);
console.log("Encrypted Request (Decrypted):", secure_headers.toString(CryptoJS.enc.Latin1)); console.log("Encrypted Request (SECURE ON)", "on", socket.id);
Object.keys(secure_headers).forEach(function (k,v) { }
// Merge new headers into existing headers object
Object.keys(secure_headers).forEach(function (k, v) {
headers[k] = secure_headers[k]; headers[k] = secure_headers[k];
}); });
} }
@@ -466,11 +543,11 @@ function processHeaders(socket, data_hex, returnHeadersBeforeSecure = false, enc
return null; 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_session_data[socket.id] = [];
socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64') socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64')
socket.on('data', function (data_hex) { socket.on('data', function (data_hex) {
socket.setTimeout(300); socket.setTimeout(300);
if (socket_buffer[socket.id]) { if (socket_buffer[socket.id]) {
@@ -487,19 +564,57 @@ var server = net.createServer(function (socket) {
}); });
socket.on('error', (err, socket) => { socket.on('error', (err, socket) => {
console.log('client socket error:', err); console.log(" * Client disconnected unexpectedly");
}); });
socket.on('end', function () { socket.on('end', function () {
socket_buffer[socket.id] = null; console.log(" * Destroying old WTVNetworkSecurity instance on socket", socket.id);
secure_mode = false; delete socket_buffer[socket.id];
socket_session_data[socket.id] = null; 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'); console.log(" * Started server on ports " + initstring + "... Public IP is " + pubip);
process.stdout.write("Looking up public IP address... ");
//pubip = getPublicIP();
console.log(pubip + " ...");
console.log('Listening on port ' + port + ' for WebTV Units in Scriptless Mode');

View File

@@ -29,11 +29,40 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Content Include="app.js" /> <Content Include="app.js" />
<Content Include="services.json">
<SubType>Code</SubType>
</Content>
<Content Include="ServiceVault\htv-update\update.html" />
<Content Include="ServiceVault\wtv-home\home.js" />
<Content Include="ServiceVault\htv-update\updatesuccess.txt" />
<Content Include="ServiceVault\htv-update\upd\cSetup.html" />
<Content Include="ServiceVault\htv-update\upd\Games.html" />
<Content Include="ServiceVault\htv-update\upd\tricks.html" />
<Content Include="ServiceVault\htv-update\upd\update.txt" />
<Content Include="ServiceVault\htv-update\upd\updater.html" />
<Content Include="ServiceVault\wtv-1800\finish-prereg.js" />
<Content Include="ServiceVault\wtv-1800\preregister.js" />
<Content Include="ServiceVault\wtv-head-waiter\finalize-security.js" />
<Content Include="ServiceVault\wtv-head-waiter\login-stage-two.js" />
<Content Include="ServiceVault\wtv-head-waiter\login.js" />
<Content Include="ServiceVault\wtv-head-waiter\test.js" />
<Content Include="ServiceVault\wtv-home\splash.txt" />
<Content Include="ServiceVault\wtv-log\log.js" />
<Content Include="ServiceVault\wtv-log\phone-log.js" />
<Content Include="wtvsec.js"> <Content Include="wtvsec.js">
<SubType>Code</SubType> <SubType>Code</SubType>
</Content> </Content>
<Content Include="package.json" /> <Content Include="package.json" />
<Content Include="README.md" /> <Content Include="README.md" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="ServiceVault\" />
<Folder Include="ServiceVault\htv-update\" />
<Folder Include="ServiceVault\htv-update\upd\" />
<Folder Include="ServiceVault\wtv-1800\" />
<Folder Include="ServiceVault\wtv-head-waiter\" />
<Folder Include="ServiceVault\wtv-home\" />
<Folder Include="ServiceVault\wtv-log\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" /> <Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" />
</Project> </Project>

View File

@@ -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"
}
}
}

View File

@@ -3,6 +3,8 @@ const endianness = require('endianness');
var crypto = require('crypto'); var crypto = require('crypto');
class WTVNetworkSecurity { class WTVNetworkSecurity {
//initial_shared_key = CryptoJS.lib.WordArray.random(8);
initial_shared_key_b64 = "CC5rWmRUE0o=";
initial_shared_key = null; initial_shared_key = null;
current_shared_key = null; current_shared_key = null;
challenge_key = null; challenge_key = null;
@@ -19,15 +21,13 @@ class WTVNetworkSecurity {
zdebug = true; zdebug = true;
constructor(wtv_initial_key = CryptoJS.lib.WordArray.random(8), wtv_incarnation = 1) { constructor(wtv_incarnation = 1) {
var initial_key = wtv_initial_key;
this.zdebug = true; 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.incarnation = wtv_incarnation;
this.initial_shared_key = initial_key; this.current_shared_key = this.initial_shared_key;
this.current_shared_key = initial_key;
} else { } else {
throw ("Invalid initial key length"); throw ("Invalid initial key length");
} }