2025-08-28 18:55:12 +02:00

348 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Plex Premium Hack
This repository contains a "mock" proxy that sits in your network and tricks Plex into thinking you have a Plex Premium
subscription.
**This should be used for educational purposes only. I take no responsibility for any misuse of this hack.**
### Requirements
- A router that **can redirect traffic** (i.e. OPNsense, pfSense, DD-WRT...)
- _(alternative) a DNS server that can redirect traffic (some apps won't work due to DNS pinning)_
- A reverse proxy (i.e. Traefik, Nginx, Caddy...)
- A Plex server (self-hosted)
### What works?
- Plexamp mobile (download mode)
- Plexamp Headless
### What doesn't work?
- Plex server still sees you as a free user *(something to do with how the claim is done I believe, would have to MITM the server itself and see what transits during claiming)*
- See [here](https://gitgud.io/yuv420p10le/plexmediaserver_crack) ([mirror](https://git.broillet.ch/Clone/plexmediaserver_crack)) for a work-around (much easier if you want transcoding or server side features)
- Transcoding
- probably a lot
### Why?
I wanted to use Plexamp on my HiFi setup but I wasn't really interested in paying for a Plex subscription just for that.
This hack allows usage of Plexamp (mobile + headless) at home and maybe some other premium features (untested) without having to pay for a subscription.
## How to setup ?
Due to the nature of this hack, you'll have to :
- generate a new certificate authority (CA) for the proxy
- trust or patch the CA on clients and/or apps that will connect to your Plex server
### 1. Generate a new Certificate Authority (CA) and proxy certificate
```bash
# Generate a root CA
openssl genrsa -out plexhackCA.key 4096
# Create a self-signed root CA certificate
openssl req -x509 -new -nodes -key plexhackCA.key -sha256 -days 3650 -out plexhackCA.pem -subj "/C=US/ST=SomeState/L=SomeCity/O=PlexHack/OU=PlexHack/CN=PlexHackCA"
# Generate private key for proxy
openssl genrsa -out plexhackproxy.key 2048
# Create a config file for the proxy certificate (SANs)
cat > plexhacksan.cnf <<EOL
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = SomeState
L = SomeCity
O = PlexHack
OU = PlexHack
CN = plex.tv
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = plex.tv
DNS.2 = *.plex.tv
DNS.3 = *.provider.plex.tv
EOL
# Create a certificate signing request (CSR) using the SAN config
openssl req -new -key plexhackproxy.key -out plexhackproxy.csr -config plexhacksan.cnf
# Sign the CSR with your root CA to create the proxy certificate
openssl x509 -req -in plexhackproxy.csr -CA plexhackCA.pem -CAkey plexhackCA.key -CAcreateserial -out plexhackproxy.crt -days 365 -sha256 -extfile plexhacksan.cnf -extensions v3_req
```
Now you should have two files `plexhackproxy.crt` and `plexhackproxy.key` that you will use in your reverse proxy.
You should also have the `plexhackCA.crt` file that you will need to trust on your clients.
> [!IMPORTANT]
> You will need to trust the `plexhackCA.crt` certificate on every device that
> will connect to your Plex server (i.e. mobile, desktop, smart TV...).
> How to do this depends on the device and OS, you will need to search for instructions
> specific to your device.
### 2. Setup reverse proxy
In my case I'm using Traefik, so here is an example configuration :
```yaml
tls:
certificates:
# use certificates generated in step 1
- certFile: /etc/traefik/ssl/custom/plexhackproxy.crt
keyFile: /etc/traefik/ssl/custom/plexhackproxy.key
http:
routers:
plex:
entryPoints:
- https
service: plex
rule: Host(`plex.<your-domain>.com`)
# you may want to use TLS here too (don't use the custom CA cert generated in step 1)
plex_proxy:
entryPoints:
- https
service: plex_proxy
rule: HostRegexp(`^.+\.plex\.tv$`) || Host(`plex.tv`)
tls: { }
services:
plex:
loadBalancer:
servers:
- url: http://<plex-machine-ip>:32400
plex_proxy:
loadBalancer:
servers:
- url: http://<machine-where-proxy-is>:8000
```
### 3. Redirect traffic
For this to work we need to redirect the domain `clients.plex.tv` and `plex.tv` to our proxy.
This is easily done if you own a router that can do this but might be tricky if you don't.
> [!IMPORTANT]
> Mobile/desktop apps tends to use hardcoded DNS servers so if you don't have a router that can redirect traffic, you
> will not be able to use this hack.
> It might be possible to patch the app to use a custom DNS server but the apps are usually obfuscated and it's not easy
> to do so.
#### OPNsense / pfSense
First, find the IP address behind the plex domains.
```bash
dig clients.plex.tv +short
# 172.64.151.205
# 104.18.36.51
dig plex.tv +short
# 52.17.59.150
# 52.49.56.127
dig features.plex.tv +short
# global-latency.plex.bz. -> we can ignore this one it points to the 3 IPs below
# 34.246.123.195
# 52.210.35.163
# 54.216.30.15
```
Then go into `Firewall` > `Aliases` and create two aliases:
- `plex_ips`
- Type: Host(s)
- Content: <the IPs you found above>
- `plex_do_not_proxy`
- Type: Host(s)
- Content: <your plex server IP> and <your proxy server IP>
Then go into `Firewall` > `NAT` > `Port Forward` and create a new rule:
- Interface: `LAN`
- Protocol: `TCP`
- Source / Invert: [☑️]
- Source: *(select alias)* `plex_do_not_proxy`
- Source Port Range: `any`
- Destination: *(select alias)* `plex_ips`
- Destination Port Range: `443`
- Redirect Target IP: `<your proxy server IP>`
- Redirect Target Port: `443`
Finally go to `Firewall` > `NAT` > `Outbound` and create a new rule *(select Hybrid mode if needed)*:
- Interface: `LAN`
- TCP/IP Version: `IPv4`
- Protocol: `any`
- Source address: `any`
- Destination address: <your proxy server IP>
- Destination port : `443`
- Translation / target: `Interface address`
##### Test the redirection
Now if you try to go to `https://clients.plex.tv/proxy` you should see a JSON response along the lines of :
```json
{
"status": "OK, Plex Pass features proxy enabled"
}
```
If you see the Plex "Oops, 404" page then something is wrong with your redirection or proxy.
## Patch Plexamp
> [!IMPORTANT]
> You'll need to have the official PlexAmp app installed on your device for this to work.
You can use ADB to extract the APK from your device:
```bash
# Execute this from the root of the cloned repo
# Also make sure you have adb installed and your device connected
mkdir extracted_apks && cd extracted_apks
for apk in $(adb shell pm path tv.plex.labs.plexamp | sed 's/package://'); do
adb pull "$apk" .
done
```
> [!NOTE]
> You might be able to download the APK from some websites but it's safer to extract it from your own device.
You'll end up with something like this in the `extracted_apks` folder:
```
.
├── base.apk
├── split_config.arm64_v8a.apk
├── split_config.de.apk
├── split_config.fr.apk
├── split_config.it.apk
└── split_config.xxxhdpi.apk
```
Then you need to patch the `cacert.pem` file inside the `base.apk` to add the `plexhackCA.crt` certificate generated in
step 1 and re-sign all the APKs.
_This might sound harder than it is, just follow these steps_:
```bash
# 1. Extract the existing cacert.pem from base.apk
unzip base.apk assets/cacert.pem -d ./
# 2. Append your custom CA cert
echo -e "\nPlexHack" >> assets/cacert.pem
echo -e "==================================" >> assets/cacert.pem
cat ../certs/plexhackCA.pem >> assets/cacert.pem
# 3. Remove old cacert.pem and add the new one (with no compression)
zip -d base.apk assets/cacert.pem
zip -X0 base.apk assets/cacert.pem
# 4. Remove existing signatures from ALL APKs (base + splits)
for f in base.apk split_config.*.apk; do
zip -d "$f" 'META-INF/*'
done
# 5. Generate a keystore if you dont already have one
mkdir -p ../keystores
# This will prompt you for some info, you can put whatever you want here and enter "yes" at the end
# WARNING: Take note of the password you enter here as you'll need it to sign the APKs
keytool -genkey -v -keystore ../keystores/plexamphack.keystore -alias plexamphack -keyalg RSA -keysize 2048 -validity 10000
# 6. Sign ALL APKs with the same key
for f in base.apk split_config.*.apk; do
apksigner sign --ks ../keystores/plexamphack.keystore "$f"
done
```
You can now install the modified APK on your Android device.
```bash
# Make sure to uninstall the official PlexAmp app first
adb install-multiple base.apk split_config.*.apk
```
## Patch Plexamp Headless
```bash
# Execute this from the root of the cloned repo
mkdir plexamp_headless && cd plexamp_headless
# Download and extract Plexamp Headless
wget --no-check-certificate https://plexamp.plex.tv/headless/Plexamp-Linux-headless-v4.12.4.tar.bz2 -O plexamp-headless.tar.bz2
tar -xvf plexamp-headless.tar.bz2 && rm plexamp-headless.tar.bz2
mv plexamp/* ./ && rmdir plexamp
# Add the custom CA cert to the cacert.pem file
echo -e "\nPlexHack" >> cacert.pem
echo -e "==================================" >> cacert.pem
cat ../certs/plexhackCA.pem >> cacert.pem # you might have to adjust the path here if on a different machine
# Now you can run Plexamp Headless with the custom CA cert
node js/index.js
# (optional) You can also setup the systemd service included
mv plexamp.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now plexamp # to start at boot and start now
```
### Configure Plexamp Headless
Once started I recommend using these settings for optimal experience:
```bash
# Do not mixdown to stereo (val: true/false)
echo "Bfalse" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AaudioMixdownToStereo
# Set cache size to 512MB (val: 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072)
echo "N512" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AcacheSize
# Set how many songs to precache on WiFi (val: 0/5/10/15/20/25/40)
echo "N0" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AcachingWiFi
# Set player name (Marantz here)
echo "SMarantz" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AplayerName
# Set precache network speed to 10Mbps (val: 0/1/5/10/50/100)
echo "N10" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AprecacheNetworkSpeed
# Set sample rate conversion quality to highest (64 point sinc) (val: 0-4)
echo "N4" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AsampleRateConversionQuality
# Set sample rate matching to "Strict" (val: 0-2)
echo "N2" > ${HOME}/.local/share/Plexamp/Settings/%40Plexamp%3Asettings%3AsampleRateMatching
```
_I don't recommend accessing the Plexamp Headless webUI as it might cause issues with the hack (not tested though)._
#### Setup output device
I had to manually overwrite the default connection as I wanted to output to a S/PDIF device, check your devices with
`aplay -l` :
```
**** List of PLAYBACK Hardware Devices ****
card 1: PCH [HDA Intel PCH], device 0: ALCS1200A Analog [ALCS1200A Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
```
Create the file ``/etc/asound.conf`` and modify it to match your device, this worked for me:
```
pcm.!default {
type plug
slave {
pcm "iec958:CARD=PCH,DEV=0"
}
}
ctl.!default {
type hw
card PCH
}
```