Sandboxing
level 1
This challenge will chroot into a jail in /tmp/jail-XXXXXX. You will be able to easily read a fake flag file inside this jail, not the real flag file outside of it. If you want the real flag, you must escape. The only thing you can do in this challenge is read out one single file, as specified by the first argument to the program (argv[1]).
Let's look at the source code.
assert(chroot(jail_path) == 0);Notice that even though the jail has been set, the program did not change directory to / and put us in that jail.
That means we are effectively not in jail.
If we give it /flag as argv[1], it is interpreted as /tmp/jail/flag, which gives us the fake flag.
In order to get the real flag, we have to pass the relative address of the real /flag from /tmp/jail/.
$ /challenge/babyjail_level1 ../../flag The first .. escapes from the jail/ and second .. escapes from the /tmp/ directory.
level 2
You may open a specified file, as given by the first argument to the program (argv[1]). You may upload custom shellcode to do whatever you want.
We can use the shellcode that we wrote for Shellcode Injection.
We can compile the program using gdb.
Let's extract the .text section using objcopy.
Now we can send this code as STDIN.
Note that we are in the hacker directory.
The shellcraft module from pwn allows us to create a shellcode easily. You could also use this method.
However creating our own shellcode allows us to have more control over it.
level 3
You may open a specified file, as given by the first argument to the program (argv[1]). You may upload custom shellcode to do whatever you want.
On examining the code for this level, we can see that this time we have been put into the jail.
That means we cannot just ../../flag our way to getting the flag.
Fortunately, there is openat syscall in linux which takes as input a directory file descriptor and then the path of the file to be opened relative to the directory.
In our case, the dirfd will be 3, the first three being STDIN, STDERR and STDOUT.
The openat syscall would look something like this:
Note that I specified flag and not /flag because that would reference the file inside jail/.
The result of the openat syscall is a file descriptor.
We can check it's value in the practice mode using strace which traces every system call.
This result is stored in $rax as is the case with most syscall that return a value.
We can pass this shellcode to the challenge.
Note that / is our argv[1], which we are using as reference in openat.
Since this directory is opened before chroot() is executed it won't be in the jail.
level 4
Escape a chroot sandbox using shellcode, but this time only using the following syscalls: "openat", "read", "write", "sendfile".
We could very well use the previous level's code but let's try something new.
The sendfile command is a combination of the read and write system calls. It's also more efficient as it does not require data to be transferred to and from user space.
It takes the following arguments:
In our case the out_fd will be 1 for STDOUT.
Replace the read and write syscalls with the above code.
level 5
Escape a chroot sandbox using shellcode, but this time only using the following syscalls: "linkat", "open", "read", "write", "sendfile"
We can no longer use openat, but now we are allowed to use linkat.
It takes five arguments.
Using linkat we can create a hard link in /tmp/jail/ that points to the /flag file in root / directory.
A hard link is an entry that associate a name with a file.
This allows us to access /flag inside of /tmp/jail/ using a different name.
Note that linkat returns a value of 0 on success.
Now we can access /flag using /flag2.txt.
level 6
Escape a chroot sandbox using shellcode, but this time only using the following syscalls: "fchdir", "open", "read", "write", "sendfile".
The fchdir syscall works similar to chdir, the only difference is that it takes a file descriptor as argument.
So we can effectively just jump out of the jail/.
level 7
Last updated
Was this helpful?