Subject: Re: Possible mass bug filing: The possibility of attack with the help of symlinks in some Debian packages

From: "Dmitry E. Oboukhov" <[email-masked]>
Date: Wed, 20 Aug 2008 00:07:31 +0400

Package: lintian
Tags: patch, security
Severity: wishlist

Hello, lintan maintainers!
please, see full discussion in -devel:
    http://lists.debian.org/debian-devel/2008/08/msg00271.html
for example, see the bug
	http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=494648
	(if attacker makes symlink from /tmp/twiki to /etc/shadow, then
	 he takes full access to the system (when twiki installs or
	 upgrades))

Hi all!

I wrote the check script for the lintian package. This additional check
verifies the debian packages for the presents of the discussed bug.

Notes and additions are welcome.

patch has been placed in attache

PS: X11 also uses the /tmp/.X11-unix directory, which may  be  used  for
attacks, I don't known :(

but many scripts (in different packages) use /tmp/.X11-unix, if this  is
not a security problem, may be I must add ignoring for this directory in
the lintian script?

I don't known yet :(

DEO> This message about the error concerns a few packages  at  once.   I've
DEO> tested all the packages on my Debian mirror.  (post|pre)(inst|rm)  and
DEO> config scripts were tested.

DEO> In some packages I've discovered scripts with errors which may be used
DEO> by a user for damaging important system files.

DEO> For example if a script uses in its work a temp file which is  created
DEO> in /tmp directory, then every user can create symlink  with  the  same
DEO> name in this directory in order to  destroy  or  rewrite  some	system
DEO> file.

DEO> I set Severity into grave for  this  bug.   The  table	of  discovered
DEO> problems is below.
--
... mpd is off

. ''`. Dmitry E. Oboukhov
: :’  : [email-masked]
`. `~’ GPGKey: 1024D / F8E26537 2006-11-21
  `- 1B23 D4F8 8EC0 D902 0555  E438 AB8C 00CF F8E2 6537
--- checks/symlink_attack	1970-01-01 03:00:00.000000000 +0300
+++ checks/symlink_attack	2008-08-19 23:11:44.000000000 +0400
@@ -0,0 +1,114 @@
+# symlink_attack -- lintian check script -*- perl -*-
+#
+# Copyright (C) 2008 Dmitry E. Oboukhov <[email-masked]>
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package Lintian::symlink_attack;
+use strict;
+use Tags;
+
+# check file
+# 
+# the parameters:
+#   1. name of check file
+#   2. error template
+#   3. warning template
+sub check_file($$$)
+{
+	my ($file_name, $err_tmpl, $warn_tmpl)=@_;
+
+    open my $file, '<', $file_name
+        or die "Can not open file `$file_name': $!\n";
+
+    $file_name =~ s/^..// if $file_name =~ m{^\./};
+    $file_name =~ s{^debfiles/}{debian/};
+
+    # read begin of shebang
+    local $_;
+    return unless 10 == read $file, $_, 10;
+    return unless m{^#!\s*/};
+    seek $file, 0, 0;
+
+    $_ = <$file>;
+    return unless m{^#!\s*(?:/\S+){2,}};
+    
+    # read all file content
+    # (remove comments, join backslash-ended string)
+    $_ = join '', map { s/#.*/\n/; s/\\$//; $_ } readline $file;
+
+    # errors
+    my $errors_found;
+    if (m{>\s*/tmp/} or m{(?:^|[|\s])tee\s+(?:-\S+\s+)*/tmp/}m)
+    {
+        $errors_found=1;
+        tag $err_tmpl, "$file_name (pipe)";
+    }
+    
+    my @wh = m{(mount|mkdir|chown|chmod)\s[^;]*?/tmp/}g;
+    # remove dups
+    @wh = keys %{{ map {($_,0)} @wh }};
+    if (@wh)
+    {
+    	$errors_found=1;
+        tag $err_tmpl, "$file_name ($_)" for @wh;
+    }
+
+    # warnings
+    unless ($errors_found)
+    {
+        tag $warn_tmpl, $file_name if m{\s+/tmp/};
+    }
+}
+
+
+sub run 
+{
+	my ($package, $type)=(@_);
+
+    my @check_files;
+
+    # check maintainer scripts
+	if ($type eq 'source')
+	{
+	    @check_files=
+	        grep /(((pre|post)(inst|rm))|(config))(?:\.in)?$/,
+	            glob ('debfiles/*');
+	}
+	else
+	{
+	    @check_files=
+	        grep /(((pre|post)(inst|rm))|(config))$/, glob ('control/*');
+	}
+    check_file $_ => 'maint-scripts-uses-tmp-err', 
+        'maint-scripts-uses-tmp-warn' for @check_files;
+
+    # check binary all files in the package
+    if ($type eq 'binary')
+    {
+    	chdir 'unpacked';
+    	open my $dir, '-|', 'find -type f -executable'
+    	    or die "Can not start find: $!";
+    	while(<$dir>)
+    	{
+    		chomp;
+    	    check_file $_ => 'scripts-uses-tmp-err', 'scripts-uses-tmp-warn';
+    	}
+    	chdir '..';
+    }
+}
+
+1;
+
+# vim: syntax=perl ts=4 sw=4 expandtab
--- checks/symlink_attack.desc	1970-01-01 03:00:00.000000000 +0300
+++ checks/symlink_attack.desc	2008-08-19 21:42:08.000000000 +0400
@@ -0,0 +1,74 @@
+Check-Script: symlink_attack
+Author: Dmitry E. Oboukhov <[email-masked]>
+Abbrev: sa_check
+Type: binary, source
+Unpack-Level: 2
+Info: This script checks source and binaries for possible symlink attacks
+
+Tag: maint-scripts-uses-tmp-err
+Type: error
+Info: Some of maintainer's scripts use direct access to /tmp directory
+ Unsing of direct access to /tmp directory may lead to symlinks attacks.
+ .
+ For example if a script uses in its work a temp file which is  created in
+ /tmp directory, then every user can create symlink  with  the  same name
+ in this directory in order to  destroy  or  rewrite  some  system or user
+ file. Symlink attack may also lead not only to the data desctruction but
+ to denial of service as well.
+ .
+ Use commands mktemp(1) or tempfile(1) in your shell-scripts, or use perl
+ module File::Temp (perldoc File::Temp) in your perl-scripts.
+ .
+ Instead of 'mktemp /tmp/tmp.XXXXXX' use 'mktemp -t' command.
+ .
+ Remember that maintainer's scripts are started with root permissions.
+
+Tag: maint-scripts-uses-tmp-warn
+Type: warning
+Info: Some of maintainer's scripts use direct access to /tmp directory
+ Unsing of direct access to /tmp directory may lead to symlinks attacks.
+ .
+ For example if a script uses in its work a temp file which is  created in
+ /tmp directory, then every user can create symlink  with  the  same name
+ in this directory in order to  destroy  or  rewrite  some  system or user
+ file.  Symlink attack may also lead not only to the data desctruction but
+ to denial of service as well.
+ .
+ Use commands mktemp(1) or tempfile(1) in your shell-scripts, or use perl
+ module File::Temp (perldoc File::Temp) in your perl-scripts.
+ .
+ Instead of 'mktemp /tmp/tmp.XXXXXX' use 'mktemp -t' command.
+ .
+ Remember that maintainer's scripts are started with root permissions.
+
+Tag: scripts-uses-tmp-err
+Type: error
+Info: Some of package's scripts use direct access to /tmp directory
+ Unsing of direct access to /tmp directory may lead to symlinks attacks.
+ .
+ For example if a script uses in its work a temp file which is  created in
+ /tmp directory, then every user can create symlink  with  the  same name
+ in this directory in order to  destroy  or  rewrite  some  system or user
+ file. Symlink attack may also lead not only to the data desctruction but
+ to denial of service as well.
+ .
+ Use commands mktemp(1) or tempfile(1) in your shell-scripts, or use perl
+ module File::Temp (perldoc File::Temp) in your perl-scripts.
+ .
+ Instead of 'mktemp /tmp/tmp.XXXXXX' use 'mktemp -t' command.
+
+Tag: scripts-uses-tmp-warn
+Type: warning
+Info: Some of package's scripts use direct access to /tmp directory
+ Unsing of direct access to /tmp directory may lead to symlinks attacks.
+ .
+ For example if a script uses in its work a temp file which is  created in
+ /tmp directory, then every user can create symlink  with  the  same name
+ in this directory in order to  destroy  or  rewrite  some  system or user
+ file.  Symlink attack may also lead not only to the data desctruction but
+ to denial of service as well.
+ .
+ Use commands mktemp(1) or tempfile(1) in your shell-scripts, or use perl
+ module File::Temp (perldoc File::Temp) in your perl-scripts.
+ .
+ Instead of 'mktemp /tmp/tmp.XXXXXX' use 'mktemp -t' command.

---

From: Russ Allbery <[email-masked]>
Date: Tue, 19 Aug 2008 13:17:12 -0700

> verifies the debian packages for the presents of the discussed bug.

Lintian already checks for this.  If the current check is not sufficient
(which is certainly believable), it should be improved, rather than adding
a new, separate check.  See
possibly-insecure-handling-of-tmp-files-in-maintainer-script.

This, like various other checks, should be extended to more than just
maintainer scripts, which requires some additional infrastruture work on
the lintian script checking.

-- 
Russ Allbery ([email-masked])               <http://www.eyrie.org/~eagle/>