返回资讯中心
外部精选
软件工程
#开发者实时流

盗版Free Netflix应用将视频藏进.jpg文件规避检测

来源标题:How a Pirate "Free Netflix" App Smuggles Video Inside .jpg Files

安全研究者拆解了一款名为netmirror.nmv2的盗版流媒体APK,发现其原生层是标准React Native外壳,视频被封装在.jpg文件中传输。该应用通过mobiledetect.app获取伪装域名跳转至net52.cc,可免认证访问公开片库并获取会话绑定的播放令牌,整个链路可用curl复现。

Hacker News 最新prfssnl2026/11/15 · 今天12 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

This is the story of how I tore apart a streaming APK my sister installed, convinced it was malware. It wasn’t — but the way it hides video is genuinely clever. Let’s get to it. 🫰

I decompiled the APK (app.netmirror.nmv2) with jadx and hermes-dec. The native layer is 100% stock React Native — no custom module, no addJavascriptInterface, nothing spicy.

MainActivity → React root "netmirror_beta" → one WebView

And every request it makes tags itself with:

Mozilla/5.0 (Linux; Android …) … /OS.Gatu v3.1

OS.Gatu is the operators’ internal codename. The “app” is a thin shell around a website. Classic stuff.

I reproduced the entire chain with plain curl. It looks like this:

1. bootstrap — 24 base64-encoded "mobile detect" decoy domains

curl https://mobiledetect.app/check.php

→ { "token_hash": "aHR0cHM6Ly9uZXQ1Mi5jYy9tb2JpbGUvaG9tZT9hcHA9MQ==" }

→ https://net52.cc/mobile/home?app=1 ← the WebView URL

2. catalog — public, no auth

curl "https://net77.cc/search.php?s=dark&t=$(date +%s)"

→ {"searchResult":[{"id":"80100172","t":"Dark"}, …]}

3. play token — session-bound

curl -X POST --data "id=81183523" https://net77.cc/play.php

→ {"h":"in=<md5>::<md5>::<epoch>::ni::p::<user_token>"}

4. hls master — live mirror only, and only with a Referer

curl -H "Referer: https://net52.cc/"
"https://net52.cc/hls/81183523.m3u8?q=720p&#x26;in=unknown::ni"

→ audio: s26.freecdn14.top/files/81183523/a/1/1.m3u8

video: s21.freecdn4.top/files/220884/720p/720p.m3u8

5. segment — 6.5 MB, magic bytes 0x47 0x40 = MPEG-TS

curl -H "Referer: https://net52.cc/"
"https://s21.freecdn4.top/files/220884/720p/2560_000.jpg"

→ 00000000: 4740 1110 0042 f025 0001 c100 00ff 01ff [email protected].%........

The PMT inside that “.jpg” spills the beans — stream type 0x1B = H.264 video, 0x0F = AAC audio, encoded by FFmpeg. It’s a transport stream wearing a JPEG costume.

The bundle hardcodes 24 mobiledetect.* / mobidetect(s).* domains, all base64-encoded. Each one gets tried with a 5-second timeout until one answers.

The names literally spell out “mobile detect” — which is the whole point. Takedown one domain and the app silently moves on to the next. No single point of failure.

The desktop site (net77.cc) still serves playlists pointing at a dead CDN — nm-cdn4.top / nm-cdn5.top, no DNS records at all. I genuinely thought the video was gone.

But the app’s actual mirror (net52.cc) serves the live CDN — freecdn*:

Same service, two different CDN generations. I was just reading the wrong mirror. Fair enough.

The CDN files don’t need cookies. They need one header:

no Referer → 404

curl "https://s21.freecdn4.top/files/220884/720p/720p.m3u8?in=unknown::ni"

→ 404 Not Found

with Referer → 200

curl -H "Referer: https://net52.cc/" "https://s21.freecdn4.top/files/220884/720p/720p.m3u8?in=unknown::ni"

→ 200, application/vnd.apple.mpegurl

That’s it. One header, and every default wget/curl script dies instantly. Simple and effective¹.

#EXTINF:16.666667, 2560_000.jpg ← video #EXTINF:10.005333, 6004_000.js ← audio

.jpg and .js. But file says neither — they’re MPEG-TS transport streams. Video is smuggled as images, audio as scripts. The fake extensions slip past extension-based takedown filters and lazy WAF rules.

This was the moment the whole thing clicked for me. 🤓

Catalog, posters, subtitles, and even audio are all essentially public. The video is the paywalled part:

curl -H "Referer: https://net52.cc/"
"https://s21.freecdn4.top/files/70213514/720p/720p.m3u8?in=unknown::ni"

→ <h1>Only Valid Users Allowed. error: in</h1>

The in= token is signed (session hash + user token + expiry) and only issued after the app’s “watch one ad for 20 seconds” flow. Without it you get a shared ~10-minute placeholder (files/220884/…) instead of the movie.

That ad wall is the DRM. Watch an ad → get a signed token → the CDN unlocks the real video. Audio flows free, so an unverified user literally hears the film while staring at a promo clip. 🫰

No. Not a keylogger, not a RAT. It’s a pirate streaming client with genuinely clever infra.

The real risks are boring but real: the remote WebView runs arbitrary backend-controlled JS, it’s debug-signed (anyone can ship a malicious “update”), and the whole thing is an ad-fraud funnel.

Package app.netmirror.nmv2 UA tag /OS.Gatu v3.1 Decoys mobiledetect.* / mobidetect(s).* (×24) Mirrors net50.cc · net52.cc · net77.cc CDN video: s21.freecdn4.top · audio: s26.freecdn14.top / freecdn5.top Posters imgcdn.kim Subtitles subs.nfmirrorcdn.top Downloads streamtape.com/.net/.to · stape.fun Cookies addhash · t_hash_p · user_token ({md5}::{md5}::{epoch}::ni[::p])

I guess the takeaway is that sometimes the interesting part isn’t the payload, but the plumbing.

Don’t try harder, try the live mirror. 🧠

¹ yep, plain curl, because you don’t always need burp :)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →