docs: record PS5 payload and Y2JB tests

This commit is contained in:
2026-10-02 20:14:53 +01:00
parent bb6b46969f
commit 38e68cf165
6 changed files with 662 additions and 6 deletions
+2
View File
@@ -16,6 +16,8 @@ Documentation:
- [PS5 setup, DNS, deployment, and troubleshooting](docs/PS5_SETUP.md)
- [Maintainer and agent handoff](docs/HANDOFF.md)
- [Y2JB / Relapse controlled test record](docs/Y2JB_TEST_2026-10-02.md)
- [External payload candidate evidence](docs/payload-evidence/README.md)
- [Repository instructions for coding agents](AGENTS.md)
## Clone and build
+120 -3
View File
@@ -1,6 +1,6 @@
# Maintainer and agent handoff
Last updated: 2026-10-01
Last updated: 2026-10-02
This file is the durable handoff for future sessions. Start work from this
repository rather than from the upstream Relapse Exploit checkout.
@@ -132,8 +132,32 @@ auto-loader because those optional payloads caused compatibility issues. The pag
now stops after starting the ELF loader; any additional reviewed ELF must be sent
externally to the PS5 on TCP port 9021.
## External payload candidate evidence
A controlled intake and startup smoke test was completed on 2026-10-02 for
kstuff-lite v1.11 and ShadowMountPlus 1.7beta3. Locally calculated SHA-256 digests
matched the digests published by GitHub's release API. The verified ELFs were sent
once from `net-utils01` to `192.168.40.14:9021`, in that order and separated by
more than two seconds. Both connected and returned successful startup output;
ShadowMountPlus identified firmware 13.20, installed its hooks, synchronized an
empty game library and bound its API only to `127.0.0.1:10101`. The temporary
server copies were removed, and no downloaded binary is stored in this repository.
The normalized, machine-readable evidence and the proposed payload-manager import
contract and test limitations are in
[`docs/payload-evidence/`](payload-evidence/README.md). The required order is
kstuff-lite first, followed by ShadowMountPlus only after kstuff startup has been
confirmed. Catalog entries remain disabled and non-favorite by default despite the
successful smoke test; user selection is separate from evidence.
## PS5 and DNS state
The PS5 now uses the static address:
```text
192.168.40.14
```
The local HTTP endpoint is available and verified at:
```text
@@ -148,11 +172,104 @@ accept the self-signed certificate warning in the User Guide.
The gateway intentionally provides no recursive DNS forwarding. Only
`manuals.playstation.net` resolves; all other names receive NXDOMAIN. This blocks
PSN and update resolution and keeps the setup independent of a public DNS operator.
The PS5 was identified as `192.168.10.26`; requests from `192.168.10.6` seen earlier
were from a different client.
The PS5 was previously identified as `192.168.10.26`; requests from
`192.168.10.6` seen at that time were from a different client. Those addresses
are historical and must not be used as the current payload destination.
The PS5 ELF loader listens on TCP port `9021` after a successful exploit run. On
2026-10-01, a connection-only probe from `net-utils01` to
`192.168.40.14:9021` succeeded after inter-VLAN access was enabled. The probe
used `nc -vz`, sent no ELF payload, and confirmed that a new TCP connection from
the server VLAN to the console VLAN was permitted. `netcat-openbsd` is installed
on `net-utils01` for this diagnostic. Keep the applicable network policy limited
to the required LAN source, destination and TCP port; never expose port `9021`
to the Internet.
The inter-VLAN firewall policy reported as configured is:
| Source | Destination | Protocol/port | Purpose/state |
| --- | --- | --- | --- |
| `net-utils01` (`192.168.20.30`) | PS5 (`192.168.40.14`) | TCP `9021` | payload manager to ELF loader; active |
| PS5 (`192.168.40.14`) | `net-utils01` (`192.168.20.30`) | TCP `80`, `443`, `8000`; UDP/TCP `53` | Relapse page, User Guide gateway and restricted DNS; active |
| PS5 (`192.168.40.14`) | `net-utils01` (`192.168.20.30`) | TCP `8001` | reserved for payload-manager phase 5; enable only during that phase |
| PS5 (`192.168.40.14`) | remaining `192.168.20.0/24` hosts | all | blocked |
| hosts other than `net-utils01` | PS5 (`192.168.40.14`) | TCP `9021` | blocked |
The specific allow rules must be evaluated before the broader deny rules. Keep
TCP `8001` disabled until phase 5 has a reviewed service that requires it. The
successful TCP `9021` probe independently verifies that particular allow path;
the complete firewall policy was not audited from this repository.
Full PS5 instructions and DNS options are in `docs/PS5_SETUP.md`.
### Y2JB controlled test (2026-10-02; kernel/loader startup verified)
The PS5 Pro is on firmware 13.20. Its separate offline test user is `PLAYER1`
(slot 2); ActRemoteLink activated that slot and enabled user/global Remote Play.
Fake sign-in was **not** executed: reviewed implementations also write base
registry state, so isolation from the existing personal account is unproven.
Remote Play pairing remains untested.
The local YouTube PKG metadata identifies `PPSA01652`, version `01.000.030`,
Content ID `JA0004-PPSA01652_00-YOUTUBESIEJA0000`, despite its filename saying EUR.
Y2JB 1.6 was initially placed under `PPSA01650`. A subsequent PSN/DNS dialog loop
persisted with both local restricted DNS and primary DNS `127.0.0.2`.
At that point neither the cause nor successful Y2JB launch had been established;
the later successful run is recorded in
[`docs/Y2JB_TEST_2026-10-02.md`](Y2JB_TEST_2026-10-02.md).
The approved directory correction placed the verified Y2JB 1.6 file at
`/user/download/PPSA01652/download0.dat` (336789504 bytes). Its source and complete
destination reread matched SHA-256
`946fb64427d340a1a302d260e0cc448b50fe15cfcff8ea167a0d33d3aa76f39d`.
An existing, different file was preserved on the PS5 as
`/user/download/PPSA01652/download0.dat.before-y2jb-20261002T150112Z`;
its reread SHA-256 is
`dc553ea85aab9da884316c0fe9bb222da3e8d384ddf2c1fd119779b11c8a79c1`.
The original `PPSA01650` copy remains untouched. Do not delete the backup without
approval. After a normal reboot the user's screenshot confirmed Y2JB 1.6,
firmware 13.20, Title ID PPSA01652, app version 01.000.030, popups disabled, and
Remote JS Loader listening at `192.168.40.14:50000`. This demonstrates working
userland startup without fake sign-in; the exact cause of the earlier loop is
not isolated because both directory and file contents differed.
After the user enabled a temporary net-utils01 → PS5 TCP 50000 exception,
`edisnord/relapse-y2jb` v1.0.0 `relapse.js` (261458 bytes, SHA-256
`f85129b861f43a19f6810be5182aecdcf82a25e59ee5fbcd0604e4a4e2a40d69`)
was sent once. Output identified 13.20 offsets, kernel privileges ready, kexp
return zero, restored eboot descriptors, both real pipe buffers restored with
10/10 writes verified, completed teardown and ELF loader on 9021. A subsequent
connection-only TCP 9021 probe succeeded. The JS temporary copy was removed.
This is a startup smoke test, not proof of long-term stability, safe app closure
on this firmware, Remote Play pairing or homebrew operation in this boot.
The payload leaves three kernel sysctl OIDs modified until reboot, including
`kern.smp.cpus` returning a kernel address instead of a CPU count. App-close safety
is asserted by the output but upstream measured it only on 12.60; do not present
that as independently verified on 13.20. Do not send another kernel exploit in
an already exploited session. Disable temporary TCP 50000 when not needed.
FTP used `ps5-payload-dev/ftpsrv` v0.21.1, SHA-256
`7d4b31c83eae4e056580482a3a074e1db25922efc74ac1e439473b45d71a5938`.
Active-mode tests failed with `550 Bad file descriptor`; passive mode succeeded.
Temporary pfSense exceptions from net-utils01 to PS5 are TCP 2121 and
49152–65535, restricted to those two IPs. FTP was terminated with KILL. Disable
these rules when the test is complete; TCP 31337 (ActRemoteLink) is also temporary.
The obsolete reverse active-FTP exception PS5 → net-utils01 TCP 20212 is not needed.
PKG Manager v1.4.1 runs in memory on PS5 TCP 8844, with Direct Install TCP 18842;
restart the reviewed payload after a PS5 reboot. Access through loopback SSH
forwards, with matching net-utils01 → PS5 firewall exceptions only. This does not
install or start the Y2JB autoloader. itsPLK autoloader v0.9.1 has no supported
kernel exploit for 13.20; v1.0.0-dev-794049f adds Relapse but remains experimental
and has not been installed in this test.
**Server memory constraint:** net-utils01 has about 1.9 GiB RAM and no swap;
`/tmp` is tmpfs. Staging approximately 622 MiB of Y2JB files there caused severe
memory pressure with SSH/HTTP stalls; removal restored SSH. Use a verified
disk-backed path instead (`/var/tmp` is currently on ext4 `/dev/sda1`, about 70 GiB
free). Check memory and mount type before future payload staging. Test downloads
must be removed explicitly after verification; do not clear service-owned tmp dirs.
## Common operations
Inspect the live service:
+39 -3
View File
@@ -20,6 +20,7 @@ Na rede onde este projeto foi inicialmente instalado:
- porta publicada: `8000`.
- DNS local: `192.168.20.30:53` (UDP e TCP);
- gateway do Guia: `192.168.20.30:80` e `192.168.20.30:443`.
- IP estático atual da PS5: `192.168.40.14`.
A porta 8080 do host já pertence ao UniFi e não deve ser reutilizada.
@@ -88,7 +89,8 @@ Editar a ligação ativa em:
Selecionar a rede, carregar em `Options` e abrir `Definições avançadas`:
- endereço IP: automático;
- endereço IP: manter a configuração estática existente (`192.168.40.14`) nesta
instalação; noutras redes, usar os parâmetros fornecidos pelo administrador;
- nome do host DHCP: não especificar;
- DNS: manual;
- MTU: automático;
@@ -167,7 +169,7 @@ Com um DNS que redirecione o manual:
3. abrir `Guia do Utilizador`;
4. confirmar que aparece a página Relapse esperada;
5. aceitar o aviso de certificado self-signed, se aparecer;
6. confirmar nos logs que o cliente `192.168.10.26` consultou o DNS e abriu o
6. confirmar nos logs que o cliente `192.168.40.14` consultou o DNS e abriu o
gateway;
7. confirmar que o destino final é `192.168.20.30:8000`.
@@ -209,6 +211,19 @@ uma mensagem genérica de conclusão prova que todas as etapas terminaram corret
Manter o carregamento de payloads limitado à LAN confiável. Nunca publicar a porta
9021 na Internet e não enviar um ELF que não tenha sido previamente revisto.
Na instalação atual, um teste de ligação sem payload confirmou o caminho
`192.168.20.30` (`net-utils01`) para `192.168.40.14:9021`. A regra entre VLANs
deve permanecer limitada a essa origem, destino, protocolo e porta.
As regras da instalação permitem ainda que a PS5 alcance apenas os serviços
necessários no `net-utils01`: TCP `80`, `443` e `8000`, e DNS UDP/TCP `53`. O
restante acesso da PS5 à rede `192.168.20.0/24` está bloqueado. Outros hosts não
podem alcançar o ELF loader da PS5 em TCP `9021`. As exceções específicas devem
ser avaliadas antes dos bloqueios gerais na firewall.
Está prevista uma exceção da PS5 para TCP `8001` no `net-utils01` apenas para a
fase 5 do payload manager. Manter essa exceção desativada até existir um serviço
revisto que precise efetivamente da porta.
## Operação no net-utils01
@@ -279,7 +294,19 @@ docker compose logs --tail=100 ps5-guide-gateway
Depois reiniciar completamente a consola para limpar resoluções antigas. Se não
existir qualquer consulta proveniente do IP da PS5, verificar regras entre as VLANs
`192.168.10.0/24` e `192.168.20.0/24`, incluindo UDP/TCP 53 e TCP 80/443/8000.
`192.168.40.0/24` e `192.168.20.0/24`, incluindo UDP/TCP 53 e TCP 80/443/8000.
Para testar apenas se o servidor consegue alcançar o ELF loader, sem enviar um
payload:
```sh
ssh net-utils01
nc -vz -w 5 192.168.40.14 9021
```
Executar o teste apenas quando a PS5 apresentar que o loader está à espera na
porta `9021`. Um timeout indica normalmente filtragem ou ausência de caminho; uma
ligação bem-sucedida confirma apenas a conectividade TCP, não valida um payload.
### O build falha nos hashes
@@ -307,3 +334,12 @@ Estas proteções não tornam os payloads seguros. Os dois binários incluídos
pré-compilados e executados no processo de obter acesso privilegiado à consola.
Manter a PS5 numa rede isolada, não usar a conta principal e conservar backups dos
dados.
## Evidência do teste Y2JB / Relapse
O teste controlado em PS5 Pro 13.20, incluindo versões e hashes, caminhos FTP,
regras temporárias, resultado e limitações, está em
[`Y2JB_TEST_2026-10-02.md`](Y2JB_TEST_2026-10-02.md). Em especial, o teste confirmou
o ELF loader na porta 9021, mas não comprovou estabilidade prolongada nem a
segurança ao fechar YouTube neste firmware. Reiniciar normalmente antes de
repetir a cadeia de exploit.
+161
View File
@@ -0,0 +1,161 @@
# Teste YouTube → Y2JB → Relapse (2026-10-02)
Resultado: Y2JB e Relapse completaram o arranque em PS5 Pro firmware 13.20; o
ELF loader na porta TCP 9021 ficou acessível. O teste não mede estabilidade
prolongada nem segurança ao fechar a app neste firmware.
## Ambiente
- PS5 Pro: `192.168.40.14`, firmware 13.20.
- Servidor: `net-utils01`, `192.168.20.30`.
- DNS normal: gateway local restritivo neste repositório.
- Conta de teste: `PLAYER1`, utilizador local slot 2, separada da conta PSN pessoal.
- Não houve alterações ao submódulo ou ao runtime Docker.
## Ativação offline
ActRemoteLink identificou o slot 2 como utilizador atual, com account ID zero,
tipo vazio e flags `0x10000`. Com autorização explícita, foi executado `SETID`
apenas no slot 2, com ID fictício, tipo `np`, flags `0x1002` e Remote Play
ativado para o utilizador e globalmente. Retornos de escrita e releitura foram
zero/sucesso. O ID não foi associado à conta PSN pessoal.
Não foi executado fake sign-in. A revisão do código mostrou escritas de estado
de registo base para além das chaves por slot; não ficou provado que o efeito
fosse isolado da conta principal. Y2JB arrancou sem fake sign-in. Remote Play
está habilitado no registo, mas não foi emparelhado nem testado. O agente de
controlo foi terminado com `QUIT`.
## PKG YouTube e localização do ficheiro
O PKG analisado em Linux foi
`YouTube.app.PPSA01652.version.EUR.01.000.030.pkg`. Strings de metadados
confirmaram:
```text
Title ID: PPSA01652
Content ID: JA0004-PPSA01652_00-YOUTUBESIEJA0000
ContentVersion: 01.000.030
```
Apesar de `EUR` no nome, o prefixo do Content ID é `JA`; não inferir a região
apenas pelo nome. O ecrã Informações da PS5 confirmou versão `1.000.030`. Não
foi feito hash do PKG instalado nem comprovada a sua proveniência Sony.
O Y2JB 1.6 foi primeiro colocado em `/user/download/PPSA01650/`, diretório
incorreto para este Title ID. Surgiu um loop de avisos PSN/DNS (`NW-102312-9`).
Trocar temporariamente o DNS primário para `127.0.0.2`, sem secundário, mudou
o erro para `NW-102249-8`, mas o loop permaneceu. O DNS local foi reposto; a
consola nunca foi ligada à PSN para este diagnóstico.
Depois de confirmar o suporte a Title IDs regionais no autoloader upstream,
foi corrigido para `/user/download/PPSA01652/download0.dat`. Esse diretório
já continha um ficheiro diferente; foi preservado antes da cópia:
```text
/user/download/PPSA01652/download0.dat.before-y2jb-20261002T150112Z
SHA-256: dc553ea85aab9da884316c0fe9bb222da3e8d384ddf2c1fd119779b11c8a79c1
```
O ficheiro final tinha 336789504 bytes. A cópia de origem e a releitura FTP
no destino coincidiram com SHA-256
`946fb64427d340a1a302d260e0cc448b50fe15cfcff8ea167a0d33d3aa76f39d`.
O ficheiro em PPSA01650 ficou intacto. Não apagar a cópia de segurança sem
autorização. Como o caminho e o ficheiro anterior diferiam, não foi isolado
qual alteração resolveu o loop.
Depois de reinício normal, sem executar o exploit do Manual no mesmo boot,
YouTube mostrou Y2JB 1.6, FW 13.20, Title ID PPSA01652, AppVer 01.000.030,
popups desativados e Remote JS Loader em `192.168.40.14:50000`.
## Relapse
Release edisnord v1.0.0, asset `relapse.js`, 261458 bytes, SHA-256
`f85129b861f43a19f6810be5182aecdcf82a25e59ee5fbcd0604e4a4e2a40d69`.
O digest correspondeu ao publicado na release. O binário/script foi enviado
uma vez à porta 50000, depois de confirmada a ligação. Uma sondagem TCP anterior
sem conteúdo gerou `No valid data received`, esperado para uma ligação vazia.
Saída do teste confirmou offsets FW 13.20, self-test de workers, kernel
read/write, privilégios prontos, kexp de 18912 bytes com retorno zero,
descritores eboot restaurados e ambos os buffers reais dos pipes restaurados
com 10/10 escritas verificadas. O teardown terminou, apareceu `relapse complete`
e o ELF loader ficou à escuta na 9021. Uma sondagem TCP posterior à porta 9021
teve sucesso. O utilizador enviou foto que confirma `Executed successfully` e
`Awaiting connection` na porta JS.
O payload deixa OIDs de sysctl alterados até reboot; `kern.smp.cpus` devolve um
endereço de kernel em vez do número de CPUs. O texto do payload indica que a app
pode fechar com os pipes restaurados, mas essa segurança foi medida upstream em
12.60, não nesta consola 13.20. Não houve teste de estabilidade prolongada,
fecho da app, Remote Play ou homebrew neste boot. Não executar outro exploit de
kernel nesta sessão. Reiniciar normalmente antes de repetir o teste.
## Artefactos verificados
| Ficheiro | Origem/versão | SHA-256 |
| --- | --- | --- |
| `actremotelink_agent.elf` | commit `e61a46eed4832ae563b65810685401ddadee2f9b` | `201ba90445e1ca1210237318f106724de238a2c629e16a0f190096319d263c4f` |
| `pkg-manager_v1.4.1.elf` | itsPLK v1.4.1 | `09adaff13b858bb3db519faaea673ee3fa67298081e608d32f6501ed6e9f706e` |
| `ftpsrv-ps5.elf` | v0.21.1 | `7d4b31c83eae4e056580482a3a074e1db25922efc74ac1e439473b45d71a5938` |
| `Y2JB_download0_1.6.zip` | Gezine 1.6 | `d032954033c17acda47c41179a22fa09016ddd40a274f4e9afbb051e5d08d3bd` |
| `download0.dat` | extraído do ZIP | `946fb64427d340a1a302d260e0cc448b50fe15cfcff8ea167a0d33d3aa76f39d` |
| `relapse.js` | edisnord v1.0.0 | `f85129b861f43a19f6810be5182aecdcf82a25e59ee5fbcd0604e4a4e2a40d69` |
Hash confirma identidade/integridade face à fonte indicada, não segurança
intrínseca. Não foi provado build reproduzível do agente nem reconstruído o JS
byte a byte nesta sessão.
## Rede e FTP
Regras foram limitadas a origem/destino nas VLANs, sem NAT, acima dos bloqueios:
| Origem → destino | TCP | Finalidade |
| --- | --- | --- |
| net-utils01 → PS5 | 9021 | ELF loader, regra habitual |
| net-utils01 → PS5 | 31337 | ActRemoteLink temporário, sem autenticação |
| net-utils01 → PS5 | 2121 | controlo FTP temporário |
| net-utils01 → PS5 | 49152–65535 | dados FTP passivos temporários |
| PS5 → net-utils01 | 20212 | tentativa FTP ativo; obsoleta |
| net-utils01 → PS5 | 50000 | loader JavaScript deste arranque |
| net-utils01 → PS5 | 8844, 18842 | PKG Manager e Direct Install |
ftpsrv v0.21.1 em modo ativo aceitou `PORT`, mas falhou com `550 Bad file
descriptor`; revisão do código encontrou socket fechado antes de connect.
Modo passivo foi funcional e cada porta anunciada foi validada no intervalo
aberto. FTP foi encerrado com `KILL`. Desativar regras temporárias 31337, 2121,
49152–65535, 20212 e 50000 quando já não necessárias; o estado final do pfSense
não foi verificado remotamente.
## Memória do net-utils01
O host tem aproximadamente 1.9 GiB RAM, sem swap; `/tmp` é tmpfs. Guardar ZIP
mais ficheiro extraído (cerca de 622 MiB) causou pressão severa de memória,
SSH sem banner e HTTP sem resposta. PSI `memory full` chegou a ~54%. Apagar os
dois downloads recuperou SSH. Não foi observado OOM kill confirmado.
Os testes seguintes usaram `/var/tmp`, verificado em ext4 `/dev/sda1`, com ~70
GiB disponíveis. Antes de staging grande, verificar:
```sh
findmnt -T /var/tmp
df -h /var/tmp
free -h
```
Não limpar `/tmp` indiscriminadamente: diretórios privados de serviços systemd
foram preservados. Os ficheiros exatos dos testes foram removidos após uso.
## Pendentes
- Fecho controlado do YouTube em FW 13.20 e confirmação de que 9021 persiste.
- Teste homebrew neste boot; evidências anteriores de kstuff-lite/ShadowMount+
estão em [payload-evidence](payload-evidence/README.md).
- Teste Remote Play, após rever uma forma de fake sign-in que não afete slot 1.
- Autoloader itsPLK v0.9.1 não tem kernel exploit para 13.20. v1.0.0-dev
integra Relapse 10.20–13.60 mas é experimental, não instalado; rever hash,
cadeia automática e elfldr loopback-only antes de o testar.
- PKG Manager corre em memória (8844 UI, 18842 Direct Install) e precisa de
reenvio depois de reboot. A UI respondeu HTTP 200 antes do reboot deste teste.
Este registo é documental; não exigiu rebuild nem deployment do runtime Docker.
+128
View File
@@ -0,0 +1,128 @@
# Payload candidate evidence: kstuff-lite and ShadowMountPlus
Evidence date: 2026-10-02
This directory records a controlled intake and startup smoke test of two payload
candidates on a PS5 running firmware 13.20. The verified payloads were sent once,
in dependency order, from `net-utils01` to the console's ELF loader. No downloaded
binary is stored in this repository or left in the server's temporary directory.
The machine-readable handoff for a future payload-manager repository is
[`manifest-2026-10-02.v1.json`](manifest-2026-10-02.v1.json). It deliberately
imports both candidates as disabled and not favorited. Runtime success does not
implicitly enable a catalog entry. User state such as
active/inactive and favorite must be stored separately from source evidence.
## Selected releases
| Payload | Release and commit | Release asset | Size | SHA-256 |
| --- | --- | --- | ---: | --- |
| kstuff-lite | `v1.11`, `85fb88a526e58e357d6f1e626ce05af4acdb8b5d` | `kstuff.elf` | 1,737,080 | `ab9a6cb4d3b1daf139d4d646e402b1cf569071acd64599c936d7a3a6164dc779` |
| ShadowMountPlus | `1.7beta3`, `f0d15ffc46e9237d41cc3555b1cf11362d9a32e0` | `shadowmountplus.elf` | 2,437,848 | `2a7427e20ba7a70bd8cd01e47eb00ee7ca82db82dff3da7884f48f9c3fcbe95a` |
| ShadowMountPlus support bundle | `1.7beta3`, same commit | `ShadowMountPlus_1.7beta3.zip` | 1,352,255 | `2fb8edd89f2390a4a6a7b568ed9c5f34db01705781e0f3f386beb6612d29b6aa` |
The files were downloaded from the release URLs recorded in the manifest. Each
locally calculated digest matched the SHA-256 digest returned by GitHub's release
API. The ELF inside the ShadowMountPlus ZIP was also byte-for-byte identical to
the separately published `shadowmountplus.elf`.
## Static findings
Both payloads are stripped, dynamically linked, position-independent ELF64 x86-64
executables. Static inspection alone cannot establish that a privileged payload is
safe.
The kstuff-lite v1.11 release states support for firmware 1.00 through 13.60, which
includes the target firmware 13.20. ShadowMountPlus documents kstuff-lite v1.07 or
newer as a dependency, so the intended order is kstuff-lite first and
ShadowMountPlus second.
ShadowMountPlus contains HTTP, HTTPS and networking support. Its supplied default
configuration enables an HTTP API only on loopback `127.0.0.1:10101`; automatic
AMPR downloading is disabled; mounts are read-only; forced mounts and persistent
mounts are disabled. Do not change the API bind address to `0.0.0.0` without a
separate firewall and threat review. Upstream also warns that mounting images can
cause shutdown problems and data corruption.
## Provenance limitations
- GitHub release digests demonstrate that the downloaded bytes match the assets
currently registered by GitHub. They do not prove benign behavior.
- Neither release provides a detached signature, SBOM, or build attestation for
the ELF. Both referenced source commits are unsigned.
- kstuff-lite's CI downloads a toolchain through a mutable `releases/latest` URL.
- ShadowMountPlus's workflow checks out build dependencies without immutable
commit pins.
- This review did not reproduce either ELF from source. The relationship between
each binary and its source commit is therefore asserted by the publisher, not
independently proven by a reproducible build.
- A tag and its release assets can be moved or replaced upstream. The payload
manager must treat the recorded SHA-256 and size as authoritative and reject any
mismatch instead of silently accepting replacement bytes.
## Runtime smoke-test evidence
At `2026-10-02T12:42:02Z`, the two hash-verified ELFs were sent sequentially from
`net-utils01` (`192.168.20.30`) to the PS5 (`192.168.40.14`) over TCP 9021. The
Relapse page had already reached `elfldr is listening on port 9021`; no R2 action
was involved.
The observed sequence was:
1. `kstuff.elf` v1.11 connected successfully. Its output reported `app.db`
patching and a successful SceShellUI trophy `IsServerAvailable` patch.
2. After more than two seconds, `shadowmountplus.elf` 1.7beta3 connected
successfully. It detected firmware 13.20, reported kstuff runtime control ready,
installed its SceShellCore hooks, started the game lifecycle watcher, synchronized
the library with zero games found and started its API on loopback
`127.0.0.1:10101`.
The effective first-run defaults kept mounts read-only, forced and persistent
mounting disabled, automatic AMPR downloads disabled, and the API unavailable to
the LAN. The temporary copies of both ELFs were removed from `net-utils01` after
the send.
This is a startup smoke test only. No image was mounted, and suspend/resume,
shutdown, reboot, API actions, gameplay stability and automatic kstuff
pause/resume were not tested.
## Payload-manager import contract
The manager should:
1. import the versioned JSON manifest without executing or downloading anything;
2. keep catalog evidence separate from per-user `enabled` and `favorite` state;
3. fetch an artifact only on explicit request into a quarantine/cache directory;
4. require the exact byte size and SHA-256 before moving it into the usable cache;
5. reject redirects that end outside the expected GitHub release infrastructure,
or at minimum record and display the final origin;
6. never resolve a mutable `latest` URL for these pinned records;
7. enforce dependency and load order: kstuff-lite, confirmation, then
ShadowMountPlus;
8. record every send attempt with payload ID, version, digest, target, timestamp,
result and operator identity, without storing credentials in the log.
Release discovery may propose newer versions, but it must create a new candidate
record and require review. It must never overwrite the evidence for an already
approved digest.
## Controlled runtime-test procedure
The current Relapse flow ends at `elfldr is listening on port 9021`; there is no R2
step. Use the following procedure for a repeat test only after explicit operator
approval:
1. confirm the PS5 is on firmware 13.20 and the ELF loader is visibly listening;
2. confirm the sender-to-PS5 firewall rule is limited to TCP 9021 on the LAN;
3. re-download and verify `kstuff.elf` against the recorded size and SHA-256;
4. send only kstuff-lite and record the console result before doing anything else;
5. confirm how the loader accepts the second payload and re-establish it if needed;
6. re-download and verify `shadowmountplus.elf`, then send it separately;
7. verify the on-console notification and `/data/shadowmount/debug.log`;
8. leave the API loopback-only and automatic downloads disabled for the first test;
9. avoid suspend, forced shutdown and writable mounts until the basic lifecycle has
been observed successfully.
A TCP connection probe is not a payload test. Do not infer runtime success from an
open port. Keep each execution as an independent runtime record rather than
overwriting this evidence.
@@ -0,0 +1,212 @@
{
"schema_version": 1,
"evidence_id": "ps5-13.20-kstuff-shadowmountplus-2026-10-02",
"generated_at": "2026-10-02T12:36:21Z",
"updated_at": "2026-10-02T12:42:02Z",
"scope": {
"target_platform": "PlayStation 5",
"target_firmware": "13.20",
"collection_mode": "official-release-download-and-static-inspection",
"executed_on_console": true,
"binaries_stored_in_repository": false
},
"import_policy": {
"download_on_demand": true,
"require_exact_size": true,
"require_sha256_before_use": true,
"reject_digest_mismatch": true,
"allow_latest_urls": false,
"default_enabled": false,
"default_favorite": false
},
"loader": {
"transport": "tcp",
"port": 9021,
"precondition": "elfldr is listening on port 9021",
"requires_r2": false
},
"payloads": [
{
"id": "kstuff-lite",
"display_name": "kstuff-lite",
"candidate_status": "integrity-verified-runtime-smoke-tested",
"recommended_load_order": 10,
"release": {
"repository": "https://github.com/EchoStretch/kstuff-lite",
"release_url": "https://github.com/EchoStretch/kstuff-lite/releases/tag/v1.11",
"github_release_id": 392541028,
"name": "Kstuff Lite 1.11 Beta",
"tag": "v1.11",
"commit": "85fb88a526e58e357d6f1e626ce05af4acdb8b5d",
"published_at": "2026-09-20T19:08:36Z",
"github_prerelease": false,
"source_commit_signature_verified": false
},
"compatibility": {
"firmware_min": "1.00",
"firmware_max": "13.60",
"target_firmware_in_range": true,
"basis": "Upstream v1.11 release notes"
},
"dependencies": [],
"artifacts": [
{
"role": "payload",
"filename": "kstuff.elf",
"url": "https://github.com/EchoStretch/kstuff-lite/releases/download/v1.11/kstuff.elf",
"github_asset_id": 584760938,
"uploader": "EchoStretch",
"size": 1737080,
"sha256": "ab9a6cb4d3b1daf139d4d646e402b1cf569071acd64599c936d7a3a6164dc779",
"github_digest_matches_local": true,
"media_type": "application/octet-stream",
"format": "ELF64 LSB x86-64 PIE, dynamically linked, stripped"
}
],
"source_snapshot": {
"url": "https://github.com/EchoStretch/kstuff-lite/archive/85fb88a526e58e357d6f1e626ce05af4acdb8b5d.tar.gz",
"sha256_observed": "67aee7b843809810346db823b684184b1b7e06ffdf3946315cf98202fd6bf601"
},
"provenance_limits": [
"No detached release signature, SBOM, or build attestation was published with the ELF.",
"The release commit is unsigned.",
"The CI downloads a mutable toolchain URL ending in /releases/latest/.",
"A source-to-binary reproducible build was not established."
]
},
{
"id": "shadowmountplus",
"display_name": "ShadowMountPlus",
"candidate_status": "integrity-verified-runtime-smoke-tested",
"recommended_load_order": 20,
"release": {
"repository": "https://github.com/drakmor/ShadowMountPlus",
"release_url": "https://github.com/drakmor/ShadowMountPlus/releases/tag/1.7beta3",
"github_release_id": 400997880,
"name": "ShadowMountPlus 1.7beta3",
"tag": "1.7beta3",
"commit": "f0d15ffc46e9237d41cc3555b1cf11362d9a32e0",
"published_at": "2026-10-01T13:31:26Z",
"github_prerelease": true,
"source_commit_signature_verified": false
},
"compatibility": {
"target_firmware": "13.20",
"target_firmware_explicitly_tested_by_this_review": false,
"basis": "Upstream documents compatibility with jailbroken firmware running kstuff-lite v1.07 or newer."
},
"dependencies": [
{
"payload_id": "kstuff-lite",
"version_constraint": ">=1.07",
"load_before": true
}
],
"artifacts": [
{
"role": "payload",
"filename": "shadowmountplus.elf",
"url": "https://github.com/drakmor/ShadowMountPlus/releases/download/1.7beta3/shadowmountplus.elf",
"github_asset_id": 603338532,
"uploader": "drakmor",
"size": 2437848,
"sha256": "2a7427e20ba7a70bd8cd01e47eb00ee7ca82db82dff3da7884f48f9c3fcbe95a",
"github_digest_matches_local": true,
"media_type": "application/octet-stream",
"format": "ELF64 LSB x86-64 PIE, dynamically linked, stripped"
},
{
"role": "supporting-release-bundle",
"filename": "ShadowMountPlus_1.7beta3.zip",
"url": "https://github.com/drakmor/ShadowMountPlus/releases/download/1.7beta3/ShadowMountPlus_1.7beta3.zip",
"github_asset_id": 603337105,
"uploader": "github-actions[bot]",
"size": 1352255,
"sha256": "2fb8edd89f2390a4a6a7b568ed9c5f34db01705781e0f3f386beb6612d29b6aa",
"github_digest_matches_local": true,
"embedded_payload_matches_standalone": true,
"media_type": "application/zip"
}
],
"source_snapshot": {
"url": "https://github.com/drakmor/ShadowMountPlus/archive/f0d15ffc46e9237d41cc3555b1cf11362d9a32e0.tar.gz",
"sha256_observed": "ece93cdad2f56629addc40ae8a101c18b4e6cf04756fd45210e3ebda65bdff5a"
},
"runtime_defaults_observed": {
"api_enabled": true,
"api_bind_address": "127.0.0.1",
"api_port": 10101,
"automatic_ampr_download": false,
"mount_read_only": true,
"force_mount": false,
"persistent_image_mounts": false
},
"provenance_limits": [
"No detached release signature, SBOM, or build attestation was published with the assets.",
"The release commit is unsigned.",
"The build workflow checks out toolchain and SDK repositories without immutable commit pins.",
"A source-to-binary reproducible build was not established."
]
}
],
"runtime_test": {
"test_id": "ps5-13.20-sequential-load-2026-10-02",
"performed_at": "2026-10-02T12:42:02Z",
"result": "successful-smoke-test",
"sender": {
"host": "net-utils01",
"source_ip": "192.168.20.30",
"tool": "netcat-openbsd"
},
"target": {
"ip": "192.168.40.14",
"firmware": "13.20",
"transport": "tcp",
"port": 9021
},
"sequence": [
{
"order": 1,
"payload_id": "kstuff-lite",
"sha256": "ab9a6cb4d3b1daf139d4d646e402b1cf569071acd64599c936d7a3a6164dc779",
"connection_succeeded": true,
"observed": [
"app.db patching started",
"SceShellUI trophy IsServerAvailable patch reported successful"
]
},
{
"order": 2,
"payload_id": "shadowmountplus",
"sha256": "2a7427e20ba7a70bd8cd01e47eb00ee7ca82db82dff3da7884f48f9c3fcbe95a",
"minimum_delay_after_previous_seconds": 2,
"connection_succeeded": true,
"observed": [
"Detected firmware 13.20",
"kstuff runtime control ready",
"SceShellCore hooks installed",
"game lifecycle watcher started",
"library synchronized with zero games found",
"HTTP/JSON API ready on loopback 127.0.0.1:10101"
]
}
],
"effective_safety_defaults": {
"api_network_exposure": false,
"automatic_ampr_download": false,
"mount_read_only": true,
"force_mount": false,
"persistent_image_mounts": false
},
"cleanup": {
"temporary_server_binaries_removed": true,
"removed_at": "2026-10-02T12:42:02Z"
},
"limitations": [
"This was one startup smoke test, not a long-duration stability test.",
"No game or image was mounted.",
"Suspend, resume, shutdown, reboot, API operations and kstuff pause/resume were not tested.",
"Runtime success does not resolve the documented source-to-binary provenance limitations."
]
}
}