]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
{proxy,chpasswd}.cgi: Fix a remote code execution vulnerability
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 4 Apr 2016 15:41:30 +0000 (16:41 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 8 Apr 2016 14:54:53 +0000 (15:54 +0100)
Handcrafted requests with shell commands could be sent to these
CGI files and gain shell access as unprivileged user.

References: #11087

Reported-by: Yann Cam <yann.cam@gmail.com>
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
html/cgi-bin/chpasswd.cgi
html/cgi-bin/proxy.cgi

index ae9e6ec70b29bf47989b32d2ec820cb79e4f11b1..0a66062edbf63a3bb81a275e43e4926b73a2266d 100644 (file)
@@ -20,6 +20,7 @@
 ###############################################################################
 
 use CGI qw(param);
+use Apache::Htpasswd;
 use Crypt::PasswdMD5;
 
 $swroot = "/var/ipfire";
@@ -74,48 +75,25 @@ if ($cgiparams{'SUBMIT'} eq $tr{'advproxy chgwebpwd change password'})
                $errormessage = $tr{'advproxy errmsg password length 1'}.$proxysettings{'NCSA_MIN_PASS_LEN'}.$tr{'advproxy errmsg password length 2'};
                goto ERROR;
        }
-       if (! -z $userdb)
-       {
-               open FILE, $userdb;
-               @users = <FILE>;
-               close FILE;
 
-               $username = '';
-               $cryptpwd = '';
+       my $htpasswd = new Apache::Htpasswd("$userdb");
 
-               foreach (@users)
-               {
-                       chomp;
-                       @temp = split(/:/,$_);
-                       if ($temp[0] =~ /^$cgiparams{'USERNAME'}$/i)
-                       {
-                               $username = $temp[0];
-                               $cryptpwd = $temp[1];
-                       }
-               }
-       }
-       if ($username eq '')
-       {
+       # Check if a user with this name exists
+       my $old_password = $htpasswd->fetchPass($cgiparams{'USERNAME'});
+       if (!$old_password) {
                $errormessage = $tr{'advproxy errmsg invalid user'};
                goto ERROR;
        }
-       if (
-           !(crypt($cgiparams{'OLD_PASSWORD'}, $cryptpwd) eq $cryptpwd) &&
-           !(apache_md5_crypt($cgiparams{'OLD_PASSWORD'}, $cryptpwd) eq $cryptpwd)
-          )
-       {
+
+       # Reset password
+       if (!$htpasswd->htpasswd($cgiparams{'USERNAME'}, $cgiparams{'NEW_PASSWORD_1'},
+                       $cgiparams{'OLD_PASSWORD'})) {
                $errormessage = $tr{'advproxy errmsg password incorrect'};
                goto ERROR;
        }
-       $returncode = system("/usr/sbin/htpasswd -b $userdb $username $cgiparams{'NEW_PASSWORD_1'}");
-       if ($returncode == 0)
-       {
-               $success = 1;
-               undef %cgiparams;
-       } else {
-               $errormessage = $tr{'advproxy errmsg change fail'};
-               goto ERROR;
-       }
+
+       $success = 1;
+       undef %cgiparams;
 }
 
 ERROR:
index 6c4e2b05d1e2f1cbc99bd0551ab88950b5a1af51..1c9bb8724af3f1ef77add867317c03035f9ef0f7 100644 (file)
@@ -27,6 +27,7 @@
 #
 
 use strict;
+use Apache::Htpasswd;
 
 # enable only the following on debugging purpose
 #use warnings;
@@ -4134,7 +4135,9 @@ sub adduser
                close(FILE);
        } else {
                &deluser($str_user);
-               system("/usr/sbin/htpasswd -b $userdb $str_user $str_pass");
+
+               my $htpasswd = new Apache::Htpasswd("$userdb");
+               $htpasswd->htpasswd($str_user, $str_pass);
        }
 
        if ($str_group eq 'standard') { open(FILE, ">>$stdgrp");