How did this compromise the machine?
If you find yourself/coworkers fearlessly unzipping and untaring 3rd party archives on your linux system, you may want to give this a read. Im going to show a POC on how an infection can occur solely through archive extractions.
The main functionality I targeted is the directory structure creation upon “unzip” or “tar -xvf” command ..If we can get files to be written to other places instead, then we can own the machine via autostart locations.
First attempt was to modify zip file and fool it into dropping files/directories with special path characters (“../” or “/” “). This may get me outside the “current working directory jail”.
Unzip is wise to this, and carefully parses out these characters before unpacking to avoid files escaping the current working directory. I found unzip has two different sanitizer routines. One pulls out directory traversal patterns, and the other pulls out “out-of-range characters (0x00-0x1f)”. Seeing this, the next step was to attempt paths like “.\x04./” hoping it would pass the traversal sanitizer and then be normalized by the out-of-range sanitizer; finally becoming “../”. Nope, still caught it.
After messing more with this, env vars, etc – I realized instead of going backwards to get out of the directory jail, you should go forward. This means making symlinks.
If an attacker can compress a directory with symlinks, these symlinks can be dropped which point to sensitive paths, and zip artifacts can be configured to write to them, thus traversing outside the current working directory.
Using ZIP with symlinks works simply enough (using the –symlinks flag), but it rats you out when it comes time to unzip, here shows a message from “unzip” claiming it just made a symlink to /etc/init.d/
can we suppress this? I attempted some terminal tricks to try that. If we can get unzip to echo special characters, we can control the terminal via Terminal Control Sequences (ie echo -e “\x1b[0;31m”). Well, we got that pesky sanitizer that unzip uses (filters out chars < 0x1F). Can we bypass the sanitizer?
Above you can see a format string being assembled, (which happens to be the symlink creation message “notScary -> /etc/init.d/”). All the sprint_f messages I could find were preceeded with this sanitizer routine. (alternatively, one could try making a filename field longer than 0x4000 in the zip format, which the sanitizer will fall short on (since 0x4000 = MAX_LENGTH), although, there are careful checks before this that wont allow this long of zip filename fields.
The only sprintf call I found that does not check for sanitization is the filename passed to zip itself, and apparently, you can name files with raw hex in them on Linux. So we make a zip file with an embedded terminal code for blanking out the console ‘\x1bPn=6’
zip -r Pictures[www.freepics.com$(echo -e “\x1bPn=6”)].zip /ResourceFolder).
Which appears as on the filesystem. Regardless of the social engineering namestyle, running this through unzip, a terminal code will be executed (the ? mark is actually a \x1b character), since the sanitizer isnt ran on the filename itself. This blanks out the console, preventing any information being echoed about the unzip process. This zip can now drop files that wont be shown in the output…kinda cool
Lets shelve this one for a sec. I found tar is the best way to deliver symlinks since they are preserved and there is no message of symlinks being made. The below file structure would exploit this, and cause infection whether unzipped as root or not (.desktop files in the .gnome dir for example). These are all autostart locations, that can get code to be ran upon next login (or even sooner with a cron job – if root).
The events become:
- untar Downloaded.tar
- unzip Pictures.zip (or Pictures[www.freepics.com?Pn=6].zip)
At unzip, the untared softlinks are hit and malware is written to /etc/init.d or the user directories paths to hit the user auto start. Heres where the console disable comes into play. Unless the targeted user’s name is known, we cant get persistence if not unziped as root, since we dont know the home/user directory name. For this, we need to attempt relative traversals (../) until we get to the $USER dir and hit files like .ssh/.gnome or other interesting files. Some of these may look strange, especially .ssh file being written. With the console hack, output can be supressed
Whats more concerning than the social engineering aspects of this, is the general concept that one can escape CWD jails with unzip or untar. This could be an issue for many platforms which allow submitted zips – trusting that contents will be jailed. For example, Android, which unzips .APKs under a priviledged process (PackageManager)…but dont bother trying this one, already did – doesnt work 😉