Recently saw a interesting web: lcamtuf. Coredump. Cx/squirrel, or a picture of a fun, because using a web browser to open it to see is a web page, use the browser to open it to see is a picture.

It is very simple to implement different responses to the same request address on the server side, such as request header Accept:

  • Accept=text/htmlReturns hypertext;
  • Accept=image/*Returns the picture;

Cx/squirrel/but lcamtuf. Coredump. This web page (or image) in case from service side, still be able to present two file content pages and images, how did this happen?

No secrets on the front end, open your web browser’s developer tools and check out the url’s response:

The response contains familiar HTML tags and a lot of garbled code. This gibberish should be the character read of the image file, but why can’t you see it on the web page? Use body {visibility: hidden; } styles and

HTML content:

<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.4 the ex; margin-bottom: 0.8 the ex; }</style><div class=n><h1><i>Hello, squirrel fans!</i></h1>This is an embedded landing page for an image. You can link to this URL and get the HTML document you are viewing right now (soon to include essential squirrel facts); or embed the exact same URL as an image on your own squirrel-themed page:<p><xmp><a href="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: [email protected]<! --Copy the code

However, when I view the image, I do not see the HTML content. Why?

JPEG related

The first thing you can determine is that the image is in JPEG format because the content has a distinct JFIF flag at the beginning. (JFIF, which is JPEG’s most common file storage format, is also the standard JPEG file conversion format.) The JPEG format defines a series of tokens, all beginning with 0xFF. Common ones are:

  • 0xFFD8, SOI (Start Of Image), Image Start mark;
  • 0xFFD9, EOI (End Of Image), End Of Image marker;
  • 0xFFDA, SOS (Start Of Scan), Start Of Scan mark;
  • 0xFFDB, DQT (Define Quantization Table), Define the Quantization Table;
  • 0xFFC4, DHT (Define Huffman Table), Define Huffman Table;
  • 0xFFEnAPPn (Application Specific), Application information;
  • 0xFFFE, COM (Comment), Comment;

The comment content of the image is not displayed, so obviously we can hide the HTML in the comment of the image. Reading the picture in hexadecimal, you can see:

This image uses the comment tag 0xFFFE, followed by 0x0372. 0x0372 in decimal is 882, and the HTML content is exactly 880 bytes long (0x0372 itself is 2 bytes), so you know that the HTML content is written in the image comment.

Code implementation

Here is a simple function to embed HTML content in a JPEG using PHP code:


      
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 0xFFD8
    fwrite($writer, $content); // write 0xFFD8

    $header  = 'FFFE' . sprintf('%04X', $length);
    $header  = pack('H*', $header);
    $content = $header . $html_str;
    fwrite($writer, $content); // write 0xFFFE

    while(! 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.8 the ex; }</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');

Copy the code

This image is a web page, just open it in a new TAB

Click here to experience it.

The practical application

Embedding a piece of HTML text into an image, actually, has no application, hahaha 😂. It would be interesting if you could hide JS or Shell scripts in images and execute them later; And itself is a picture file, can avoid some security software checks.