WebSVN 2.3.2 Unproper Metacharacters Escaping exec () Remote
Commands Injection Vulnerability
Tested against: Microsoft Windows Server R2 SP2
PHP 5.3.6 VC9 with magic_quotes_gpc = off (default)
Apache 2.2.17 VC9
Introduction:
This is a very special vulnerabilty, given the incredibly high number
Of machines involved. This can be verified by submitting the following
Queries to Google:
"Powered by WebSVN * and Subversion"
"Powered by WebSVN 2.3.2 and Subversion"
House age url: http://websvn.tigris.org/
Description says:
"WebSVN offers a view onto your subversion repositories thats been designed
Reflect the Subversion methodology. You can view the log of any file or directory
And see a list of all the files changed, added or deleted in any given revision.
You can also view compare two versions of a file so as to see exactly what was
Changed in a participant revision.
Since its written using PHP, WebSVN is very portable and easy to install ."
Vulnerabilty:
Without prior authentication, if the allowDownload option is enabled
In config. php, meaning that a tarball download is allowed internal SS all
Repositories (not uncommon), an attacker can invoke the dl. php script
And passing a well formed path argument to execute arbitrary
Commands against the underlying operating system.
Vulnerable code:
Look at dl. php, lines 114-139:
...
} Else {
@ Unlink ($ tempDir );
Mkdir ($ tempDir );
// Create the name of the directory being archived
$ ArchiveName = $ path;
$ IsDir = (substr ($ archiveName,-1) = /);
If ($ isDir ){
$ ArchiveName = substr ($ archiveName, 0,-1 );
}
$ ArchiveName = basename ($ archiveName );
If ($ archiveName = ){
$ ArchiveName = $ rep-> name;
}
$ Plainfilename = $ archiveName;
$ ArchiveName. =. r. $ rev;
// Export the requested path from SVN repository to the temp directory
$ SvnExportResult = $ svnrep-> exportRepositoryPath ($ path, $ tempDir. DIRECTORY_SEPARATOR. $ archiveName, $ rev, $ peg );
If ($ svnExportResult! = 0 ){
Header (HTTP/1.x 500 Internal Server Error, true, 500 );
Error_log (svn export failed for:. $ archiveName );
Print svn export failed for ". xml_entities ($ archiveName ).".;
RemoveDirectory ($ tempDir );
Exit (0 );
}
...
Then look at exportRepositoryPath () function inside./include/svnlook. php, lines 879-896:
...
// {ExportDirectory
//
// Exports the directory to the given location
Function exportRepositoryPath ($ path, $ filename, $ rev = 0, $ peg = ){
$ Cmd = $ this-> svnCommandString (export, $ path, $ rev, $ peg) .. quote ($ filename); // <---------------
$ Retcode = 0;
ExecCommand ($ cmd, $ retcode); // <----------------------
If ($ retcode! = 0 ){
Global $ lang;
Error_log ($ lang [BADCMD].:. escape ($ cmd ));
}
Return $ retcode;
}
//}}}
...
Again look at execCommand () function inside./include/command. php, lines 107-123:
...
// {ExecCommand
Function execCommand ($ cmd, & $ retcode ){
Global $ config;
// On Windows machines, the whole line needs quotes round it so that its
// Passed to cmd.exe correctly
// Since php 5.3.0 the quoting seems to be done internally
If ($ config-> serverIsWindows & version_compare (PHP_VERSION, 5.3.0alpha) ===- 1 ){
$ Cmd = ". $ cmd."; // <------------ nonsense...
}
Return @ exec ($ cmd, $ tmp, $ retcode); // <------------------- boom
}
//}}}
...
Also, look at quote () inside./include/command. php:
...
// {Quote
//
// Quote a string to send to the command line
Function quote ($ str ){
Global $ config;
If ($