Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:9731
HistorySep 15, 2005 - 12:00 a.m.

TWiki Remote Command Execution Vulnerability

2005-09-1500:00:00
vulners.com
7

This advisory alerts you of a potential security issue with your
TWiki installation: The TWiki history function allows arbitrary
shell command execution. The permanent place for this advisory is
http://twiki.org/cgi-bin/view/Codev/SecurityAlertExecuteCommandsWithRev .
Please see updates and follow-up on that topic.

If you do not use TWiki, please ignore this e-mail. If you don't
administer your TWiki site, or started a site now administered by
someone else, please pass it to the current TWiki site administrator.

Table of Contents:

  • Vulnerable Software Version
  • Attack Vectors
  • Impact
  • MITRE Name for this Vulnerability
  • Details
  • Countermeasures
  • Authors and Credits
  • Hotfix
    • Patch for TWiki Production Release 01-Sep-2004 and 02-Sep-2004
    • Patch for TWiki Production Release 01-Feb-2003
    • Patch for TWiki Production Release 01-Dec-2001
    • Patch for TWiki Production Release 01-Dec-2000
  • TWiki News

—++ Vulnerable Software Version

  • TWikiRelease02Sep20042 – TWiki20040902.zip
  • TWikiRelease01Sep20043 – TWiki20040901.zip
  • TWikiRelease01Feb20034 – TWiki20030201.zip
  • TWikiRelease01Dec20015 – TWiki20011201.zip
  • TWikiRelease01Dec20006 – TWiki20001201.zip

Not affected are:

  • Recent DakarReleases7 (upcoming production release, soon)
  • TWikiRelease01Sep2004 patched with Florian Weimer's
    UncoordinatedSecurityAlert23Feb20058

—++ Attack Vectors

HTTP GET requests towards the Wiki server (typically port 80/TCP).
Usually, no prior authentication is necessary.

Possibly also HTTP POST, but this is untested.

—++ Impact

An attacker is able to execute arbitrary shell commands with the
privileges of the web server process, such as user nobody.

—++ MITRE Name for this Vulnerability

The Common Vulnerabilities and Exposures project has assigned the
name CAN-2005-2877 to this vulnerability.

—++ Details

The TWiki revision control function uses a user supplied URL
parameter to compose a command line executed by the Perl backtick
(``) operator.

The URL parameter is not checked properly for shell metacharacters
and is thus vulnerable to revision numbers containing pipes and
shell commands. Exploit is possible on topics with two or more
revisions.

Example URL path with exploited rev parameter:
/cgi-bin/view/Main/TWikiUsers?rev=2%20%7Cless%20/etc/passwd

If access to TWiki is not restricted by other means, attackers can
use the revision function without prior authentication.

See Also: SecurityAlertExecuteCommandsWithSearch9 and
UncoordinatedSecurityAlert23Feb20058

—++ Countermeasures

  • Apply hotfix (see patches below)
    • NOTE: The hotfix is known to prevent the current attacks,
      but it might not be a complete fix
  • Upgrade to the latest patched production TWikiRelease03Sep20041
    • NOTE: If you are running an unmodified
      TWikiRelease02Sep20042, simply copy the patched
      lib/TWiki/Store.pm, lib/TWiki/UI/RDiff.pm,
      lib/TWiki/UI/View.pm and lib/TWiki/UI/Viewfile.pm to your
      installation
  • Apply patch of UncoordinatedSecurityAlert23Feb20056 (but see
    known issues of that patch)
  • Filter access to the web server
  • Use the web server software to restrict access to the web pages
    served by TWiki

—++ Authors and Credits

  • Credit to B4dP4nd4 ([email protected]) for disclosing the issue
    to the [email protected] mailing list
  • PeterThoeny, CrawfordCurrie, SvenDowideit, ColasNahaboo,
    WillNorris, RichardDonkin, B4dP4nd4 and Florian Weimer for
    contributing to this advisory

—++ Hotfix

—+++ Patch for TWiki Production Release 01-Sep-2004 and 02-Sep-2004

Affected files: =twiki/lib/TWiki/Store.pm=, =twiki/lib/TWiki/UI/RDiff.pm=,
=twiki/lib/TWiki/UI/View.pm=, =twiki/lib/TWiki/UI/Viewfile.pm=

See also attached patch file TWiki200409-02-03.patch

— lib/TWiki/Store.pm.orig Thu Jul 22 01:43:40 2004
+++ lib/TWiki/Store.pm Thu Sep 8 21:30:44 2005
@@ -572,7 +572,9 @@
}

$theRev = "" unless( $theRev );
  • $theRev =~ s/^1\.//o;
  • $theRev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $theRev = "" unless( $theRev =~ s/.?([0-9]+)./$1/o );
$topicHandler = _getTopicHandler( $theWebName, $theTopic,

$attachment ) if( ! $topicHandler );
my( $rcsOut, $rev, $date, $user, $comment ) =
$topicHandler->getRevisionInfo( $theRev );
— lib/TWiki/UI/RDiff.pm.orig Sun Aug 8 01:28:45 2004
+++ lib/TWiki/UI/RDiff.pm Thu Sep 8 21:33:13 2005
@@ -409,6 +409,9 @@
if( ! $rev2 ) { $rev2 = 0; }
$rev1 =~ s/r?1\.//go; # cut 'r' and major
$rev2 =~ s/r?1\.//go; # cut 'r' and major

  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev1 = $maxrev unless( $rev1 =~ s/.?([0-9]+)./$1/o );
  • $rev2 = $maxrev unless( $rev2 =~ s/.?([0-9]+)./$1/o );
    if( $rev1 < 1 ) { $rev1 = $maxrev; }
    if( $rev1 > $maxrev ) { $rev1 = $maxrev; }
    if( $rev2 < 1 ) { $rev2 = 1; }
    — lib/TWiki/UI/View.pm.orig Tue Aug 24 23:36:15 2004
    +++ lib/TWiki/UI/View.pm Thu Sep 8 21:34:52 2005
    @@ -107,6 +107,8 @@
if&#40; $rev &#41; {
  $rev =~ s/r?1&#92;.//go;  # cut &#39;r&#39; and major
  •  # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •  $rev = $maxrev unless&#40; $rev =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
    if&#40; $rev &lt; 1 &#41;       { $rev = 1; }
    if&#40; $rev &gt; $maxrev &#41; { $rev = $maxrev; }
    

    } else {
    — lib/TWiki/UI/Viewfile.pm.orig Fri May 28 23:51:35 2004
    +++ lib/TWiki/UI/Viewfile.pm Thu Sep 8 21:35:59 2005
    @@ -43,6 +43,9 @@

    my $fileName = $query->param( 'filename' );
    my $rev = $query->param( 'rev' ) || "";

  • $rev =~ s/r?1\.//o; # cut 'r' and major

  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev = "" unless( $rev =~ s/.?([0-9]+)./$1/o );

return unless TWiki::UI::webExists( $webName, $topic );

—+++ Patch for TWiki Production Release 01-Feb-2003

Affected files: =twiki/lib/TWiki/Store.pm=, =twiki/bin/rdiff=,
=twiki/bin/view=, =twiki/bin/viewfile=

— lib/TWiki/Store.pm.orig Sat Jan 4 17:36:56 2003
+++ lib/TWiki/Store.pm Thu Sep 8 23:10:58 2005
@@ -351,9 +351,11 @@
if( ! $theWebName ) {
$theWebName = $TWiki::webName;
}

  • $theRev =~ s/^1\.//o;
  • $theRev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $theRev = "" unless( $theRev =~ s/.?([0-9]+)./$1/o );
  • $topicHandler = _getTopicHandler( $theWebName, $theTopic,
    $attachment ) if( ! $topicHandler );
    my( $rcsOut, $rev, $date, $user, $comment ) =
    $topicHandler->getRevisionInfo( $theRev );

— bin/rdiff.orig Sat Feb 1 00:57:32 2003
+++ bin/rdiff Thu Sep 8 23:18:05 2005
@@ -155,6 +155,9 @@
if( ! $rev2 ) { $rev2 = 0; }
$rev1 =~ s/r?1\.//go; # cut 'r' and major
$rev2 =~ s/r?1\.//go; # cut 'r' and major

  •    # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •    $rev1 = $maxrev unless&#40; $rev1 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
    
  •    $rev2 = $maxrev unless&#40; $rev2 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
      if&#40; $rev1 &lt; 1 &#41;       { $rev1 = $maxrev; }
      if&#40; $rev1 &gt; $maxrev &#41; { $rev1 = $maxrev; }
      if&#40; $rev2 &lt; 1 &#41;       { $rev2 = 1; }
    

— bin/view.orig Thu Jan 30 00:21:25 2003
+++ bin/view Thu Sep 8 23:13:47 2005
@@ -123,6 +123,8 @@
writeDebug( "maxrev = $maxrev" );
if( $rev ) {
$rev =~ s/r?1\.//go; # cut 'r' and major

  •        # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •        $rev = $maxrev unless&#40; $rev =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
          if&#40; $rev &lt; 1 &#41;       { $rev = 1; }
          if&#40; $rev &gt; $maxrev &#41; { $rev = $maxrev; }
      } else {
    

— bin/viewfile.orig Sun Jan 5 00:36:54 2003
+++ bin/viewfile Thu Sep 8 23:14:54 2005
@@ -63,6 +63,9 @@
my $fileName = $query->param( 'filename' );

my $rev = $query-&gt;param&#40; &#39;rev&#39; &#41; || &quot;&quot;;
  • $rev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev = "" unless( $rev =~ s/.?([0-9]+)./$1/o );
    my $topRev = &TWiki::Store::getRevisionNumber( $webName, $topic,
    $fileName );
if&#40; &#40; $rev &#41; &amp;&amp; &#40; $rev ne $topRev &#41; &#41; {

—+++ Patch for TWiki Production Release 01-Dec-2001

Affected files: =twiki/bin/rdiff=, =twiki/bin/view=, =twiki/bin/viewfile=

— bin/rdiff.orig Tue Nov 13 18:59:02 2001
+++ bin/rdiff Thu Sep 8 23:51:50 2005
@@ -149,6 +149,9 @@
if( ! $rev2 ) { $rev2 = 0; }
$rev1 =~ s/r?1\.//go; # cut 'r' and major
$rev2 =~ s/r?1\.//go; # cut 'r' and major

  •    # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •    $rev1 = $maxrev unless&#40; $rev1 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
    
  •    $rev2 = $maxrev unless&#40; $rev2 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
      if&#40; $rev1 &lt; 1 &#41;       { $rev1 = $maxrev; }
      if&#40; $rev1 &gt; $maxrev &#41; { $rev1 = $maxrev; }
      if&#40; $rev2 &lt; 1 &#41;       { $rev2 = 1; }
    

— bin/view.orig Mon Dec 3 09:11:20 2001
+++ bin/view Thu Sep 8 23:52:57 2005
@@ -114,6 +114,8 @@
writeDebug( "maxrev = $maxrev" );
if( $rev ) {
$rev =~ s/r?1\.//go; # cut 'r' and major

  •        # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •        $rev = $maxrev unless&#40; $rev =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
          if&#40; $rev &lt; 1 &#41;       { $rev = 1; }
          if&#40; $rev &gt; $maxrev &#41; { $rev = $maxrev; }
      } else {
    

— bin/viewfile.orig Fri Oct 5 18:03:20 2001
+++ bin/viewfile Thu Sep 8 23:53:45 2005
@@ -62,6 +62,9 @@
my $fileName = $query->param( 'filename' );

my $rev = $query-&gt;param&#40; &#39;rev&#39; &#41; || &quot;&quot;;
  • $rev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev = "" unless( $rev =~ s/.?([0-9]+)./$1/o );
    my $topRev = &TWiki::Store::getRevisionNumber( $webName, $topic,
    $fileName );
if&#40; &#40; $rev &#41; &amp;&amp; &#40; $rev ne $topRev &#41; &#41; {

—+++ Patch for TWiki Production Release 01-Dec-2000

Affected files: =twiki/bin/rdiff=, =twiki/bin/view=

— bin/rdiff.orig Tue Nov 14 23:08:48 2000
+++ bin/rdiff Fri Sep 9 00:04:25 2005
@@ -139,6 +139,9 @@
if( ! $rev2 ) { $rev2 = 0; }
$rev1 =~ s/1\.//go; # cut major
$rev2 =~ s/1\.//go; # cut major

  •    # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •    $rev1 = $maxrev unless&#40; $rev1 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
    
  •    $rev2 = $maxrev unless&#40; $rev2 =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
      if&#40; $rev1 &lt; 1 &#41;       { $rev1 = $maxrev; }
      if&#40; $rev1 &gt; $maxrev &#41; { $rev1 = $maxrev; }
      if&#40; $rev2 &lt; 1 &#41;       { $rev2 = 1; }
    

— bin/view.orig Tue Nov 14 23:14:31 2000
+++ bin/view Fri Sep 9 00:05:10 2005
@@ -77,6 +77,8 @@
$maxrev =~ s/1\.//go; # cut major
if( $rev ) {
$rev =~ s/1\.//go; # cut major

  •        # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •        $rev = $maxrev unless&#40; $rev =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
          if&#40; $rev &lt; 1 &#41;       { $rev = 1; }
          if&#40; $rev &gt; $maxrev &#41; { $rev = $maxrev; }
          $text= &amp;wiki::readVersion&#40; $topic, &quot;1.$rev&quot; &#41;;
    

—++ TWiki News

  • A new TWiki release is upcoming soon, code named DakarRelease7
  • To customize your TWiki installation, TWiki.org offers now
    177 Plugin packages11, 56 Add-on packages10, 30 Skin
    packages12, and 11 TWiki contrib packages 13
  • Codev.TWikiSecurityAlertProcess14 documents our security
    process
  • Wikis and TWiki get covered more my the press15
  • TWiki is represented at the International Symposium on Wikis16
    in San Diego, 17-18 Oct 2005
  • A new book on Wikis in the Workplace is in work17

Best regards,
Peter

— …/TWiki20040902/lib/TWiki/Store.pm 2004-07-22 10:43:40.000000000 +0200
+++ lib/TWiki/Store.pm 2005-09-09 06:30:44.000000000 +0200
@@ -572,7 +572,9 @@
}

$theRev = &quot;&quot; unless&#40; $theRev &#41;;
  • $theRev =~ s/^1\.//o;
  • $theRev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $theRev = "" unless( $theRev =~ s/.?([0-9]+)./$1/o );
$topicHandler = _getTopicHandler&#40; $theWebName, $theTopic,

$attachment ) if( ! $topicHandler );
my( $rcsOut, $rev, $date, $user, $comment ) =
$topicHandler->getRevisionInfo( $theRev );
— …/TWiki20040902/lib/TWiki/UI/RDiff.pm 2004-08-08
10:28:45.000000000 +0200
+++ lib/TWiki/UI/RDiff.pm 2005-09-09 06:33:13.000000000 +0200
@@ -409,6 +409,9 @@
if( ! $rev2 ) { $rev2 = 0; }
$rev1 =~ s/r?1\.//go; # cut 'r' and major
$rev2 =~ s/r?1\.//go; # cut 'r' and major

  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev1 = $maxrev unless( $rev1 =~ s/.?([0-9]+)./$1/o );
  • $rev2 = $maxrev unless( $rev2 =~ s/.?([0-9]+)./$1/o );
    if( $rev1 < 1 ) { $rev1 = $maxrev; }
    if( $rev1 > $maxrev ) { $rev1 = $maxrev; }
    if( $rev2 < 1 ) { $rev2 = 1; }
    — …/TWiki20040902/lib/TWiki/UI/Viewfile.pm 2004-05-29
    08:51:35.000000000 +0200
    +++ lib/TWiki/UI/Viewfile.pm 2005-09-09 06:35:59.000000000 +0200
    @@ -43,6 +43,9 @@

my $fileName = $query->param( 'filename' );
my $rev = $query->param( 'rev' ) || "";

  • $rev =~ s/r?1\.//o; # cut 'r' and major
  • Fix for Codev.SecurityAlertExecuteCommandsWithRev

  • $rev = "" unless( $rev =~ s/.?([0-9]+)./$1/o );

return unless TWiki::UI::webExists( $webName, $topic );

— …/TWiki20040902/lib/TWiki/UI/View.pm 2004-08-25
08:36:15.000000000 +0200
+++ lib/TWiki/UI/View.pm 2005-09-09 06:34:52.000000000 +0200
@@ -107,6 +107,8 @@

if&#40; $rev &#41; {
  $rev =~ s/r?1&#92;.//go;  # cut &#39;r&#39; and major
  •  # Fix for Codev.SecurityAlertExecuteCommandsWithRev
    
  •  $rev = $maxrev unless&#40; $rev =~ s/.*?&#40;[0-9]+&#41;.*/$1/o &#41;;
    if&#40; $rev &lt; 1 &#41;       { $rev = 1; }
    if&#40; $rev &gt; $maxrev &#41; { $rev = $maxrev; }
    
    } else {
    — …/TWiki20040902/lib/TWiki.pm 2004-11-20 06:31:53.000000000 +0100
    +++ lib/TWiki.pm 2005-09-10 03:01:49.000000000 +0200
    @@ -154,7 +154,7 @@

===========================

TWiki version:

-$wikiversion = '02 Sep 2004 $Rev: 1742 $';
+$wikiversion = '03 Sep 2004 $Rev: 1742 $';

===========================

Key Global variables, required for writeDebug

— …/TWiki20040902/license.txt 2004-11-20 06:31:10.000000000 +0100
+++ license.txt 2005-09-10 03:04:46.000000000 +0200
@@ -1,4 +1,4 @@
-Copyright and License of TWiki, 02 Sep 2004
+Copyright and License of TWiki, 03 Sep 2004

TWiki (TM) is copyrighted (C) 1999-2004 by Peter Thoeny,
— …/TWiki20040902/readme.txt 2004-11-20 06:37:33.000000000 +0100
+++ readme.txt 2005-09-10 03:05:03.000000000 +0200
@@ -5,7 +5,7 @@
TWiki Distribution

-Version: 02 Sep 2004 $Rev: 1742 $
+Version: 03 Sep 2004 $Rev: 1742 $
Release type: Production release

This version is TWiki Release 01-Sep-2004 patched for
— …/TWiki20040902/TWikiDocumentation.html 2004-08-31
18:35:18.000000000 +0200
+++ TWikiDocumentation.html 2005-09-10 03:09:15.000000000 +0200
@@ -1,7 +1,7 @@
<html><head>
<title>TWikiDocumentation</title>
</head><body bgcolor="#ffffff">
-<h1><a name="TWiki_Reference_Manual_01_Sep_20"> </a><a
name="_TWiki_Reference_Manual_01_Sep_2"> </a> TWiki Reference Manual
(01 Sep 2004 $Rev: 1742 $) </h1>
+<h1><a name="TWiki_Reference_Manual_03_Sep_20"> </a><a
name="_TWiki_Reference_Manual_03_Sep_2"> </a> TWiki Reference Manual
(03 Sep 2004 $Rev: 1742 $) </h1>
<p />
<script type="text/javascript">
<!–
@@ -3816,7 +3816,7 @@
</li>
</ul>
<p />
-This version of TWiki - 01 Sep 2004 $Rev: 1742 $ - expands the
following variables (enclosed in <code><b>%</b></code> percent signs):
+This version of TWiki - 03 Sep 2004 $Rev: 1742 $ - expands the
following variables (enclosed in <code><b>%</b></code> percent signs):
<p />
<p />
<p />
@@ -4627,7 +4627,7 @@
<ul>
<li> Syntax: <code>%WIKIVERSION%</code>
</li>
-<li> Expands to: <code>01 Sep 2004 $Rev: 1742 $</code>
+<li> Expands to: <code>03 Sep 2004 $Rev: 1742 $</code>
</li>
<li> Related: <a class="twikiAnchorLink"
href="#VarPLUGINVERSION">PLUGINVERSION</a>, <a class="twikiAnchorLink"
href="#VarWIKITOOLNAME">WIKITOOLNAME</a>
</li>
@@ -9836,4 +9836,4 @@
</li>
</ul>
<p />
-</body></html>
\ No newline at end of file
+</body></html>