/* [ MEMDUMP: parsed (physical) memory dumping program -- version 1.0.0 ] * * parsed (physical) memory dumping program. intended for use in system * * (security) audits, and memory exploration. includes display of * * existing files, existing passwd entries, passwd comparisons/ * * decryptions, comparative environments, text display, existing shell * * commands, and display delaying. * * * * AUTHOR: * * v9/vade79 v9@fakehalo.deadpig.org. (fakehalo) * * * * COMPILE: * * linux: * * # gcc memdump.c -o memdump -lcrypt -DCRYPT_H * * solaris/irix: * * # gcc memdump.c -o memdump -DCRYPT_H * * bsd: * * # gcc memdump.c -o memdump * * * * NOTE: * * this program will most likely need gid=kmem, or root to run properly. * * as it is intended to be used in an administration fashion. * * * * memdump.c: program source code for memdump. (353l!800w!9677b) * **************************************************************************/ #ifdef CRYPT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #define _XOPEN_SOURCE #define VERSION "1.0.0" /* version value. */ #define DFL_DEVICE "/dev/mem" /* default memory device. */ #define MIN_LINELEN 4 /* point to parse/display lines. (4 >= chars) */ #define MIN_SENSCAN 4 /* point to assume is a sentences (4 >= " "'s) */ unsigned short foff=0; unsigned short idev=0; unsigned short igrp=0; unsigned short flelist=0; unsigned short pwdlist=0; unsigned short pwdmtch=0; unsigned short cmdlist=0; unsigned short envlist=0; unsigned short wrdlist=0; unsigned short encmtch=0; unsigned long delay=0; unsigned long offset[2]={0,0}; unsigned int lmin=MIN_LINELEN; unsigned int lspc=MIN_SENSCAN; unsigned char *device; unsigned char *grep; unsigned char *passwd; char *parm; void usage(void); void sighandler(int); unsigned short parameter(char *,int,unsigned int); unsigned short iswdigit(unsigned char *); void dumpmem(void); void stringhandler(unsigned char *); void printe(unsigned char *,unsigned short); void printg(unsigned char *); void usage(void){ printf("-f show existing files/dirs\t\t-p show existing passwd entries\n" "-c show existing shell cmds\t\t-e show comparative environments\n" "-x extended passwd decryption (-P)\t-w check for text/sentences\n\n" "-D alternate memory device/file (/dev/mem=default)\n" "-o offset in memory to start dumping (non-zero)\n" "-g only display matching text, inside the memory string\n" "-m minimum number of characters to process (4=default)\n" "-d delay (in useconds) time between display\n" "-P match encrypted passwd against local crypt()\n" "-W alternate number of spaces to scan for (-w/4=default)\n" "\nnote: all functions have the potential for informational errors.\n" "memdump/v%s: vade79/v9@fakehalo.deadpig.org.\n",VERSION); exit(0); } void sighandler(int sig){ if(sig==SIGINT) printe("canceled dump.",0); exit(0); } unsigned short parameter(char *str,int i,unsigned int sep){ unsigned int j=0; unsigned int k=0; unsigned int r=0; char *buf; if(!(buf=(char *)malloc(strlen(str)+1))) printe("allocation of memory.",1); bzero(buf,(strlen(str)+1)); if(i<0) r=1; else for(j=0;j0) r=1; free(parm); if(!(parm=(char *)strdup(buf))) printe("duplication of memory.",1); bzero(buf,strlen(buf)); free(buf); return(r); } unsigned short iswdigit(unsigned char *str){ unsigned int i=0; for(i=0;str[i];i++){ if(!isdigit((unsigned int)str[i])) return(0); } return(strlen(str)?1:0); } void dumpmem(void){ unsigned int chr=0; unsigned int ssize=0; FILE *rd; unsigned char *string; if(!(rd=fopen(device,"r"))) printe("could not open memory device. (check existence/permissions)",1); else{ if(offset[0]){ if(fseek(rd,offset[0],SEEK_SET)) printe("offset failed",1); } if(!(string=(char *)malloc(1))) printe("allocation of memory.",1); while((chr=fgetc(rd))!=EOF){ if((offset[0]+1)<=offset[0]) offset[1]++; offset[0]++; if(!foff) foff=1; if(chr>0x19&&chr<0x7F&&isprint((unsigned int)chr)){ string[ssize++]=chr; if(!(string=(char *)realloc((char *)string,(ssize+1)))) printe("(re)allocation of memory.",1); } else if(!chr||chr==0x0A){ if(ssize){ string[ssize]=0x0; if(strlen(string)>=lmin) stringhandler(string); } bzero(string,strlen(string)); free(string); if(!(string=(char *)malloc(1))){ printe("allocation of memory.",1); exit(1); } ssize=0; } else if(ssize){ bzero(string,strlen(string)); free(string); if(!(string=(char *)malloc(1))) printe("allocation of memory.",1); ssize=0; } } } printe("dump finished.",0); return; } void stringhandler(unsigned char *str){ unsigned short icmd=0; unsigned short ndmp=0; unsigned int i=0; unsigned int j=0; char *tmppath; struct stat mod; if(flelist){ ndmp=1; if(!access(str,F_OK)) printg(str); } if(pwdlist){ ndmp=1; for(i=0;i5&&j<9&&!parameter(str,0,0x3A)&&getpwnam(parm)&&!parameter(str,2, 0x3A)&&iswdigit(parm)&&!parameter(str,3,0x3A)&&iswdigit(parm)) printg(str); } if(pwdmtch){ ndmp=1; if(pwdmtch==1){ if(!strcmp((char *)crypt(str,passwd),passwd)) printg(str); } else{ for(j=i=0;!parameter(str,j++,0x20);i++){ if(!strcmp((char *)crypt(parm,passwd),passwd)) printg(str); } } } if(cmdlist){ ndmp=1; if((str[0]==0x2F||(str[0]==0x2E&&str[1]==0x2F))&&!parameter(str,0,0x20)&& !stat(parm,&mod)&&(S_IXUSR&mod.st_mode||S_IXGRP&mod.st_mode||S_IXOTH& mod.st_mode)&&!(S_IFDIR&mod.st_mode)) icmd=1; else{ while(!parameter((char *)getenv("PATH"),i++,0x3A)){ if(!(tmppath=(char *)strdup(parm))) printe("duplication of memory.",1); if(!parameter(str,0,0x20)){ if(!(tmppath=(char *)realloc((char *)tmppath,(strlen(tmppath)+ strlen(parm)+2)))) printe("(re)allocation of memory.",1); strcat(tmppath,"/"); strcat(tmppath,parm); if(strlen(parm)&&isalnum((unsigned int)parm[0])&&!stat(tmppath,&mod)&& (S_IXUSR&mod.st_mode||S_IXGRP&mod.st_mode||S_IXOTH&mod.st_mode)&& !(S_IFDIR&mod.st_mode)) icmd=1; } bzero(tmppath,strlen(tmppath)); free(tmppath); if(icmd) break; } } if(icmd){ printg(str); icmd=0; } } if(envlist){ ndmp=1; if(!parameter(str,0,0x3D)&&getenv(parm)&&!parameter(str,1,0x3D)) printg(str); } if(wrdlist){ ndmp=1; for(j=i=0;i=lspc) printg(str); } if(!ndmp) printg(str); return; } void printe(unsigned char *str,unsigned short err){ printf("%s(%lu+%.10lu): %s\n",(err?"error":"warning"),offset[1],(foff?( offset[0]-strlen(str)):0),str); if(err) exit(1); return; } void printg(unsigned char *str){ if(!(igrp&&!strstr(str,grep))&&strlen(str)){ printf("%lu+%.10lu: %s\n",offset[1],(offset[0]-strlen(str)),str); if(delay) usleep(delay); } return; } int main(int argc,char **argv){ int opt=0; extern char *optarg; if(argc>1&&!strcmp(argv[1],"--help")) usage(); signal(SIGINT,sighandler); while((opt=getopt(argc,argv,"D:g:P:d:m:W:o:fpxcew"))!=EOF){ switch(opt){ case 'D': if(idev){ bzero(device,strlen(device)); free(device); } if(!(device=(char *)strdup(optarg))) printe("duplication of memory.",1); idev=1; break; case 'g': if(igrp){ bzero(grep,strlen(grep)); free(grep); } if(!(grep=(char *)strdup(optarg))) printe("duplication of memory.",1); igrp=1; break; case 'P': if(pwdmtch){ bzero(passwd,strlen(passwd)); free(passwd); } if(!(passwd=(char *)strdup(optarg))) printe("duplication of memory.",1); pwdmtch=1; break; case 'd': delay=atoi(optarg); break; case 'm': lmin=atoi(optarg); break; case 'W': lspc=atoi(optarg); break; case 'o': offset[0]=atol(optarg); break; case 'f': flelist=(flelist?0:1); break; case 'p': pwdlist=(pwdlist?0:1); break; case 'x': pwdmtch=(pwdmtch?2:0); break; case 'c': cmdlist=(cmdlist?0:1); break; case 'e': envlist=(envlist?0:1); break; case 'w': wrdlist=(wrdlist?0:1); break; default: usage(); break; } } if(!idev){ if(!(device=(char *)strdup(DFL_DEVICE))) printe("duplication of memory.",1); } dumpmem(); exit(0); }