You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Environment variables and how to get them](#environment-variables-and-how-to-get-them)
7
+
-[Introduction](#introduction)
8
+
-[Why do we care](#why-do-we-care)
9
+
-[How they work](#how-they-work)
10
+
-[docker variables](#docker-variables)
11
+
-[How to get them](#how-to-get-them)
12
+
-[`printenv` - print all or part of environment](#printenv---print-all-or-part-of-environment)
13
+
-[`env` - print the environment or run a program in a modified environment](#env---print-the-environment-or-run-a-program-in-a-modified-environment)
14
+
-[`set` BUILTIN - show or set shell variables and functions](#set-builtin---show-or-set-shell-variables-and-functions)
15
+
-[`declare` / `typeset` BUILTINS - declare variables and/or give them attributes](#declare--typeset-builtins---declare-variables-andor-give-them-attributes)
16
+
-[ps](#ps)
17
+
-[/proc](#proc)
18
+
-[What next](#what-next)
19
+
-[References](#references)
6
20
7
21
## Introduction
8
-
> An **environment variable** is a named value that can be accessed and affect the way running processes will behave on a computer.
22
+
> An **environment variable** is a named value that can be accessed and affect the way running processes will behave on a computer.
9
23
> - wikipedia
10
24
11
25
Think of variables as symbolic names we give to values in order to avoid remembering them. Say you use the number `3.1415926535897932384626433` quite often, and unless you are a robot it is going to be hard to remember the entire number by heart. So you give a name this number `pi=3.1415926535897932384626433` and now whenever you want to use it you simply use the symbolic name `pi`, instead of the huge number sequence.
12
26
13
27
In this document we will outline the use of environment variables, how they can be accessed, manipulated and taking advantage of them for both offensive and defensive security engineers.
14
28
15
29
## Why do we care
16
-
So why are environment variables important from a security perspective?
30
+
So why are environment variables important from a security perspective?
17
31
18
-
It used to be (in the old days lol) that environment variables where visible by everyone and as a rule most developers didn't use them to hold sensitive information.
32
+
It used to be (in the old days lol) that environment variables where visible by everyone and as a rule most developers didn't use them to hold sensitive information.
19
33
However, as the adoption of environment variables grew, so was the need to start holding a bit more sensitive information. So the ability to hide the environment variables from other users and processes was added to some, if not all, UNIX and UNIX-like systems (such as Linux) and thus limiting their attack surface.
20
34
21
35
Now, we've moved into the container era, environment variables got a new meaning. Have a quick look at docker hub and you'll see millions of images that use environment variables that hold sensitive information. From username, passwords, encryption keys, authentication tokens, system keys, there is an image with an environment variable use to match any imagination...
@@ -48,8 +62,8 @@ $ echo $mystring
48
62
$
49
63
```
50
64
51
-
The same will happen if you open another terminal and try to access the variable. So why is that?
52
-
The variables have effect only on the current session. In order for a variable to be available on subsequent commands and sessions that are spawned from the existing one, we have to `export` them.
65
+
The same will happen if you open another terminal and try to access the variable. So why is that?
66
+
The variables have effect only on the current session. In order for a variable to be available on subsequent commands and sessions that are spawned from the existing one, we have to `export` them.
53
67
```bash
54
68
$ export mystring
55
69
$ bash
@@ -64,17 +78,17 @@ Understanding the concept of variable visibility is particularly important in si
64
78
65
79
_We will not go deep into docker specifics just as far as we need for understanding the variables._
66
80
67
-
Lets see an example with docker variables.
81
+
Lets see an example with docker variables.
68
82
```bash
69
-
$ docker run -it -e "myvar=myvalue" bash
83
+
$ docker run -it -e "myvar=myvalue" bash
70
84
root@envlab: / # echo $myvar
71
85
myvalue
72
-
root@envlab: / #
86
+
root@envlab: / #
73
87
```
74
88
75
89
One thing we notice is that this variable is exported
76
90
```bash
77
-
root@envlab: / # bash
91
+
root@envlab: / # bash
78
92
root@envlab: / # echo $myvar
79
93
myvalue
80
94
```
@@ -84,7 +98,7 @@ Even if we start a login bash the variable is still there
84
98
root@envlab: / # bash -l
85
99
4df007c4e761:/# echo $myvar
86
100
myvalue
87
-
4df007c4e761:/#
101
+
4df007c4e761:/#
88
102
```
89
103
90
104
Even if we change users and shell, the variable is still there
### `env` - print the environment or run a program in a modified environment
@@ -139,8 +153,8 @@ root@envlab: / #
139
153
140
154
2. Reset the environment and run `/usr/bin/env` to print the environment and see that its empty
141
155
```bash
142
-
root@envlab: / # env -i /usr/bin/env
143
-
root@envlab: / #
156
+
root@envlab: / # env -i /usr/bin/env
157
+
root@envlab: / #
144
158
```
145
159
146
160
3. Reset the environment and run `/usr/local/bin/bash`. What we get is the variables that bash defines by default
@@ -150,7 +164,7 @@ root@envlab: / # env
150
164
PWD=/
151
165
SHLVL=1
152
166
_=/usr/bin/env
153
-
root@envlab: / #
167
+
root@envlab: / #
154
168
```
155
169
156
170
4. Run bash with modified `$HOME` variable
@@ -168,7 +182,7 @@ _=/usr/bin/env
168
182
### `set` BUILTIN - show or set shell variables and functions
169
183
Without options, the name and value of each shell variable are displayed in a format that can be reused as input for setting or resetting the currently-set variables. Read-only variables cannot be reset.
170
184
171
-
This is a builtin command that is used to define and/or print shell specific variables and functions.
185
+
This is a builtin command that is used to define and/or print shell specific variables and functions.
172
186
173
187
Running just `set`, returns far more variables than before.
174
188
```bash
@@ -224,7 +238,7 @@ root@envlab: / # /bin/ash
224
238
HISTFILE='/root/.ash_history'
225
239
HOME='/root'
226
240
HOSTNAME='envlab'
227
-
IFS='
241
+
IFS='
228
242
'
229
243
LINENO=''
230
244
OPTIND='1'
@@ -240,7 +254,7 @@ _='/bin/sh'
240
254
_BASH_BASELINE='5.1'
241
255
_BASH_LATEST_PATCH='8'
242
256
_BASH_VERSION='5.1.8'
243
-
/ #
257
+
/ #
244
258
```
245
259
246
260
An added bonus of using `set` is that it also displays functions that may have been defined
@@ -253,15 +267,15 @@ _=set
253
267
_BASH_BASELINE=5.1
254
268
_BASH_LATEST_PATCH=8
255
269
_BASH_VERSION=5.1.8
256
-
mytest ()
257
-
{
270
+
mytest ()
271
+
{
258
272
ls
259
273
}
260
274
root@envlab: / # mytest
261
275
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
262
276
```
263
277
### `declare` / `typeset` BUILTINS - declare variables and/or give them attributes
264
-
Declare variables and/or give them attributes. If no names are given then display the values of variables. This command has the ability to display and manipulate variables as well as their attributes (eg. int, array, exported, etc).
278
+
Declare variables and/or give them attributes. If no names are given then display the values of variables. This command has the ability to display and manipulate variables as well as their attributes (eg. int, array, exported, etc).
265
279
266
280
Without arguments it operates just like `set`, displaying the shell and environment variables and functions
267
281
```bash
@@ -301,9 +315,9 @@ This is what the declare attributes mean
301
315
*`-u` When the variable is assigned a value, all lower-case characters are converted to upper-case
302
316
*`-x` Mark names for export to subsequent commands via the environment
303
317
304
-
For more details about the `declare` command check the `bash(1)` manual pages under the **SHELL BUILTIN COMMANDS** section.
318
+
For more details about the `declare` command check the `bash(1)` manual pages under the **SHELL BUILTIN COMMANDS** section.
305
319
306
-
The `typeset` command behaves very similar to `declare` and is mostly there for compatibility with other shells. However, `typeset` without options, returns all variables and builtin shell functions.
320
+
The `typeset` command behaves very similar to `declare` and is mostly there for compatibility with other shells. However, `typeset` without options, returns all variables and builtin shell functions.
307
321
308
322
### ps
309
323
The previous commands we saw all work on the current shell session, however many times we would like to see what environment variables were defined for an already running application, that may or may not have started by us.
@@ -346,13 +360,13 @@ As we can see, the first three processes belonging to the `root` and `sampleuser
346
360
### /proc
347
361
There is another way to get the environment from a running process and this is through `/proc`, the process information pseudo-filesystem.
348
362
349
-
The proc filesystem is a pseudo-filesystem which provides an interface to kernel data structures. It is commonly mounted at `/proc`, automatically by the system.
363
+
The proc filesystem is a pseudo-filesystem which provides an interface to kernel data structures. It is commonly mounted at `/proc`, automatically by the system.
350
364
351
365
The filesystem provides and easy query to query and manipulate kernel structures as if they were simple files. For every process on the system, there is a corresponding directory under `/proc/<pid>/` with the exported kernel information. The files located under that folder correspond to different types of kernel information, but the ones that is of interest to us is `environ` & `cmdline`
352
366
353
-
`/proc/[pid]/environ`: This file contains the **initial** environment that was set when the currently executing program was started via `execve(2).` The entries are separated by null bytes (`\0`), and there may be a null byte at the end. Thus, to print out the environment of process 1, you would do
367
+
`/proc/[pid]/environ`: This file contains the **initial** environment that was set when the currently executing program was started via `execve(2).` The entries are separated by null bytes (`\0`), and there may be a null byte at the end. Thus, to print out the environment of process 1, you would do
`/proc/[pid]/cmdline`: This read-only file holds the complete command line for the process, unless the process is a zombie. In the latter case, there is nothing in this file: that is, a read on this file will return 0 characters. The command-line arguments appear in this file as a set of strings separated by null bytes (`\0`), with a further null byte after the last string.
0 commit comments