steal-video

As we all know that “security via obscurity” is a bad thing, common people will always believe that.

Remember, only encryption gives you security for some extend.

Watch film online

I want to watch a masterpiece called fight club. Going through some simple search you can find those streaming website.

watch fight club online

I always appreaciate these guys for letting people watch movie freely, making money from advertising, very old-school way.

Due to my poor Internet connection, I want to donwload the film and watch it without interruption.
However, the website do not provide a direct donwload button.

View the source

So we just view the page source to see if we can find the video directly from <video src="xxx">

source

It’s not there, I don’t know what a blob: is.

Network traffic

Then I check the network log, the site must send the video through.

m3u8

Fortunately, I have heard about the m3u8 file, functioning as a donwload list for stream video by small segments.

chatgpt

But the m3u8 file does not seems to be a standard one, it doesn’t have the .ts file and unable to directly access.

non-standard

unable to directly access

That confuse me, I then bark at the wrong tree for some time.

View the segments

Just before giving up, an idea hit me, why not just see the streaming process of the segments ?

segments

You can see that the request is not 404, it is actually redirect to a png file.

So it is really import to use a burp suite !!! Don’t be lazy

They must hide the video in the png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
$ file 2c4c3bda-341d-467a-aeb6-e020a1f8ac8a.png
2c4c3bda-341d-467a-aeb6-e020a1f8ac8a.png: PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced
$ xxd 2c4c3bda-341d-467a-aeb6-e020a1f8ac8a.png
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
00000010: 0000 0001 0000 0001 0806 0000 001f 15c4 ................
00000020: 8900 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB.......
00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000 ..gAMA......a...
00000040: 0009 7048 5973 0000 1274 0000 1274 01de ..pHYs...t...t..
00000050: 661f 7800 0000 0d49 4441 5418 5763 f8ff f.x....IDAT.Wc..
00000060: ffff 7f00 09fb 03fd 0543 45ca 0000 0000 .........CE.....
00000070: 4945 4e44 ae42 6082 4740 1110 0042 f025 IEND.B`.G@...B.%
00000080: 0001 c100 00ff 01ff 0001 fc80 1448 1201 .............H..
00000090: 0646 466d 7065 6709 5365 7276 6963 6530 .FFmpeg.Service0
000000a0: 3177 7c43 caff ffff ffff ffff ffff ffff 1w|C............
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000d0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000e0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000f0: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000100: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000110: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000120: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000130: ffff ffff 4740 0010 0000 b00d 0001 c100 ....G@..........
00000140: 0000 01f0 002a b104 b2ff ffff ffff ffff .....*..........
00000150: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000160: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000170: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000180: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000190: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001a0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001b0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001c0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001d0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001e0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000001f0: 4750 0010 0002 b01d 0001 c100 00e1 00f0 GP..............
00000200: 001b e100 f000 0fe1 01f0 060a 0475 6e64 .............und
00000210: 0008 7de8 77ff ffff ffff ffff ffff ffff ..}.w...........
00000220: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000230: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000240: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000250: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000260: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000270: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000280: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000290: ffff ffff ffff ffff ffff ffff ffff ffff ................
000002a0: ffff ffff ffff ffff ffff ffff 4741 0030 ............GA.0
000002b0: 0750 00da d57c 7e00 0000 01e0 0000 80c0 .P...|~.........
000002c0: 0a31 06db 9a05 1106 db42 2100 0000 0109 .1.......B!.....
000002d0: f000 0000 0106 0007 802b f200 0003 0040 .........+.....@
000002e0: 8000 0001 0601 0401 2088 1080 0000 0001 ........ .......
000002f0: 6764 0028 ac2c ac07 8065 b011 0000 0303 gd.(.,...e......
00000300: e800 00bb 80e0 0000 0f42 4000 01e8 482e .........B@...H.
00000310: f2e0 a000 0000 0168 ee3c b000 0000 0165 .......h.<.....e
00000320: b802 003f de06 f77f cf8d 41b0 cbfc 8f9e ...?......A.....
00000330: d303 1876 3d9f d8c3 3b60 7c53 c928 eeef ...v=...;`|S.(..
00000340: 11e0 b016 876f caea 685a de84 a77c 4885 .....o..hZ...|H.
00000350: 62de eb1c f8a4 dd03 3f3c 2bb7 e35b 0730 b.......?<+..[.0
00000360: 233c e45a 9997 14d4 4701 0011 4e4f 173e #<.Z....G...NO.>
00000370: 8dda ef44 9307 b77d 38ae 0529 88ec 1727 ...D...}8..)...'
00000380: 9aa7 267b c8cb 8593 a5c9 b238 85f8 505d ..&{.......8..P]
00000390: e0a9 0502 a726 e51c 4c54 45d2 be7a f6e6 .....&..LTE..z..
000003a0: 1dd6 9b6b 6402 d469 dc55 2a4e 722c a667 ...kd..i.U*Nr,.g
000003b0: 7c1c 42b8 2642 1caa 53ba e5ac a49d cdff |.B.&B..S.......
000003c0: 0f5f 9cc0 c7be e7cb d2a1 a39b bee8 ca9c ._..............
000003d0: 65aa 531c a753 52e6 d25d c01c 4906 c125 e.S..SR..]..I..%
000003e0: f00f 79fb d7d8 68f5 30eb f89f 3c6c 2a41 ..y...h.0...<l*A
000003f0: b301 bae4 b13f ad01 6c20 9bb5 306c 2f8a .....?..l ..0l/.
00000400: b15e 4317 497a 5855 7082 c42a f5c0 8335 .^C.IzXUp..*...5
00000410: 55c1 593e b33d 3d4c 3157 8b13 46f5 351c U.Y>.==L1W..F.5.
00000420: 9d46 59c1 4701 0012 6c97 b23a a508 87ad .FY.G...l..:....
00000430: 3a76 65c3 9c20 e3ff b344 79e2 07ee 1478 :ve.. ...Dy....x
00000440: 6a3a 223f 64b3 aba6 6fcf 3a34 fc0c 9e30 j:"?d...o.:4...0
00000450: df56 5e47 a0a0 9dbd 680e f5ab 4237 035d .V^G....h...B7.]
00000460: 92f4 18ec edf3 40f5 286c 6b25 ae4c 33a9 ......@.(lk%.L3.
00000470: 1317 d706 49ae 1486 b22e a388 588e d4b0 ....I.......X...
00000480: dd20 a88d b90c 2dfb 5532 8477 05a0 3ee2 . ....-.U2.w..>.
00000490: 9beb 1986 8bb9 a4d4 b566 fcd0 3f80 d8e4 .........f..?...
000004a0: 130d c419 0fa5 8270 bca0 7f5c 3273 8f15 .......p...\2s..
...
$ binwalk -E 2c4c3bda-341d-467a-aeb6-e020a1f8ac8a.png

entropy

Power of FFmpeg

I don’t know much about the video encoding, but I know that FFmpeg is really powerful.
So I just google some thing then find something about ‘video disguise as png’.

disguise

ffprobe

It works. 🎉.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$ dd if=2c4c3bda-341d-467a-aeb6-e020a1f8ac8a.ts of=1.ts ibs=8 skip=1
398198+0 records in
6221+1 records out
3185584 bytes transferred in 0.438318 secs (7267746 bytes/sec)
$ ffprobe 1.ts
ffprobe version 6.1.1 Copyright (c) 2007-2023 the FFmpeg developers
built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/6.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopenvino --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox
libavutil 58. 29.100 / 58. 29.100
libavcodec 60. 31.102 / 60. 31.102
libavformat 60. 16.100 / 60. 16.100
libavdevice 60. 3.100 / 60. 3.100
libavfilter 9. 12.100 / 9. 12.100
libswscale 7. 5.100 / 7. 5.100
libswresample 4. 12.100 / 4. 12.100
libpostproc 57. 3.100 / 57. 3.100
[h264 @ 0x7fef31205300] non-existing SPS 0 referenced in buffering period
Last message repeated 1 times
Input #0, mpegts, from '1.ts':
Duration: 00:00:06.12, start: 319.406178, bitrate: 4164 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x800 [SAR 1:1 DAR 12:5], 24 fps, 24 tbr, 90k tbn
Stream #0:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 194 kb/s
$ ffmpeg -i 1.ts out.mp4
ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
built with Apple clang version 15.0.0 (clang-1500.1.0.2.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/6.1.1_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags='-Wl,-ld_classic' --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libharfbuzz --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopenvino --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-audiotoolbox
libavutil 58. 29.100 / 58. 29.100
libavcodec 60. 31.102 / 60. 31.102
libavformat 60. 16.100 / 60. 16.100
libavdevice 60. 3.100 / 60. 3.100
libavfilter 9. 12.100 / 9. 12.100
libswscale 7. 5.100 / 7. 5.100
libswresample 4. 12.100 / 4. 12.100
libpostproc 57. 3.100 / 57. 3.100
[h264 @ 0x7fb70f304b00] non-existing SPS 0 referenced in buffering period
Last message repeated 1 times
Input #0, mpegts, from '1.ts':
Duration: 00:00:06.12, start: 319.406178, bitrate: 4164 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x800 [SAR 1:1 DAR 12:5], 24 fps, 24 tbr, 90k tbn
Stream #0:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 194 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x7fb70e73f3c0] using SAR=1/1
[libx264 @ 0x7fb70e73f3c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x7fb70e73f3c0] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0x7fb70e73f3c0] 264 - core 164 r3108 31e19f9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out.mp4':
Metadata:
encoder : Lavf60.16.100
Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 24 fps, 12288 tbn
Metadata:
encoder : Lavc60.31.102 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc60.31.102 aac
frame= 0 fps=0.0 q=0.0 size= 0kB time=00:00:00.27 bitrate= 1.4kbits/s dup=3 drop=0 speed= 5frame= 0 fps=0.0 q=0.0 size= 0kB time=00:00:02.06 bitrate= 0.2kbits/s dup=3 drop=0 speed=3.frame= 10 fps=8.6 q=28.0 size= 0kB time=00:00:02.90 bitrate= 0.1kbits/s dup=3 drop=0 speed=2frame= 26 fps= 16 q=28.0 size= 512kB time=00:00:03.64 bitrate=1150.6kbits/s dup=3 drop=0 speed=2frame= 44 fps= 20 q=28.0 size= 768kB time=00:00:04.31 bitrate=1456.8kbits/s dup=3 drop=0 speed=1frame= 63 fps= 23 q=28.0 size= 1024kB time=00:00:05.10 bitrate=1642.2kbits/s dup=3 drop=0 speed=1frame= 81 fps= 25 q=28.0 size= 1280kB time=00:00:05.94 bitrate=1764.1kbits/s dup=3 drop=0 speed= [out#0/mp4 @ 0x7fb70e708380] video:2549kB audio:102kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.230687%
frame= 147 fps= 31 q=-1.0 Lsize= 2657kB time=00:00:06.00 bitrate=3627.7kbits/s dup=3 drop=0 speed=1.25x
[libx264 @ 0x7fb70e73f3c0] frame I:1 Avg QP:21.43 size:112709
[libx264 @ 0x7fb70e73f3c0] frame P:39 Avg QP:23.28 size: 35773
[libx264 @ 0x7fb70e73f3c0] frame B:107 Avg QP:25.57 size: 10298
[libx264 @ 0x7fb70e73f3c0] consecutive B-frames: 1.4% 2.7% 6.1% 89.8%
[libx264 @ 0x7fb70e73f3c0] mb I I16..4: 6.8% 60.8% 32.4%
[libx264 @ 0x7fb70e73f3c0] mb P I16..4: 5.1% 17.3% 2.3% P16..4: 44.5% 12.0% 5.5% 0.0% 0.0% skip:13.2%
[libx264 @ 0x7fb70e73f3c0] mb B I16..4: 0.5% 1.2% 0.1% B16..8: 48.2% 4.5% 0.9% direct: 2.1% skip:42.5% L0:42.1% L1:52.5% BI: 5.4%
[libx264 @ 0x7fb70e73f3c0] 8x8 transform intra:69.0% inter:77.9%
[libx264 @ 0x7fb70e73f3c0] coded y,uvDC,uvAC intra: 53.0% 35.7% 6.2% inter: 14.7% 10.1% 0.1%
[libx264 @ 0x7fb70e73f3c0] i16 v,h,dc,p: 30% 23% 12% 36%
[libx264 @ 0x7fb70e73f3c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 28% 18% 24% 4% 5% 7% 5% 5% 4%
[libx264 @ 0x7fb70e73f3c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 27% 26% 11% 4% 6% 6% 7% 6% 7%
[libx264 @ 0x7fb70e73f3c0] i8c dc,h,v,p: 54% 20% 21% 4%
[libx264 @ 0x7fb70e73f3c0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x7fb70e73f3c0] ref P L0: 69.4% 16.9% 10.0% 3.6%
[libx264 @ 0x7fb70e73f3c0] ref B L0: 91.4% 7.6% 0.9%
[libx264 @ 0x7fb70e73f3c0] ref B L1: 96.4% 3.6%
[libx264 @ 0x7fb70e73f3c0] kb/s:3408.59
[aac @ 0x7fb70e769f40] Qavg: 1057.715

res

Get the movie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import requests as r
from tqdm import tqdm
url = "https://m3.ziziys.com"

f = open("18NjViNzhmZTg4ZDk5NSRodHRwczovL3d3dy5idHR3by5uZXQvd3AtY29udGVudC91cGxvYWRzLzIwMjMvMDUvOTJiNmFjMzVmMjI5NDkubTN1OCQxNzA2NTI4NzQ065b78fe88d992.m3u8" , "rt")


ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604."

head = { "User-Agent" : ua }

ls = [l for l in f.readlines() if 'ts' in l]
for index,line in tqdm(enumerate(ls), desc="Downloading items" , total = len(ls)):
location = url + line.strip()
try:
resp = r.get(location , headers = head)
except:
try:
resp = r.get(location , headers = head)
except:
print("error downloading {}.ts, URL:{}".format(index , location))
continue
if resp.status_code == 200:
# Actually I expect a 302 here, but it just return the png file without redirection ...
with open("clips/{}.ts".format(index) , "wb") as savefile:
savefile.write( resp.content[1:] )
else:
print("error downloading {}.ts, URL:{}".format(index , location))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# It costs me fucking 5 hours ! I should have made the script multi-threading.
$ py down.py
Downloading items: 100%|█████████████████████████████████| 1392/1392 [4:56:34<00:00, 12.78s/it]

$ ls -1 | sort --numeric-sort > filelist.txt
$ nvim filelist.txt
$ cat filelist.txt
file 000.png
file 001.png
file 002.png
file 003.png
file 004.png
file 005.png
file 006.png
file 007.png
file 008.png

# Although there are some warning/error, I successfully get it !
$ ffmpeg -f concat -safe 0 -i filelist.txt -c copy Fight_Club.mp4
...
[h264 @ 0x7fd8ff806340] non-existing SPS 0 referenced in buffering period
Last message repeated 1 times
[out#0/mp4 @ 0x7fd8fd010100] video:2650522kB audio:197995kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.144595%
size= 2852636kB time=02:21:40.98 bitrate=2749.0kbits/s speed=53.2x

movie

Conclusion

Know the detail, but don’t be confused by the detail.

The attack idea is important.

The idea is always the most important.


Revisit

Now we are in 2025, we have AI

The website now use public CDN to host their video clips, fantastic and profitble

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:14
#EXTINF:6.286444,
https://dc.xhscdn.com/file/0c991deaeac4c6ae81dfecb3d8bff869/000.png
#EXTINF:3.840000,
https://dc.xhscdn.com/file/f6af916521553f1b9189ab9637bece0b/001.png
#EXTINF:3.240000,
https://dc.xhscdn.com/file/43786032d246eec297939cba6dd6c480/002.png
#EXTINF:3.640000,
https://dc.xhscdn.com/file/af9452210b281c8fa05ef28b225284a0/003.png
#EXTINF:10.000000,
https://dc.xhscdn.com/file/fb85be6378570d9bcdf2129f79173a4b/004.png
#EXTINF:2.240000,
https://dc.xhscdn.com/file/d6a4efc6f5338075b0d1e626c0ea6425/005.png
#EXTINF:1.000000,
https://dc.xhscdn.com/file/aea2ff8a322d815fd6f5531a951b22c6/006.png
#EXTINF:4.240000,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import requests
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm

urls = []
with open("../list.m3u8","rt") as f:
for line in f:
if '.png' in line:
urls.append(line.strip())

# Function to download a single URL
def download_url(url):
try:
response = requests.get(url)
# Simulate a small delay for demonstration purposes (can be removed)
with open("{}".format(urlparse(url).path.split('/')[-1]) ,"wb") as f:
f.write(response.content[1:])
return url, len(response.content) # return URL and size of content
except requests.RequestException as e:
return url, str(e) # If there's an error, return the error message

# Create a ThreadPoolExecutor with a maximum of 30 threads
def download_urls(urls):
results = []

# Initialize ThreadPoolExecutor and progress bar
with ThreadPoolExecutor(max_workers=30) as executor:
# Track the progress using tqdm
with tqdm(total=len(urls), desc="Downloading", unit="url") as pbar:
# Submit the download tasks to the thread pool
futures = {executor.submit(download_url, url): url for url in urls}

# Process each future as it completes
for future in as_completed(futures):
url, result = future.result()
results.append((url, result))
pbar.update(1) # Update the progress bar after each download

return results

if __name__ == '__main__':
# Call the download function
results = download_urls(urls)

# Print the results of each download
for url, result in results:
print(f"Downloaded from {url}: {result}")

The download get speed up by 30x.

(If the .m3u8 file contain .ts files point to a normal video clip instead of a .png, than IINA meidan player can play it directly)

Further investigation

  • How to use public CDN like xhscdn.com to store your own file ?
  • The website use Thinkphp V5.0.24, and do a simple search on the Internet, you will find that this version has some unserialize vulnerability to all RCE.