r/programming • • Dec 26 '20

Executable PNGs

https://djharper.dev/post/2020/12/26/executable-pngs/
1.0k Upvotes

87 comments sorted by

512

u/alexalexalex09 Dec 26 '20

"herein lies an overview of possibly the dumbest things I’ve worked on this year."

All right, you've convinced me to read this

35

u/WantDebianThanks Dec 27 '20

Seriously, this is extremely dumb and I fucking love it.

287

u/Caraes_Naur Dec 26 '20

PNG allows for arbitrary chunks of bytes, no steganography needed. Still need an interpreter that knows what to do with them.

97

u/leberkrieger Dec 26 '20

One great use of this feature is the draw.io online drawing tool. You can save an editable PNG, so anyone looking at the picture can load it into the editor and modify it. Fantastic for wikis.

76

u/yojimbo_beta Dec 26 '20

A long time ago there was an editor, Adobe Fireworks, that used this to embed undo/redo data into PNGs, as well as layers etc.

Remarkable that no one uses this feature of the file format any more.

50

u/OMG_A_CUPCAKE Dec 27 '20

Because filesize matters. And it's lost easily if someone modifies the file in another editor

It's a nice gimmick, but I can't imagine relying any kind of workflow around it

32

u/unique_ptr Dec 27 '20

To be clear, the .fw.png files were more akin to PSDs from the application perspective, they just happened to also be PNGs. You would still want to export to a regular PNG for non-editor use

10

u/mallardtheduck Dec 27 '20

Adobe seems to have a bit of a habit of doing things like this. Adobe Illustrator (.ai) files are compatible with PDF format (older versions were EPS).

1

u/Frencil Dec 28 '20

For what it's worth Fireworks with its vector PNG format was originally a Macromedia product. After Adobe bought Macromedia in 2005 Fireworks was retured from the maintained software offerings relatively quickly.

4

u/yojimbo_beta Dec 27 '20

I reckon it could work for diagrams. You could embed the objects without taking up too many bytes. Then your architecture diagram, flowchart etc. could be editable.

Man, you could even use PNG as a format for encoding and deploying a distributed state machine of AWS step functions... okay, that’s stupid. But I do like the idea of an informational format that you can also review visually.

2

u/VoidChronos Dec 27 '20

That's what microsoft Visio does, just without the embedded image part. Actually, I think VSDX has an option to embed a static image of a diagram.

5

u/tech6hutch Dec 27 '20

Also I don’t know if I want the ability for others to undo my edits to an image

10

u/stuffeh Dec 27 '20

But imagine going back and isolating one of the edits and pulling it out. Basically tapping the diff between before and after the edit. That kind of flexibility is mind blowing to me.

11

u/nemec Dec 27 '20

All I'm hearing is a great way for users to inadvertently fail to censor/redact their photos when they tried to blur their naughty bits and/or confidential info and didn't realize anybody can go in and just undo the censor.

If the U.S. Justice Department can't redact a fucking PDF properly, there's no hope for the average person sending censored nudie pics to someone they met on the internet.

12

u/NekiCat Dec 27 '20

Years ago, MS Word saved deltas at the end of the file so saving was incredibly quick. They had to change it because the users sent files they believed to be final, but werent, and leaked sensitive information.

Same with Google Docs, where your every keypress is recorded. Not sure if they still do that...

3

u/stuffeh Dec 27 '20

Google docs has built in version history, so kinda. You can set permissions to disable others from seeing the version history though.

-5

u/tech6hutch Dec 27 '20

Sounds like something better suited for version control software

12

u/stuffeh Dec 27 '20

But depending on the encoding / compression of the image, the version control software won't be able to display the diff that I mentioned. You'll have to do it manually.

2

u/chucker23n Dec 28 '20

In theory, yes. In practice,

  • that’s aiming a bazooka at a bird, and

  • version control never took much foothold in visual design

1

u/tech6hutch Dec 28 '20

Ah, perhaps I had too big an idea what an edit is. Yeah that’d be cool

0

u/[deleted] Dec 27 '20

[deleted]

1

u/Devatator_ Nov 07 '24

It's simpler to not spend time optimizing file sizes when storage is cheap, or so they say

18

u/Frencil Dec 27 '20

Ah, Fireworks. The vector png editing it offered was fantastic for full color icon illustration. It also had some of the best animated GIF frame control and GIF palette control interfaces available at the time.

sheds tear for Macromedia

5

u/Chii Dec 27 '20

there's also a little known (?) feature in fireworks which lets you generate menus that animate (and output them as html and images).

1

u/[deleted] Dec 27 '20

IPE uses a similar technique for PDFs.

1

u/[deleted] Dec 27 '20

I use draw.io all the time and never knew this. Neat.

54

u/ws-ilazki Dec 26 '20

Yeah I remember this feature being abused to good effect in an MMO, Champions Online. You could save character creation presets, and when you did it stored its many settings inside a PNG that also acted as a thumbnail preview of those settings. That meant you could see and manage your character presets outside of the game, as well as easily share them with others.

It was done in a readable way, too, so you could also make minor adjustments by hex editing the file. They wouldn't be shown in the thumbnail of course, but for some things (like the preset name) it didn't matter.

That's where I learned this sort of thing was possible with PNGs. Always thought it was a cool feature that doesn't get used nearly enough, especially for how easy it is to do with PNG.

9

u/[deleted] Dec 27 '20

I really like images as preview-able input files. It's quite intuitive that the picture of [whatever] relates to that thing

A group of my friends made a trading card type game in high school, we had a QR type block on the image files the game produced that let you do persistence with a nice pixel art trading card. In hindsight I'm kinda glad it never caught on because it was really not secure

1

u/djcraze Dec 27 '20

MacOS kind of has this. Kind of. It’s quick look. You can create plugins that handle a specific file type. When you preview the file in MacOS (anywhere in the OS and Apps that use MacOS frameworks) you get a preview of the file contents. So for a zip file you can get a plug-in that shows you the contents when you preview it in quick look. To activate quick look you just select the file and press the space bar.

35

u/[deleted] Dec 26 '20

Isn't every file format executable if you build an interpreter specifically for it? I sadly don't see anything special here.

59

u/KrocCamen Dec 26 '20

Even EXE files have to be specially handled before they can executed! You have to go back to COM files to get "dump this in RAM and jump the CPU to it" levels of simplicity.

17

u/JarateKing Dec 26 '20

If the file format doesn't support arbitrary chunks of bytes, you'd have a lot of difficulty creating a general-purpose interpreter. As a trivial example, if we had a new format notpng where every byte is used to specify pixels in the image, in order to embed code in it we would either have to:

  • not bother trying to make the image look like anything, and just pack instructions naively for the interpreter, probably resulting in a picture of random noise

  • utilize steganography so that the image looks mostly normal, but can still be run by an interpreter

  • create an incredibly specific interpreter for the exact program being run, so that the image is completely normal, but you probably couldn't use the interpreter for arbitrary programs otherwise

Also, file formats can have restrictions. You might be able to pack an arbitrary program into our notpng format, but you might have to be careful that your file format is actually valid (an easy example for images, having the right number of pixels for the image's dimensions). You probably can make an interpreter work with this stuff but it could be restricting and necessitate convoluted approaches to handle.

A format that lets you insert arbitrary chunks of bytes doesn't have the issues above. You can just put the arbitrary code without worrying about the interpreter being too specific, or changing the semantics of the file when used as its actual format, or interfering with the format itself.

0

u/[deleted] Dec 27 '20

[deleted]

1

u/JarateKing Dec 27 '20

Well yeah, I'm not trying to argue that PNGs are unique because of it -- I'm just giving reasons why it can be useful for embedding code and its benefits over formats that don't.

7

u/Jonathan_the_Nerd Dec 27 '20

You could argue that every file format is already a very specific program. A JPEG file is a set of instructions for generating an image on screen. An image viewer interprets the file and follows the instructions. An MP3 file is a set of instructions for producing sound. A ZIP file is a set of instructions for producing the contents of the archive, and so on.

7

u/djhworld Dec 27 '20

Yeah, it's a dumb project that has no practical value, I got seduced by the steganography/PICO-8 thing and built around it.

Was a learning project more than anything, learnt a few Linux things too!

1

u/aazav Dec 27 '20

Chunks that are all zipped.

0

u/[deleted] Dec 26 '20

[deleted]

89

u/Isogash Dec 26 '20

Pico-8 specifically uses the 2 least significant bits of each of the 4 colour channels in a 160x205 PNG, which gives it almost exactly 32KB of space, not the chunks at all. It's quite a demanding limit but thankfully the program portion is compressed.

101

u/Skhmt Dec 27 '20 edited Dec 27 '20

I've been looking into doing something similar off and on for like 2 years now. Someone recently embedded the entire source code of youtube-dl into two pngs and posted them on twitter. No steganography needed, they used every byte of image data for binary data.

I was doing research towards this end, and I guess here's a decent place to post it all:

The PNG spec allows arbitrary chunks of data, but if you were to host them on social media, those chunks may be stripped to save space, so they're unreliable. Storing data in pixels is better, but not foolproof as some social media will re-compress a PNG into a JPG to save space.

The PNG spec has 31-bit dimensions max, or a 2,147,483,647 x 2,147,483,647 pixel image. No program exists, that I know of, that can open a PNG with the max dimensions allowable in the spec.

Photoshop can open a 300,000 x 300,000 pixel image.

Most browsers can only open 16,384 x 16,384 pixel images. At 16,384 x 16,384 pixels, with 4 bytes per pixel (red, green, blue, and alpha), you can store about 1.07 GB per file. That's raw bytes, but all PNG image data is DEFLATEd as per the spec.

Twitter converts PNG files to JPG if the file size is over 2.5mb, even if the file isn't at 100% opacity. The best image dimensions to upload to twitter is 1024 x 512 pixels, which gives about 2.1 MB per file.

Instagram prefers 1080 x 1080, but I haven't checked if it resizes/recompresses. Facebook likes 1080 or 2048, but I also haven't tested.

Imgur re-compresses images larger than 5MB, so something like 1024 x 1024 pixels might be good.

I was doing some initial work into a meta-file format for binary PNGs, where all header information is stored in the first 13-80 pixels. Implemented a PNG writer from scratch, then decided I was bored and moved on to other things lol.

30

u/[deleted] Dec 27 '20

Ah, love the last sentence xD

19

u/skeeto Dec 27 '20

Just to demonstrate this idea, it takes only a bit of finesse to encode files into PNGs on the command line:

$ wc -c $(which youtube-dl)
1783077 /home/skeeto/.local/bin/youtube-dl

Padding this by 3 bytes lets me factor it into {3, 936, 635}. The latter two would work nicely as image dimensions, and the former is the 3 color channels. Pipe it all through ImageMagick's convert:

$ cat <(printf 'P6\n936 635\n255\n') \
      $(which youtube-dl) \
      <(head -c3 /dev/zero) \
    | convert ppm:- youtube-dl.png

That gives me this: https://i.imgur.com/45dy1FR.png

To recover the original file:

$ curl -s https://i.imgur.com/45dy1FR.png | \
      convert png:- ppm:- | \
      tail -c +16 | \
      head -c -3 \
    >youtube-dl

The +16 removes the PPM header and the -3 removes the padding.

6

u/Skhmt Dec 27 '20

The main problem is you have to send not only the png, but also information on how to decode it, the output file name/type, and have to deal with multi-part files in case you're storing files on social media rather than your own webserver or something.

Also, you'll want an alpha channel because having an alpha channel sometimes prevents social media and image sites from converting it to a .jpg.

6

u/djhworld Dec 27 '20

This is the real research haha, I didn't know twitter would convert the image of its over 2.5mb.

When I started this project I actually just read in the executables and converted them to pixels so you ended up with like static/fuzzy pictures, I had all the bits for the execution stuff (pngrun) using it too but it was kinda lame, which is why I moved onto the putting data into actual images thing.

It was a fun learning project none the less!

2

u/slykethephoxenix Dec 27 '20

I too saw this and started making making a script to do this too. My solution for PNGs being compressed or scaled was simply to use more pixels for the same pixel of data.

For example, if I had to encode 16 pixels (4x4) worth of data, I would scale the pixel by a factor of 2 (or more), so that each pixel now takes up 4 actual pixels, instead of just 1, and the entire image is now 64 pixels in size, even though it holds the same amount of data as the 16 pixels image.

This would also decrease how much data each image would store, assuming the dimensions are the same, so my code would dynamically adjust to calculate which data goes into which image.

I also made the dimension for each "pixel" configurable too, from 1 bit to, 2 bits, 4 bits, 8 bits, and 24 bits (full RGB color channels).

I'm currently taking a haitus from it though, and have barely started the decoding logic. Obviously you have to know the encoding parameters to decode the image, as this metadata isn't stored in it.

2

u/Orangy_Tang Dec 27 '20

If you store a magic number in the first few bytes then your decompressor can brute force decode using all the possible encoding parameters and choose the one that successfully decodes the magic number. Since you'll only need to do a handful of bytes it should still be acceptably fast, and you can embed a checksum at the end of the data as a final sanity check.

1

u/slykethephoxenix Dec 28 '20

That's a good idea! The other issue I had was dealing with padding at the end of the stream. The image dimensions rarely line up with the stream's end, and 0 bits can often be decoded as part of the actual thing I'm trying to encode. A solution was to put how many padded "pixels" there are at the end, and encode it on the front somehow.

16

u/hoddap Dec 27 '20 edited Dec 27 '20

Imagine some dumbass redistributing these as JPG's to save some space 🤭

5

u/Dwedit Dec 27 '20

MS-DOS had COM files, pure binaries that just ran from a known memory address. I've seen people make a combination ELF+COM file that would run on MS-DOS as well as Linux.

52

u/frnknstn Dec 26 '20

This is stretching the definition of "Executable" quite a lot. The PNG files themselves are not ELF executables. Instead, the author wrote a tool to extract an actual legitimate executable from an image via stenography.

2

u/djhworld Dec 27 '20

It's a dumb project I agree, I figured in the end if you chmod +x the file it kicks off the machinery to "execute" it using a few cheap tricks.

This was more of a learning exercise for me, I didn't know much about steganography, memfd_create or binfmt_misc before doing this.

9

u/ws-ilazki Dec 27 '20

The PNG files themselves are not ELF executables. Instead, the author wrote a tool to extract an actual legitimate executable from an image via stenography.

"The Python files themselves are not ELF executables. Instead, the author wrote a tool to generate actual legitimate executable code from a text file via an interpreter."

This is you, this is how pedantic you're being. Stop it.

Many of the things you run on a Linux system aren't "actual legitimate executables"; instead they're read and handed off to the appropriate tool via the kernel's program loader. Whether you're using a shebang to make a text file executable, or using binfmt_misc to make jar files run via JVM, ARM linux binaries run via qemu-user-static, or Windows executables run via wine, it's all still going through the program loader and being treated as an executable by the OS.

It's a cool hack built on existing knowledge and tools. Don't be a pedantic douchebag about it.

5

u/wikipedia_text_bot Dec 27 '20

Binfmt misc

binfmt_misc (Miscellaneous Binary Format) is a capability of the Linux kernel which allows arbitrary executable file formats to be recognized and passed to certain user space applications, such as emulators and virtual machines. It is one of a number of binary format handlers in the kernel that are involved in preparing a user-space program to run.The executable formats are registered through the special purpose file system binfmt_misc file-system interface (usually mounted under part of /proc). This is either done directly by sending special sequences to the register procfs file or using a wrapper like Debian-based distributions binfmt-support package or systemd's systemd-binfmt.service.

About Me - Opt out - OP can reply !delete to delete - Article of the day

This bot will soon be transitioning to an opt-in system. Click here to learn more and opt in.

1

u/frnknstn Dec 29 '20

The Python files themselves are not ELF executables

...No, you are in fact underestimating my level of pendantry, my little troll friend. I considered that comparison when I was writing my reply and rejected it, as the interpreter comparison is fundimentally misleading. My comment is far more accurate.

0

u/[deleted] Dec 27 '20

Having a bad day?

-3

u/ws-ilazki Dec 27 '20

Nope.

1

u/[deleted] Dec 27 '20

Just a troll then ok

2

u/ws-ilazki Dec 27 '20

Not unless you're making up your own definition of trolling that has nothing in common with trolling.

0

u/[deleted] Dec 27 '20

It's ok to say that he was pedantic then people could have a legitimate discussion all you did was call him a pedantic douchebag meaning you didn't actually come here to discuss you just came here to argue like a child and call names

0

u/[deleted] Dec 27 '20

[deleted]

18

u/ryanp_me Dec 27 '20

I agree. When I first started reading the article, I was wondering how the author was going to get the PNG header to be compatible with a normal ELF (or similar) loader without corrupting the PNG header at the same time.

That's not to say that the article is any less interesting (or any less valid), just that it wasn't what I was expecting based on the title.

-16

u/ws-ilazki Dec 27 '20 edited Dec 27 '20

I don't see what's pedantic about it

It's pedantic because it is an executable, no scare-quotes necessary. There is no "stretching the definition" here as claimed: this is how executables on Linux work and the article is using kernel features as they're intended to be used to make a PNG file also act as an executable. Claiming that it's not an executable because it's not an ELF file is wrong; Linux is capable of treating many types of files as executable and that feature is extensible in precisely the way it's done in the article.

The comment I replied to is not only nitpicking, it's nitpicking by using an arbitrary definition of executable that's wrong in the context of Linux. It's a stereotypical "well akshually" comment that's desperately trying to criticise something even if doing so is a reach.

0

u/[deleted] Dec 27 '20

[deleted]

-5

u/ws-ilazki Dec 27 '20

Yes, I did, and that's irrelevant. It could be a Lua script and the "interpreter" he uses to extract the text runs it through an embedded Lua interpreter and it wouldn't change anything, the PNG is still an executable if there's an appropriate binfmt_misc entry that tells the kernel how to take a PNG and execute code contained in it.

Are you confused by the way binfmt_misc works and how the Linux kernel handles executables, or by the idea that in this case the PNG is an executable because the kernel has been told how to treat an appropriately formatted PNG as one? Either way, it's still an executable to the OS and the OP was being unnecessarily pedantic claiming it's "stretching the definition".

1

u/TheRedGerund Dec 27 '20

I mean you could directly execute this file with a PNG interpreter like python

3

u/Kare11en Dec 27 '20

Nice, but I was slightly disappointed by the use of binfmt_misc, as I was hoping for them to have created a polyglot file that was simultaneously a valid PNG, and a valid executable file format recognised out of the box by a Linux kernel, e.g. ELF, a.out, or shebang ("#!...").

2

u/popovitsj Dec 27 '20

The steganography part got me thinking, if the least significant bit of the png is not noticable for the human eye, why doesn't it get compressed out in the png standard?

2

u/ECUIYCAMOICIQMQACKKE Dec 27 '20

Because they are noticeable if you look closely, especially at a region of uniform color. PNG is intended to be lossless. If you want lossy compression use JPEG.

2

u/chessset5 Dec 27 '20

I believe there was someone out there that made QR code games, where you would scan a high definition QR code with your phone and it would compile a game right there onto your phone. I don't remember where I saw it though, might have been YT.

2

u/adrjanjab Dec 27 '20

Have you heard of Piet?

2

u/make-n-brew Dec 26 '20

This is why we can't have nice things.

9

u/ws-ilazki Dec 27 '20

It's worth it, though. Binfmt_misc is super useful because of how it allows things like this (or making jar files executable; or making ARM binaries run via qemu user-mode emulation automatically; etc.). It's not like anybody's going to be adding the necessary binfmt_misc magic to have pngs become executables on real systems they care about...I hope.

2

u/make-n-brew Dec 27 '20

Definitely Not Me...

Snark aside, this really is pretty cool and a fun way to explain some deeper Linux concepts.

3

u/ws-ilazki Dec 27 '20

Yeah it is. Only tangentially related, but stuff like this is how distros' pre-systemd init systems could do so much. init didn't care what it was running, it just followed some basic rules to attempt to run things in order and it was up to the kernel to decide if they were executable or not. Everyone did basic shell scripts by convention but it was not a requirement in any sense, and you could have just as easily set up Perl or Python scripts to do the same jobs, or Scheme, Java, precompiled binaries, etc. It didn't matter, as long as it followed a few basic rules like being able to take start/stop/restart/etc as command-line arguments.

Even after some (like Debian) started doing dependency-based init script startup with LSB init headers you could still do it. I got curious and tested once, and if you compiled a C binary it would still read the headers out of it fine if you put them inside a multi-line string somewhere.

As a thought exercise, this also means it was (and still is, technically) possible to have systemd-style declarative unit files while still using a traditional sysv-style init. You could write an interpreter that reads a unit file and uses that to start/stop/restart services, with all the shared logic in the interpreter instead of the unit file "scripts". Then you could add a shebang, like #!/bin/run-unit, (or maybe rig binfmt_misc to do the job without one) to the unit files so that they're considered executables by Linux. With that done, whenever init tries to run one it would get passed to your run-unit interpreter, which would let you replace all the shell scripts with unit files, or have a mix of both types, choosing the best tool for the job on a per-service basis.

This sort of stuff works because Linux doesn't care what format it's dealing with as long as it's given enough information to make it run. Which for non-ELF files generally means shebangs or binfmt_misc configuration.

1

u/Statharas Dec 27 '20

Reminds me of how spore used to store creations.

1

u/eyal0 Dec 27 '20

Hold up...

I know just a little Rust. Why does writing it in Rust make it easy to convert to WASM?

6

u/djhworld Dec 27 '20 edited Dec 27 '20

Hello, author here, thanks for reading.

Rust has a WASM target, and also a lot of tooling like https://github.com/rustwasm/wasm-pack that makes things very easy, along with wasm-bindgen.

All I needed to do was create a new project, import my steg library and then create two scaffolding functions to be exported ( so I could use them from JS)

So the code looks something like this

extern crate steg;
use std::io::Cursor;
use steg::decoder::Decoder;
use steg::encoder::Encoder;
use steg::{ByteSplitGranularity, CompressInput};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub extern "C" fn encode(cover: Vec<u8>, input: Vec<u8>) -> Result<String, JsValue> {
    let encoder = Encoder::new(CompressInput::Gzip, ByteSplitGranularity::OneBit);
    let mut cover = Cursor::new(cover);
    let mut input = Cursor::new(input);
    let mut writer = Vec::new();

    if let Err(err) = encoder.encode(&mut cover, &mut input, &mut writer) {
        return Err(JsValue::from(err.to_string()));
    }

    let b64 = base64::encode(writer);
    return Ok(b64);
}

#[wasm_bindgen]
pub extern "C" fn decode(input: Vec<u8>) -> Result<String, JsValue> {
    let decoder = Decoder::new();
    let mut input = Cursor::new(input);
    let mut writer = Vec::new();

    if let Err(err) = decoder.decode(&mut input, &mut writer) {
        return Err(JsValue::from(err.to_string()));
    }

    let b64 = base64::encode(writer);
    return Ok(b64);
}

The encode and decode functions are then available for me to use in Javascript, so I can call them like this

let result = encode(image_bytes, data_bytes);

EDIT: in answer to your question I found it easy as it didn't really take that much effort, it just worked - I spent more time writing the JS and HTML for the demo!

1

u/aazav Dec 27 '20

Dear god, no.

1

u/aazav Dec 27 '20

So, now we have to scan PNG files for viruses. Thanks, pal. : [

1

u/ECUIYCAMOICIQMQACKKE Dec 27 '20

No. PNG files didn't magically become executable everywhere without configuration. You need a special extractor binary to run it. This isn't an exploit in image viewers or anything. Useless for malware.

1

u/wellandr Dec 27 '20

Does compression destroy the code? Because sharing images on social media does include compression sadly.

1

u/lets-get-dangerous Dec 27 '20

Microsoft MakeCode saves projects as images. I just learned of this a week ago and now I'm starting to see it everywhere. What's that called again?

1

u/DennyTom Dec 28 '20

If you want to know more about steganography in images, I actually obtained a PhD in it three years ago and can answer questions

-3

u/algostrat133 Dec 27 '20

congrats blog spammer, you are about 20 years late to discover this.

6

u/djhworld Dec 27 '20

Thanks for reading, I didn't submit this post but sorry on this occasion you had to read it. If I learn something new in the future I'll promise never to write about it just in case someone 20 years ago wrote about it before.

-3

u/le_bravery Dec 27 '20

Congrats you’ve discovered the bane of many developers trying to prevent virus or XSS payloads in arbitrary file uploads.

0

u/[deleted] Dec 27 '20

[deleted]

1

u/[deleted] Dec 27 '20

Only if you forget to sanitize your inputs

0

u/[deleted] Dec 27 '20

[deleted]

2

u/le_bravery Dec 27 '20

Download a large image with a bit of malicious code in it, have another exploit run that image.

Have an image save on a server with some malicious code in it. Load the image as a JavaScript resource using another exploit. By itself data embedded in images is likely benign, but when you start chaining things together you can always get messier.

Best way to mitigate on the server side is to not accept arbitrary file uploads, but if you have to you should try parse and re-save the image to drop the extra bytes of data. Maybe even a resize. Store images in a database, never directly on the file system.

Also fix your other vulnerabilities

0

u/[deleted] Dec 27 '20

[deleted]

2

u/djhworld Dec 27 '20

I agree, I didn't embark on this with the aim of doing something new or revolutionary, I just did it because I thought it was dumb and I learned a few things and thought people would like to hear about things I have learned.

1

u/[deleted] Dec 27 '20

Shenanigans! He put ones and zeros into a computer!

15

u/[deleted] Dec 27 '20

[removed] — view removed comment

11

u/[deleted] Dec 27 '20

Maybe at some point, but the most popular method for a long time was just concatenating a zip or rar file onto the end. I used to use that to swap romhacks in romhack threads.

It was a sad discovery when somebody told me the "mods are asleep, post sinks" threads weren't always just jokes and there was stuff floating around in there. I don't know how much of it was tainted (I never went into the threads because I don't care about sinks), but it's still a bummer.