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...
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$ ```