---
# System prepended metadata

title: 02 Environment Variables and Attacks
tags: [攻防演練, 110-1, NTNU, CSIE, 選修]

---

# 02 Environment Variables and Attacks
NTNU 資安攻防演練
##### [Back to Note Overview](https://reurl.cc/XXeYaE)
##### [Back to Information Security: A Hands-on Approach](https://hackmd.io/z5PJjK7eTJ29YEhMjyAaCw)
<!-- {%hackmd @sophie8909/pink_theme %} -->
###### tags: `攻防演練` `110-1` `CSIE` `選修` `NTNU`
<!-- tag順序 [學校] [系 必選]  or  [學程 學程名(不含學程的 e.g. 大師創業)] [課程] [開課學期]-->

## Overview

- Environment Variables
- Attack Interfaces Caused by Environment Variables
- Attack via Dynamic Linker
- Attack via External Program
- Attack via Library
- Attack via Application Code
- Appendix

## Environment Variables

- An environment variable is a <font color=red> dynamic-named value </font> that can affect the way running processes will behave on a computer.
    - You can treat them as <font color=red> **systemwise configuration**</font>.
- By default, when a process is created, it **inherits** a <font color=blue> duplicate run-time environment of its parent process</font>, except for explicit changes made by the parent when it creates the child.
- You can use **env** to check the environment variables in your computer.

```c=
// First Method
#include <stdio.h>

int main(int argc, char *argv[], cahr *envp[]){
    int i = 0;
    
    while(envp[i] != NULL){
        printf("%s\n", envp[i]);
    }
    
    return 0;
}
```

- main() is called by <font color=red> __libc_start_main() </font> which you can find its definition in **glibc/csu/libc-start.c**. You can see how the environment variables are transfered.

```c=
// Second Method
#include <stdio.h>

// you can find it in glibc/posix/enviro.c
extern char **environ;    // also can get env
int main(){
    ...
}
```

```c=
// Third Method
#include <stdlib.h>

char *getenv(const char *name);
int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);
```

```c=
#include <unistd.h>

int execve( const char *pathname,
            char *const argv[],
            char *const envp[]);
```

- **execve()** is different to **fork()**. <font color=red> There is no new process when using **execve()**</font>.
- You can pass the envoronment variables through the third argument in **execve()**.

### shell variable

- A shell script is a computer program designed to be run by the shell, a command-line **interpreter**.
    - Since there are lots of shells, there are lots of grammars.
    - The most horrible part is that **they are similar** and therefore, it is hard to debug.
- Shell variables are interval variables maintained by the shell.

![](https://i.imgur.com/MsrNICY.png)

```shell=
$ strings /proc/$$/environ | grep LOGNAME
LOGNAME=seed
$ echo $LOGNAME
seed
$ LOGNAME=neokent
$ echo $LOGNAME
neokent
$ strings /proc/$$/environ | grep LOGNAME
LOGNAME=seed
$ unset LOGNAME
$ echo $LOGNAME

$ strings /proc/$$/environ | grep LOGNAME
LOGNAME=seed
```

- Since <font color=red> **env** is a child process </font> to shell, so you cannot observe the shell's environment variables through this command.
    - > $$ is the current shell's PID.

```shell=
$ strings /proc/$$/environ | grep LOGNAME
LOGNAME=seed
$ LOGNAME2=alice
$ export LOGNAME3=bob
$ env | grep LOGNAME
LOGNAME=seed
LOGNAME3=bob
$ strings /proc/$$/environ | grep LOGNAME
LOGNAME=seed
$ unset LOGNAME
$ env | grep LOGNAME
LOGNAME3=bob
```

## Attack Interfaces Caused by Environment Variables

- The environment variable is a kind of interface for the attacker to input some malicious (惡意的) data to your program.
- This path is hard to be noticed.
- Even worse, it is obvious that the user can **change the environment variables without root privilege**.

![](https://i.imgur.com/28krSAz.png)

- **Linker**: A linker is used to <font color=blue> **find** </font> the external libraries used by a program. The lookup place is determined by the <font color=red> environment variables</font>.
- **Library**: Most programs invoke functions from external libraries and they may use <font color=red> environment variables</font>.
- **External Program**: A program may invoke external programs and they may use <font color=red> environment variables</font>.
- **Application Code**: A program may use <font color=red> environment variables</font> in its code but the developer may not realize it.

## Attack via Dynamic Linker

- **Static Linking**:
    - At compile time, all required functions and variables are copied into a target application by a compiler, linker, producting an object file.
    - The executable is <font color=blue> self-contained </font>.
    - The executable's size is larger than dynamic linking file.
    - There will be no <font color=red> **dependency hell issus**</font>.
- **Dynamic Linking**:
    - A dynamic linker loads and links the shared libraries needed by an executable <font color=red> at run time</font>, by copying the content of libararies from persistent storage to RAM. filling jump tables and relocating pointers.
    - Save memory

```shell=
$ gcc -o hello_dynamic hello.c
$ gcc -static -o hello_static hello.c
$ ls -al hello*
-rw-rw-r-- 1 seed seed 79 Jun 29 11:17 hello.c
-rwxrwxr -x 1 seed seed 16696 Jun 29 11:17 hello_dynamic
-rwxrwxr -x 1 seed seed 871704 Jun 29 11:18 hello_static
$ ldd hello_static
not a dynamic executable
$ ldd hello_dynamic
linux -vdso.so.1 (0 x00007ffedc7dc000)
libc.so.6 => /lib/x86_64 -linux -gnu/libc.so.6 (0 x00007f517a38b000)
/lib64/ld-linux -x86 -64.so.2 (0 x00007f517a597000)
```

- <font color=blue> **LD_PRELOAD** </font>: This contains a list of shared libraries, which will be serached first by the dynamic linker.
- <font color=blue> **LD_LIBRARY_PATH** </font>: This contains a list of directories, where the dynamic linker will search.
- > These two variables can be set by the user.

```shell=
$ gcc mytest.c -o mytest
$ ldd mytest
linux -vdso.so.1 (0 x00007ffdb7fe3000)
libc.so.6 => /lib/x86_64 -linux -gnu/libc.so.6 (0 x00007fd7b96a1000)
/lib64/ld-linux -x86 -64.so.2 (0 x00007fd7b98ad000)
$ gcc -c mysleep.c
$ gcc -shared -o libmysleep.so mysleep.o
$ export LD_PRELOAD =./ libmysleep.so
$ ldd mytest
linux -vdso.so.1 (0 x00007fffd2b7d000)
./ libmysleep.so (0 x00007ff1e800f000)
libc.so.6 => /lib/x86_64 -linux -gnu/libc.so.6 (0 x00007ff1e7e0a000)
/lib64/ld-linux -x86 -64.so.2 (0 x00007ff1e801b000)
$ ./mytest
I am not sleeping !!
$ unset LD_PRELOAD
$ ./mytest    # sleep for a second
$
```

- <font color=purple> If a process's RUID and EUID are different, the dynamic linker will **ignore** LD_PRELOAD and LD_LIBRARY_PATH</font>.

```shell=
$ cp /usr/bin/env ./myenv
$ sudo chown root myenv
$ sudo chmod +s myenv
$ export LD_PRELOAD =./ libmysleep.so
$ export LD_LIBRARY_PATH =.
$ export LD_MYOWN=neokent
$ env | grep LD_
LD_PRELOAD =./ libmysleep.so
LD_MYOWN=neokent
LD_LIBRARY_PATH =.
$ ./myenv | grep LD_
LD_MYOWN=neokent
```

## Attack via External Program

- **system()**: The system() library function uses <font color=red> fork(2) </font> to create a child process that executes the shell command specified in command using execl(3) as follows: execl(<font color=blue>”/bin/sh”</font>, ”sh”, ”-c”, command, (char *) NULL);
- **execve()**: execve() executes the program referred to by pathname. This causes the program that is currently being run by <font color=red> the calling process to be replaced </font>with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.
- Conclusion: We should use **execve() family** instead of system().

## Attack via Library

- Example: A locale is a set of parameters that defines the user's language, region and any special variant preferences that the user wants to see in their user interface.
    - LANG
    - NLSPATH
    - $\cdots$
- User can not control a locale-based program's output