<<< Date Index >>>     <<< Thread Index >>>

TWiki Remote Command Execution Vulnerability



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

  * TWikiRelease02Sep2004[2] -- TWiki20040902.zip
  * TWikiRelease01Sep2004[3] -- TWiki20040901.zip
  * TWikiRelease01Feb2003[4] -- TWiki20030201.zip
  * TWikiRelease01Dec2001[5] -- TWiki20011201.zip
  * TWikiRelease01Dec2000[6] -- TWiki20001201.zip

Not affected are:
  * Recent DakarReleases[7] (upcoming production release, soon)
  * TWikiRelease01Sep2004 patched with Florian Weimer's
    UncoordinatedSecurityAlert23Feb2005[8]


---++ 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: SecurityAlertExecuteCommandsWithSearch[9] and
UncoordinatedSecurityAlert23Feb2005[8]


---++ 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 TWikiRelease03Sep2004[1]
     * NOTE: If you are running an *unmodified*
       TWikiRelease02Sep2004[2], 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 UncoordinatedSecurityAlert23Feb2005[6] (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 (b4dp4nd4@xxxxxxxxx) for disclosing the issue
    to the twiki-security@xxxxxxxxxxxxxxxxxxxxx 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( $rev ) {
      $rev =~ s/r?1\.//go;  # cut 'r' and major
+      # Fix for Codev.SecurityAlertExecuteCommandsWithRev
+      $rev = $maxrev unless( $rev =~ s/.*?([0-9]+).*/$1/o );
      if( $rev < 1 )       { $rev = 1; }
      if( $rev > $maxrev ) { $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( $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; }
--- 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( $rev =~ s/.*?([0-9]+).*/$1/o );
            if( $rev < 1 )       { $rev = 1; }
            if( $rev > $maxrev ) { $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->param( 'rev' ) || "";
+    $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( ( $rev ) && ( $rev ne $topRev ) ) {


---+++ 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( $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; }
--- 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( $rev =~ s/.*?([0-9]+).*/$1/o );
            if( $rev < 1 )       { $rev = 1; }
            if( $rev > $maxrev ) { $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->param( 'rev' ) || "";
+    $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( ( $rev ) && ( $rev ne $topRev ) ) {


---+++ 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( $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; }
--- 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( $rev =~ s/.*?([0-9]+).*/$1/o );
            if( $rev < 1 )       { $rev = 1; }
            if( $rev > $maxrev ) { $rev = $maxrev; }
            $text= &wiki::readVersion( $topic, "1.$rev" );


---++ TWiki News

  * A new TWiki release is upcoming soon, code named DakarRelease[7]
  * To customize your TWiki installation, TWiki.org offers now
    177 Plugin packages[11], 56 Add-on packages[10], 30 Skin
    packages[12], and 11 TWiki contrib packages [13]
  * Codev.TWikiSecurityAlertProcess[14] documents our security
    process
  * Wikis and TWiki get covered more my the press[15]
  * TWiki is represented at the International Symposium on Wikis[16]
    in San Diego, 17-18 Oct 2005
  * A new book on Wikis in the Workplace is in work[17]

Best regards,
Peter


[1]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease03Sep2004
[2]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease02Sep2004
[3]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease01Sep2004
[4]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease01Feb2003
[5]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease01Dec2001
[6]:  http://twiki.org/cgi-bin/view/Codev/TWikiRelease01Dec2000
[7]:  http://twiki.org/cgi-bin/view/Codev/DakarReleases
[8]:  http://twiki.org/cgi-bin/view/Codev/UncoordinatedSecurityAlert23Feb2005
[9]:  http://twiki.org/cgi-bin/view/Codev/SecurityAlertExecuteCommandsWithSearch
[10]: http://twiki.org/cgi-bin/view/Plugins/AddOnPackage
[11]: http://twiki.org/cgi-bin/view/Plugins/PluginPackage
[12]: http://twiki.org/cgi-bin/view/Plugins/SkinPackage
[13]: http://twiki.org/cgi-bin/view/Plugins/ContribPackage
[14]: http://twiki.org/cgi-bin/view/Codev/TWikiSecurityAlertProcess
[15]: http://twiki.org/cgi-bin/view/Codev/TWikiInTheNews
[16]: http://twiki.org/cgi-bin/view/Codev/InternationalSymposiumOnWikis
[17]: http://twiki.org/cgi-bin/view/Codev/WikisInTheWorkplaceBook


--
  * Peter Thoeny                           Peter@xxxxxxxxxx
  * Is your team already TWiki enabled?    http://TWiki.org
  * This e-mail is:  (x) public  (_) ask first  (_) private

--- ../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 = "" 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 );
--- ../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( $rev ) {
      $rev =~ s/r?1\.//go;  # cut 'r' and major
+      # Fix for Codev.SecurityAlertExecuteCommandsWithRev
+      $rev = $maxrev unless( $rev =~ s/.*?([0-9]+).*/$1/o );
      if( $rev < 1 )       { $rev = 1; }
      if( $rev > $maxrev ) { $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>