安全研究,开源安全

M3U8解密流程

Dplayer播放器的m3u8解密脚本

https://github.com/DIYgod/DPlayer

前言

暂时只适合未加密的m3u8文件,加密的以后再写

看看能不能用go写一个 感觉会很棒,把下面都集成一下,顺便练练开发(画饼

  1. 自行下载m3u8文件(看F12 network找
  2. 通过下面脚本获取所有流文件
# pip install aiohttp
# python3.6 以上 支持asyncio
# 在脚本目录下建一个m3u8文件夹
# 默认支持bmp后缀和ts后缀 如是其他后缀下面get_all_url函数第三行bmp或ts改一下
# 最下面将https换成了http 加快下载速度 如果服务端只支持https请删除replace
# 异步比较快 但可能会报错,对已经下载的文件会跳过,报错了退出重新运行,多运行几次到全部下完
import aiohttp
import asyncio
import re
import os
import hashlib

#你下载下来的m3u8文件
filename = "video.m3u8"

#防止文件重名(我就遇到了)
def md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()

def get_all_url():
    file_content = open(filename).read()
    urls = re.findall(r"http.*?\.(bmp|ts)",file_content,re.S)
    return urls

async def fetch(client,url):
    async with client.get(url) as resp:
        return await resp.read()

async def main(url):
    if os.path.exists(f"./m3u8/{md5(url)}.ts"):
        print("url exist: break")
        return
    async with aiohttp.ClientSession() as client:
        body = await fetch(client,url)
        open("./m3u8/"+md5(url)+'.ts',"wb").write(body)
        print(f"download success: {url}")

loop = asyncio.get_event_loop()
tasks = []

for url in get_all_url():
        # !!!!!!自行观察服务器知否支持http,如果不确定就把下面.replace删了,!!!!
    task = loop.create_task(main(url.replace("https","http")))
    tasks.append(task)

#可能报错,报错了就重新运行,直到不下载新的文件
loop.run_until_complete(asyncio.wait(tasks))

Untitled

  1. 合并

网上说ffmpeg可以合并 我命令一直报错(淦

ffmpeg -allowed_extensions ALL -i hls-720p.m3u8 -c copy new.mp4

哦对我这个脚本因为可能文件名会重复md5了一下,需要把m3u8得内容换成md5文件名重新写入才行

脚本如下

同样记得看情况改下面的 bmp

import re
import os
import hashlib

filename = "video.m3u8"
new_filename = "new.m3u8"
def md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()

file_content = open(filename).read()

with open(new_filename,"wb") as txt:
    for i in file_content.split("\n"):
        print(i)
        if re.search("http.*?\.(bmp|ts)",i,re.S):
            i = md5(i)+".ts"
            txt.write(i.encode("utf-8")+b"\n")
        else:
            txt.write(i.encode("utf-8")+b"\n")

然后合并所有文件,我直接用的python合并 3.1G的视频我本地跑了快20分钟,如果有开发大佬可以优化一下

注意下面 url=url.replace("https","http")

import hashlib
import re

filname = "video.m3u8"
def md5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()

def get_all_url():
    file_content = open(filename).read()
    urls = re.findall(r"http.*?\.(bmp|ts)",file_content,re.S)
    return urls

urls = get_all_url()
filenames = []
for url in urls:
#!!!!!!!!!!!!!!!!看情况删~之前md5存的时候有没有https!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    url=url.replace("https","http")
    filenames.append(md5(url)+".ts")

big_buffer = b""

i = 1
for filename in filenames:
    print(f"now is {str(i)}| all is {str(num)} ")
    i+=1
    big_buffer += open("m3u8/"+filename,"rb").read()

open("./m3u8_lab/new.ts","wb").write(big_buffer)

Untitled

bingo

后缀直接改成mp4也可以播放,不知道是容错还是啥(来个misc选手

对了 file命令不好使file啥都是data(- -

如果后缀是ts,windows自带的播放器可以直接打开(我是win11

如果不是,改成ts或者mp4说不定能直接打开,反正file命令是真不行

Comment

This is just a placeholder img.