在JPEG图片中嵌入HTML

最近看到一个有趣的网页:lcamtuf.coredump.cx/squirrel/,或者说一张有趣的图片——因为用网络浏览器打开它看到的是一个网页,用图片浏览器打开它看到的又是一张图片。

在服务端要对同一个请求地址实现不同响应是十分简单的,比如通过请求头Accept来判断:

  • Accept=text/html则返回超文本;
  • Accept=image/*则返回图片;
  • ……

可是lcamtuf.coredump.cx/squirrel/这个网页(或者说图片)在脱离服务端的情况下,依然能够呈现出网页和图片两种文件内容,这是怎样实现的呢?

在前端没有秘密,打开网络浏览器的开发者工具查看一下网址的响应内容:

响应内容中有熟悉HTML标签,也有一大堆乱码。这堆乱码应该是图片文件的字符读码,但是为什么在网页上看不到呢? 原来HTML中使用了body { visibility: hidden; }样式和<!--注释标签(浏览器自动补全),乱码部分就这样被隐藏了。

HTML内容:

<html><body><style>body { visibility: hidden; } .n { visibility: visible; position: absolute; padding: 0 1ex 0 1ex; margin: 0; top: 0; left: 0; } h1 { margin-top: 0.4ex; margin-bottom: 0.8ex; }</style><div class=n><h1><i>Hello, squirrel fans<img src="http://lcamtuf.coredump.cx/squirrel/">Click here!</a></xmp><xmp><img src="http://lcamtuf.coredump.cx/squirrel/"></xmp><p>No server-side hacks involved - the magic happens in your browser. Let's try embedding the current page as an image right now (INCEPTION!):<p><img src="#" style="border: 1px solid crimson"><p>Pretty radical, eh? Send money to: lcamtuf@coredump.cx<!--" style="margin: auto" />

然而在查看图片的时候,也没看到HTML的内容,又是为什么呢?

JPEG相关

首先可以确定这张图片是JPEG格式,因为内容开头有明显的JFIF标记(JFIF,是JPEG最常见的文件存储格式,也是标准的JPEG文件转换格式)。 JPEG格式定义了一系列标记码,都是以0xFF开头,常见的有:

  • 0xFFD8,SOI(Start Of Image),图片开始标记;
  • 0xFFD9,EOI(End Of Image),图片结束标记;
  • 0xFFDA,SOS(Start Of Scan),扫描开始标记;
  • 0xFFDB,DQT(Define Quantization Table),定义量化表;
  • 0xFFC4,DHT(Define Huffman Table),定义哈夫曼表;
  • 0xFFEn,APPn(Application Specific),应用程序信息;
  • 0xFFFE,COM(Comment),注释;
  • ……

图片的注释内容不会展示,很显然我们可以把HTML隐藏在图片注释中。 用十六进制读取这张图片,可以看到:

这张图片中使用了注释标记0xFFFE,标记后面跟着0x03720x0372转成十进制是882,而HTML内容的长度刚好是880个字节(0x0372本身占2个字节),所以可以知道,HTML内容就是写在这张图片注释中。

代码实现

下面用PHP代码简单实现一个将HTML内容嵌入JPEG中的函数:

<?php
function embedHtmlInJpeg($jpeg_file, $html_str, $html_file) {$length = strlen($html_str) + 2;if ($length > 256 * 256 - 1) {return false;}$content = '';$reader= fopen($jpeg_file, 'rb');$writer= fopen($html_file, 'wb');$content = fread($reader, 2); // read 0xFFD8fwrite($writer, $content); // write 0xFFD8$header= 'FFFE' . sprintf('%04X', $length);$header= pack('H*', $header);$content = $header . $html_str;fwrite($writer, $content); // write 0xFFFEwhile (!feof($reader)) {$content = fread($reader, 8192);fwrite($writer, $content); // write else}fclose($reader);fclose($writer);return true;
}

// call it
embedHtmlInJpeg('lena.jpg','<html><body><style>body { visibility: hidden; } .n { visibility: visible; position: absolute; padding: 0 1ex 0 1ex; margin: 0; top: 0; left: 0; } h1 { margin-top: 0.4ex; margin-bottom: 0.8ex; }</style><div class=n><h1><i>This image is a page.</i></h1>Just open it in new tab.<p><img src="#" style="border: 1px solid crimson"><!--','lena.html'); 

这张图片是一个网页,不信你就在新标签页中打开它

点击这里体验。

实际应用

将一段HTML文本嵌入到一张图片中,实际上,还没什么应用,哈哈哈😂。 如果能将JSShell脚本藏在图片中,并能后期执行,那就有意思了;而且本身是一个图片文件,可以避过一些安全软件的检查。

网络安全成长路线图

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成hei客大神,这个方向越往后,需要学习和掌握的东西就会越来越多,以下是学习网络安全需要走的方向:

# 网络安全学习方法

​ 上面介绍了技术分类和学习路线,这里来谈一下学习方法:
​ ## 视频学习

​ 无论你是去B站或者是油管上面都有很多网络安全的相关视频可以学习,当然如果你还不知道选择那套学习,我这里也整理了一套和上述成长路线图挂钩的视频教程,完整版的视频已经上传至CSDN官方,朋友们如果需要可以点击这个链接免费领取。网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值