# Work of week #4: Environment Variable and Set-UID Program Lab
## Task 1
- The first task is just to get to know basic environment variable visualization / manipulation commands, such as `env`, `printenv`, `export` and `unset`, where the last two are Bash internal commands.
```
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$ export TEST=123
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$ printenv TEST
123
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$ env | grep TEST
TEST=123
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$ unset TEST
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$ printenv TEST
[11/10/21]seed@VM:~/.../Environment_Variable_and_SetUID$
```
## Task 2
- By following the task's steps, we can conclude that the environment variables at the parent and the child processes are the same, which means that the child process inherits its environment variables from the parent process at the moment it is created with the call to fork().
```
seed@VM ~/D/s/c/E/Labsetup (master)> gcc myprintenv.c
seed@VM ~/D/s/c/E/Labsetup (master)> ./a.out > file1
seed@VM ~/D/s/c/E/Labsetup (master)> vim myprintenv.c
(using vim to comment printenv in child process and uncommenting it in parent process)
seed@VM ~/D/s/c/E/Labsetup (master)> gcc myprintenv.c
seed@VM ~/D/s/c/E/Labsetup (master)> ./a.out > file2
seed@VM ~/D/s/c/E/Labsetup (master)> diff file1 file2
seed@VM ~/D/s/c/E/Labsetup (master)>
```
## Task 3
The new program must get its environment variables explicitly through the `execve` call. As we saw from the task, if no environment variables are passed through the call, the program will not have access to them.
```
seed@VM ~/D/s/c/E/Labsetup (master)> gcc myenv.c
seed@VM ~/D/s/c/E/Labsetup (master)> ./a.out
seed@VM ~/D/s/c/E/Labsetup (master)> vim myenv.c
(editing myenv.c to, instead of sending NULL in the envp argument of execve, send the received environment variables)
seed@VM ~/D/s/c/E/Labsetup (master)> gcc myenv.c
seed@VM ~/D/s/c/E/Labsetup (master)> ./a.out
COLORTERM=truecolor
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
DESKTOP_SESSION=ubuntu
(...)
```
## Task 4
By using the `system()` call, the environment variables are passed to the program because it uses `execl` internally, which provides the environment variables to `execve` automatically.
```
seed@VM ~/D/s/c/E/Labsetup (master)> vim system_call.c
(creating the system call file, which calls the system() function to execute /usr/bin/env)
seed@VM ~/D/s/c/E/Labsetup (master)> gcc system_call.c
seed@VM ~/D/s/c/E/Labsetup (master)> ./a.out
GJS_DEBUG_TOPICS=JS ERROR;JS LOG
LESSOPEN=| /usr/bin/lesspipe %s
USER=seed
(...)
```
## Task 5
The environment variables are passed to the Set-UID child process. Surprisingly, however, the variable `LD_LIBRARY_PATH` doesn't seem to have been passed.
```
seed@VM ~/D/s/c/E/Labsetup (master)> vim print_env.c
(creating the c file that prints all of the environment variables)
seed@VM ~/D/s/c/E/Labsetup (master)> gcc print_env.c
seed@VM ~/D/s/c/E/Labsetup (master)> sudo chown root a.out
seed@VM ~/D/s/c/E/Labsetup (master)> sudo chmod 4755 a.out
(changed terminal from fish to bash)
[]seed@VM:~/.../Labsetup$ export PATH="/bin:/usr/bin"
[11/12/21]seed@VM:~/.../Labsetup$ printenv PATH
/bin:/usr/bin
[11/12/21]seed@VM:~/.../Labsetup$ export LD_LIBRARY_PATH="Mylibrarypath"
[11/12/21]seed@VM:~/.../Labsetup$ printenv LD_LIBRARY_PATH
Mylibrarypath
[11/12/21]seed@VM:~/.../Labsetup$ export MY_VAR_ANY="djksdfkjsdfkjhsdfkjh"
[11/12/21]seed@VM:~/.../Labsetup$ ./a.out | grep "MY_VAR_ANY\|LD_LIBRARY_PATH\|PATH"
MY_VAR_ANY=djksdfkjsdfkjhsdfkjh
PATH=/bin:/usr/bin
```
## Task 6
By creating an executable file called "ls" in the /home/seed directory, and adding that directory to the PATH environment variable, we were able to make the Set-UID process run that executable instead of the "real" ls. Furthermore, by checking the effective user id (by calling `geteuid()`), we found out that our "ls" was running with the root privilege.
```c
// Code of the executable file named "ls" in the /home/seed directory:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
printf("My malicious code!!\n");
if (geteuid() == 0) {
printf("I have root privilege!\n");
}
return 0;
}
```
```
[11/12/21]seed@VM:~/.../Labsetup$ vim ls_program.c
(creating the program that will call system("ls"))
[11/12/21]seed@VM:~/.../Labsetup$ gcc ls_program.c
[11/12/21]seed@VM:~/.../Labsetup$ sudo chown root ./a.out
[11/12/21]seed@VM:~/.../Labsetup$ sudo chmod 4755 ./a.out
[11/12/21]seed@VM:~/.../Labsetup$ sudo ln -sf /bin/zsh /bin/sh
[11/12/21]seed@VM:~/.../Labsetup$ export PATH=/home/seed:$PATH
[11/12/21]seed@VM:~/.../Labsetup$ ./a.out
My malicious code!!
I have root privilege!
[11/12/21]seed@VM:~/.../Labsetup$
```
## CTF - web
### Challenge 1
After visiting the contents of the web application we came into the conclusion that the frameworks and plugins being used were:
- Wordpress v5.8.1
- WooCommerce plugin v5.7.1
- Booster for WooCommerce plugin v5.4.3
The version of the Booster for WooCommerce was associated with an **authentication bypass** exploit. The flag for this CTF was the CVE associated the exploit: **flag{CVE-2021-34646}**.
### Challenge 2
The CVE stated the following:
```
Versions up to, and including, 5.4.3, of the Booster for WooCommerce
WordPress plugin are vulnerable to authentication bypass via the
process_email_verification function due to a random token generation weakness
in the reset_and_mail_activation_link function found in the ~/includes/class-
wcj-emails-verification.php file.
This allows attackers to impersonate users and trigger an email address
verification for arbitrary accounts, including administrative accounts, and
automatically be logged in as that user, including any site administrators.
This requires the Email Verification module to be active in the plugin and
the Login User After Successful Verification setting to be enabled, which it
is by default.
```
The vulnerable code is the following:
```php=
$code = md5(time());
$url = add_query_arg( 'wcj_verify_email', base64_encode(json_encode( array(
'id' => $user_id, 'code' => $code))), wc_get_page_permalink('myaccount')
);
```
This allowed anyone to request a password change for any user, given his username, since the generated code only depended on the time the request was received.
This way we requested a password change email for the **admin** user, calculated the code for the time the request was performed. With this we logged in as admin and were able to find **flag{9f86e8033975050cb63d0d85876445b4}**.
Code fixed in version 5.4.4:
```php=
$code = mb_strtoupper(strval(bin2hex(openssl_random_pseudo_bytes(16))));
$url = wp_nonce_url(add_query_arg( 'wcj_verify_email', base64_encode(
json_encode(array('id' => $user_id, 'code' => $code))),
wc_get_page_permalink('myaccount')));
```