Обфускація лінків зображень
5 Dec 2025 05:05Я побачив це недавно, але коїтися воно почалосі біля року тому. На деяких уйоб-сайтах звичайний теґ img став раптом виглядати як божевільне майкрософтське ікстеншона Інторнет Іксплореру 1998 року:
<img src="blob:https://example.com/b501e863-fe43-4b63-ae5d-dac14cac097e">
Уйоб-сторінка, яка його містить, наочно рендерить зображення без
жодних прублем, але коли наївний користувач збросіт лінк в чят, з
того вийде нічого--блоб, на який посилається <img>, існує лише ув
пам'ті конкретного інстансу бовзера, а на https://example.com/UUID
сервер відповість 404.
Навіщо це роблять? Деякі люди кожні n років починають боятися хотлінкінґу (сволочі воруют наш трафік), борці з ЕйАй намагаються зіпсувати бізнес злим корпораціям, а поціновувачі іграшкових DRM тішаться від нової скіми.
Якщо подивиться на fetch-ріквести такої сторінки, там будуть ресурси які схожі на зображення, але насправді не є ними:
$ url='https://ia800206.us.archive.org/🙈.jpg' $ curl -sI "$url" | grep -e type -e length -e obfuscate content-type: image/jpeg content-length: 267470 x-obfuscate: 1|uoEV6/PZOWtGhOZdVM898w== $ curl -s "$url" | head -c25 | file - /dev/stdin: data
Такий .jpg є зашифрований. Частковий ключа є ув X-Obfuscate хедері,
але про це не знає ані скрейпера рендомної ЕйАй контори, ані
будь-яка соцсіточка. Шифр також не афішується, і кожний уйоб-сайт може
мати який завгодно, дотримання рекомендацій тут зводить нанівець мету
обфускації.
Алгоритм малювання зображень тоді стає таким:
- завантажити зашифрований хфайла;
- розшифрувати його ключем з відповідного хедеру і запхнути результат ув блоб;
- створити посилання на блоб хфункцією
URL.createObjectURL; - інджекнути до DOM елемента
img, у якого атрібута src дорівнює новому посиланню.
Для збільшення ентропії можна написати кастомного елемента:
<img-blob alt="a fluffy cat" src="cat.bin"></img-blob>
який буде робити все перелічене самотужки.
Ув якості економії, аркайв.орґ AES-CTR-шифрує лише перші 1024 байт зображення. Бовзери знають про AES, але суворо вимагають secure context, що може дратувати під час тестування, тому для мікімаусного DRM можна взяти xor-шифра.
Обфускатувати X-Obfuscate хедера можна ще більше. Наприклад
x-obfuscate: rlW2MKWmnJ9hVwbtZFjtVzgyrFV6VPVkZwZ0AFW9Pt==
виглядає як рядок ув base64, але
$ echo rlW2MKWmnJ9hVwbtZFjtVzgyrFV6VPVkZwZ0AFW9Pt== | base64 -d | xxd
base64: invalid input
00000000: ae55 b630 a5a6 9c9f 6157 06ed 6458 ed57 .U.0....aW..dX.W
00000010: 3832 ac55 7a54 f564 6706 7400 55bd 3e 82.UzT.dg.t.U.>
Я спитав вініпухівський ДіпСік розібратися: він витратив 9 хвилин і залишив без води 2 села ув провінції Чжецзян, був кілька разів дуже близько від мети, але зрештою зазнав невдачі.
Рядок був оброблений напилком rot13:
$ alias rot13="tr 'A-Za-z' 'N-ZA-Mn-za-m'"
$ echo rlW2MKWmnJ9hVwbtZFjtVzgyrFV6VPVkZwZ0AFW9Pt== | rot13 | base64 -d
{"version": 1, "key": "12345"}
Ув якості домашнього завдання, до кастомного елементу можна додати
еквівалента loading="lazy" за допомогою Інтерсекційного
Спостерігача.