Assuming that you can't reach the internet nor reboot the machine, how can I recover from
chmod -x chmod
?
Assuming that you can't reach the internet nor reboot the machine, how can I recover from
chmod -x chmod
?
1 - use a programming language that implements chmod
Ruby:
ruby -e 'require "fileutils"; FileUtils.chmod 0755, “chmod"'
Python:
python -c "import os;os.chmod('/bin/chmod', 0755)”
Perl:
perl -e 'chmod 0755, “chmod”'
Node.js:
require("fs").chmod("/bin/chmod", 0755);
C:
$ cat - > restore_chmod.c
#include <sys/types.h>
#include <sys/stat.h>
int main () {
chmod( "/bin/chmod", 0000755 );
}
^D
$ cc restore_chmod.c
$ ./a.out
2 - Create another executable with chmod
By creating an executable:
$ cat - > chmod.c
int main () { }
^D
$ cc chmod.c
$ cat /bin/chmod > a.out
By copying an executable:
$ cp cat new_chmod
$ cat chmod > new_chmod
3 - Launch BusyBox (it has chmod inside)
4 - Using Gnu Tar
Create an archive with specific permissions and use it to restore chmod:
$ tar --mode 0755 -cf chmod.tar /bin/chmod
$ tar xvf chmod.tar
Do the same thing but on the fly, not even bothering to create the file:
tar --mode 755 -cvf - chmod | tar xvf -
Open a socket to another machine, create an archive and restore it locally:
$ tar --preserve-permissions -cf chmod.tar chmod
$ tar xvf chmod.tar
Another possibility would be to create the archive regularly and then editing it to alter the permissions.
5 - cpio
cpio
allows you to manipulate archives; when you run cpio file
, after the first 21 bytes there are three bytes that indicate the file permissions; if you edit those, you're good to go:
echo chmod |
cpio -o |
perl -pe 's/^(.{21}).../${1}755/' |
cpio -i -u
6 - Dynamic loaders
/bin/ld.so chmod +x chmod
(actual paths may vary)
7 - /proc
wizardry (untested)
Step by step:
attrib
, ls -@
, etc.)sed
or something similar to alter the execution bit without the kernel realising itchmod +x chmod
once8 - Time Travel (git; yet untested)
First, let's make sure we don't get everything else in the way as well:
$ mkdir sandbox
$ mv chmod sandbox/
$ cd sandbox
Now let's create a repository and tag it to something we can go back to:
$ git init
$ git add chmod
$ git commit -m '1985'
And now for the time travel:
$ rm chmod
$ git-update-index --chmod=+x chmod
$ git checkout '1985'
There should be a bunch of git-based solutions, but I should warn you that you may hit a git script that actually tries to use the system's chmod
9 - Fighting Fire with Fire
It would be great if we could fight an Operating System with another Operating System. Namely, if we were able to launch an Operating System inside the machine and have it have access to the outer file system. Unfortunately, pretty much every Operating System you launch is going to be in some kind of Docker, Container, Jail, etc. So, sadly, that is not possible.
Or is it?
Here is the EMACs solution:
Ctrl+x b > *scratch*
(set-file-modes "/bin/chmod" (string-to-number "0755" 8))
Ctrl+j
10 - Vim
The only problem with the EMACs solution is that I'm actually a Vim kind of guy. When I first delved into this topic Vim didn't have a way to do this, but in recent years someone made amends with the universe, which means we can now do this:
vim -c "call setfperm('chmod', 'rwxrwxrwx') | quit"