Security notes
Three things matter before you put this disc in a console: what the applet is permitted to ask for, the remote-control code that is physically inside the image, and what I changed when republishing it.
Summary
The faithful image contains a remote-control implementation. It is present in the bytecode and I did not remove it. In this build that code has no reachable call path, on four independent pieces of static evidence. No phone-home occurs, because the route to it does not exist in these bytes. All of that is static analysis of the file itself, which is the only honest way to answer a question about what these bytes contain.
What the applet may ask for
The signed JAR carries its BD-J permission request in the clear, readable with unzip -p 00000.jar org/bdj/bluray.InitXlet.perm:
<permissionrequestfile orgid="0x56789abc" appid="0x4000">
<applifecyclecontrol value="true"/>
<bd-bindingunitarea value="true"/>
<bd-vfs value="true"/>
<file value="true"/>
<servicesel value="true"/>
<userpreferences read="true" write="true"/>
</permissionrequestfile>
That is control of its own lifecycle, the disc filesystem and BD-J VFS, read and write on user preferences, and service selection. The orgid matches the self-signing identity O=BDJCompany.56789abc. Nothing network-related is requested here.
The privilege escalation does not come from these permissions. It comes from the kernel stage, which is why the safety page is the one that matters most.
The dormant remote-control code
Present in org.bdj.Boot (14,533 bytes) and org.bdj.Cfg (429 bytes):
| Element | Function |
|---|---|
Boot.run() | Handshake, then poll up to 100,000 times and execute whatever commands arrive |
Boot.io(String, byte[]) | HTTP POST to http://tester.f5rvoice.com:1992 with an X-Ticket header |
ticket, xor, ksq, mix, hex16, hexb | Obfuscation and ticket construction helpers |
Cfg.SERVER, PORT, CID, CKEY, BUILD | The remote configuration those routines read |
CKB, KSB | Key material slots |
The transport is plaintext HTTP with no certificate or host pinning. Whoever controlled that host would be feeding commands to a kernel-level interpreter, which is why I am documenting it rather than burying it.
Four reasons it is unreachable here
- No caller. Across all 24 classes there are zero direct method references to
org/bdj/Boot.run:()Ljava/lang/String;. The routine exists and nothing invokes it. - The one
runsite resolves a different class. Of the forty templates, exactly one,cmd-0043, resolves a method namedrun, and it does so throughcls(30).getMethod('run')where slot 30 is the class defined asHx1400. That template calls the kernel stage, notBoot.run(). - Offline configuration is baked in. In the local execution path
InitXletsetsBoot.EPto the disc's ownfile:root, withSID = "offline"andSK = null. The endpoint variable never points at HTTP. - Key material is zeroed by the disc. Templates
cmd-0029,cmd-0030andcmd-0031scrub theCKB,SKandKSBfields before the stage runs.
These are the checks recorded as Boot.run has zero callers (dormant) and templates resolve Hx1400.run, not Boot.run in reports/VERIFY_REPORT.json.
Dormant does not mean disabled forever
Dormant describes these bytes, not a guarantee about other bytes. Any of the following would re-enable it: setting Boot.EP back to an http:// value, adding a call path to Boot.run, removing or reordering the three scrub templates, or changing the schedule so slot 30 resolves Boot instead of Hx1400.
Because every asset is SHA-256 pinned, making such a change also requires re-signing the JAR, and the original key is not available. A re-signed disc therefore carries different digests and a different signature, which is exactly what you can check. If an image you are offered matches the digest on this site, my analysis describes it. If it does not match, my findings say nothing about it.
I will not publish a build that activates this code, and no such build exists here.
Defensive steps
- Block
tester.f5rvoice.comand TCP port1992at your firewall for the duration of an experiment. It should make no difference, and it costs nothing. - Keep the console offline unless you have decided otherwise.
- Only run images whose digest you have verified yourself. A same-size ISO is trivial to fake.
- Be suspicious of any clean, safe or no-telemetry variant of this disc that you did not check. Producing one requires re-signing, which changes every digest, so such a variant is a different program rather than this one with a switch flipped.
- Do not run this on a console you cannot afford to re-initialise.
What I changed
hen.iso is byte-for-byte the reference disc. hen-branded.iso differs from it in 469 bytes, all of them inside the 564-byte NOTICE.txt text extent at sector 448, and that change is a credit line. The UDF metadata, the signed JAR, the other 37 file extents and the total size are identical, and the verification page shows the commands that prove it. I added no class, no template, no schedule entry and no re-signing.
The source is closed, so you cannot audit a build pipeline. That is a real cost of this arrangement. What you can do is verify every byte-level claim on this page against the published files, which is what the verification page is for.