经验教程 ·

白嫖一下 Emby

分析

使用工具抓包,发现 Emby 客户端访问了一个外部站点 mb3admin.com 会请求一些东西,然后返回了​‌‌‌​‌​​​​​‌‌​‌​‍​‌​‌‌‌​​‌‌‌‌​‌​‍​‌​​‌​​​‌​​​‌‌​‍​​‌‌​​​‌​​‌‌​‌​‍​‌‌‌‌‌‌​​​​‌​‌​‌‍‌​‌​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍‌​‌‌‌‌​‌‍‌​​‌​​‌‌‍‌​​‌​​​​‍‌​​‌‌​​​‍​​‌‌​‌​​​​​‌​​‌‍​‌​‌‌‌​‌​‌‌​‌‌​‍​‌‌‌​​​​‌​​​‌​‌‌‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌​‌‌‌‌‌‌‌‌​​​‍​‌‌​​‌‌‌​‌‌​​‌‌‌‍​‌‌​​​‌‌‌​​​‌​‌‍​​‌‌‌‌‌‌‌‌​​‌‌‍​​​‌​​‌‌​​​​​‌​‍​‌​​‌​‌​​‌​‌​​‌‍​‌‌​​​‌‌‌‌‌‌‌‌‌‍​‌‌​​​‌‌‌‌‌​‌​​‍‌​‌‌‌​‌​‍‌​​‌​​‌​‍‌​​‌‌‌​‌‍‌​​​​‌‌​‍​​‌‌‌‌‌‌‌‌​​‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​​​‌​‌​‌‌​​‌‌‌​‍‌​​‌​​​​‍‌​​​‌​‌​‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍​‌‌​​​‌​‌‌‌​​​‌‍‌‌​​‌‌​‌‍‌‌​​‌‌‌‌‍‌‌​​‌‌​‌‍‌‌​​‌‌‌‌‍‌‌​‌​​‌​‍‌‌​​‌‌‌‌‍‌‌​​‌‌‌​‍‌‌​‌​​‌​‍‌‌​​‌‌‌​‍‌‌​​​‌‌‌‍​​‌‌‌​‌‌​‌‌‌‌‌‌‍​‌​‌‌‌​​‌‌​​‌‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌‌​‌​​‌‌‌‌​​​‍​‌​‌​​​‌‌​​‌‌‌‌‍​‌​‌​​​‌​‌‌‌‌‌‌‍​​​​​​​​‌‌‌​​‌​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​​‌‌‌‌‍‌​​​‌‌​​‍‌‌​​​‌​‌‍‌​‌​​​‌‌‍‌​‌​​​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​​‌‌​‌‍‌​​‌‌‌​‌‍‌​​​‌‌‌​‍‌‌​‌​​​‌‍‌​​‌‌‌​​‍‌​​‌​​​‌‍‌​‌​​​‌‌‍‌​​‌‌​‌​‍‌​​​​‌‌‌‍‌​​​‌‌‌‌‍‌​‌​​​‌‌‍‌​​‌‌​‌​‍‌​​‌​​‌​‍‌​​‌‌‌​‌‍‌​​​​‌‌​‍‌​‌​​​​​‍‌​​‌​‌‌‌‍‌​​‌‌‌‌​‍‌​​‌‌‌​​‍‌​​‌​‌​​‍‌‌​‌​​​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​‌​​‌​‍‌​​‌​​‌‌

{
  "message" : "Device Not Registered",
  "cacheExpirationDays" : 7,
  "resultCode" : "NOTREG"
}

这里应该就是判断客户端是否被授权的响应了。值得注意的是,客户端的请求带上了服务器 ID、客户端 ID 等其他客户端信息。这令我想起了之前参阅 Emby Premiere 规则时看到的,单个 Key 至多支持 25 台设备,我之前看到网上有不少 Emby 合车的人,但是他们都是 10 人车,我还纳闷为啥不 25 人车?(顺便一提,Emby Premiere 永久价格大概是 815 块大洋。) 如果是按照客户端来计算激活设备的话,并且还要算上服务器激活一台的话,那么 10 人车每个人只能享受 2 台设备的样子?(一台服务器,一个手机) 那客户端发过去的设备 ID 是随机的,我刷个机或者怎么样就变一个 id,这 25 台设备还不是一下自就造完了...

回到正题,后来查阅资料,也着手分析了一下 Emby 的 Windows 版本 (是个 Electron 应用),我们只需要让客户端请求后得到如下返回:

{
    "cacheExpirationDays": 7,
    "message": "Device Valid",
    "resultCode": "GOOD",
}

即可。既然不方便对客户端下手,那我们来搭建一个伪站吧。
据自己测试,客户端会缓存授权信息,猜测应该和 cacheExpirationDays 有关,也许和 KMS 一样的操作,我现在设置成 365 了。。。不过经测试,激活一次后使用流量可正常使用:经过整理,emby 每次激活会访问:

/admin/service/registration/validate
/admin/service/registration/getStatus
/admin/service/registration/validateDevice

搭建伪站

一些准备

你只需要一个能访问的 Web 服务器就行,本文使用 Nginx
一个装有 OpenSSL 的设备,当然你也可以不用
Emby 客户端,其实这个你不要也可以 (逃

建立一个站点

新建一个域名为 mb3admin.com 的站点就行,
你的服务端,客户端都要能够正常访问伪站。
然后只需要配置伪静态。Apache 服务器请自行寻找相关资料,目的就是直接让 Nginx 返回我们需要的 JSON
这里我提供我写的伪静态,如果你有更好的...

location /admin/service/registration/validateDevice {
    default_type application/json;
  return 200 '{"cacheExpirationDays": 7,"message": "Device Valid","resultCode": "GOOD"}';
}
location /admin/service/registration/validate {
    default_type application/json;
  return 200 '{"featId":"","registered":true,"expDate":"2099-01-01","key":""}';
}
location /admin/service/registration/getStatus {
    default_type application/json;
  return 200 '{"deviceStatus":"","planType":"","subscriptions":{}}';
}

保存后,到浏览器内测试访问一下 https://mb3admin.com/admin/service/registration/validateDevice
正常返回我们要的 json 即成功。

签发证书

这里我会详细介绍如何签发自己的证书,当然你可以跳过这一步,直接到文件末尾下载我生成好的证书。
这里我提供三种方法,前一种是自己动手,第二种是超级省事,翻到文章末尾是粘贴复制 (逃

使用 OpenSSL 进行签发

生成 CA 请求并签名

使用命令 openssl req -x509 -new -nodes -key ca.key -days 3650 -subj "/C=JP/ST=Japan/L=Japan/O=Emby/CN=mb3admin.com" -out ca.pem
一步到位。
这样就会在当前路径下签出一张 CA 证书与 CA 密钥,如果懂一点点的话可以按需要修改其中的参数。

请求服务器证书

使用命令 openssl req -newkey rsa:2048 -days 824 -nodes -keyout ssl.key -subj "/C=JP/ST=Japan/L=Japan/O=Emby/CN=mb3admin.com" -out ssl.csr
然后

构建 CA 机构结构

使用命令 mkdir -p /etc/pki/CA;mkdir -p /etc/pki/CA/newcerts;touch /etc/pki/CA/index.txt;mkdir /etc/pki/CA/private;echo 01 > /etc/pki/CA/serial
即可一键构建好 CA 机构,然后将 CA 的证书和密钥添加到机构中:
cp ca.pem /etc/pki/CA/cacert.pem;cp ca.key /etc/pki/CA/private/cakey.pem

自定义证书用途

此时如果直接签发,会发现不仅没有 DNS 备选名称而且证书用途是这样会导致 Chrome 以及大部分现代浏览器不信任。
新建一个 http.ext 文件,里头写上:

keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
[email protected]
 
[ SubjectAlternativeName ]
DNS.1=mb3admin.com
DNS.2=*.mb3admin.com

签发证书!

执行 openssl ca -extfile http.ext -in ssl.csr -out ssl.pem
回答两个 y 即可发现当前目录下已经签出了 ssl.pem

使用网上的工具一键签发

因为对 OpenSSL 了解不深,一些自定义项根本不知道写啥,为此搜索了一圈,发现了这个宝藏站点:国密线上证书签发
打开后,按照这样填写:


一个是加密算法选 RSA, 密钥长度至少选 2048, 然后除主题名称要按我这个写之外其他的按照规则随意填写。点开高级选项:


主题备用名称照我这样填写,记得 DNS 与数字直接有一个.。按照图这样勾选两处用途。然后勾选自动包含CA证书链,最后是证书有效天数,写 824 天即可。

 

配置证书

在 Web 服务器中为站点部署好 ssl.key 与 ssl.pem 作为密钥与 SSL 证书即可。如果是国密生成出来的就是 mb3admin.com.key.pem 和 mb3admin.com.cert.pem

国密证书请下载刚刚生成页面中提到的根证书也可以前往本文最后获取国密的 CA 证书,然后按照下面的方法使用。如果你是 OpenSSL 命令生成的:
把 ca.pem 中的内容写入到本地计算机新建的一个 ca.crt 文件中,双击打开:


选择安装证书,根据需求选择安装位置,然后第三步,


选择将所有证书都放入下列存储,单击浏览,选择受信任的根证书颁发机构然后下一步下一步
导入完成后,我们在浏览器中访问 https://mb3admin.com/admin/service/registration/666


It's works!
如果还是报错,尝试重启浏览器,清理缓存等步骤。

 

添加头部

Nginx 服务器请直接在网站的配置文件中加入:

    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers *;
    add_header Access-Control-Allow-Method *;
    add_header Access-Control-Allow-Credentials true;

避免部分地方有跨域的问题。

尝试一下

打开 Emby Windows 客户端,


能使用下载到功能,并且能直接修改主题
并且播放也正常。iOS 设备也全部正常!

 

在 Linux 下配置证书

经测试,共两处需要配置

/opt/emby-server/etc/ssl/certs/ca-certificates.crt
/etc/pki/tls/certs/ca-bundle.crt

第一处是 emby 的 c# 环境自带的信任列表,这个我找了很久。第二处是 linux 系统的信任列表。本来是没打算写的,因为在我服务器上修改系统的信任列表直接可用 (CentOS8) 但是多方测试发现在 CentOS7 下会出现证书信任问题,但是 curl 可以正常请求。就考虑到是 C# 类似 java 一样,本身有信任列表。

在 emby 的目录翻找,运气好找到了这个文件。只需要把根证书添加在结尾即可。
Windows 下可以不用管,是直接跟系统信任的。

为什么是 824 天?

可能有人注意到了,为什么服务器证书只能写 824 天?
这里要感谢 V2ex 的网友。之前证书在 Windows 完全正常,但是在 iOS 设备上就是提示非私人链接,逐询问万能的网友。这里了解了一份苹果官方文件感兴趣的可以点开看看,对证书做了一些要求,故保全,使用 825-1 天。

 

原文:https://imrbq.cn/exp/emby_hack.html

参与评论