step 1 complete :DDD
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
 | 
			
		||||
lab1/login_linux
 | 
			
		||||
 | 
			
		||||
lab1/mylogin
 | 
			
		||||
							
								
								
									
										10
									
								
								lab1/Makefile
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								lab1/Makefile
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
all: login_linux
 | 
			
		||||
 | 
			
		||||
mylogin: mylogin.c pwent.h pwent.c
 | 
			
		||||
	gcc -g -Wall pwent.c mylogin.c -lcrypt -o mylogin
 | 
			
		||||
 | 
			
		||||
login_linux: login_linux.c pwent.h pwent.c
 | 
			
		||||
	gcc -g -Wall pwent.c login_linux.c -lcrypt -o login_linux
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o mylogin login_linux
 | 
			
		||||
							
								
								
									
										95
									
								
								lab1/login_linux.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										95
									
								
								lab1/login_linux.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/* $Header: https://svn.ita.chalmers.se/repos/security/edu/course/computer_security/trunk/lab/login_linux/login_linux.c 585 2013-01-19 10:31:04Z pk@CHALMERS.SE $ */
 | 
			
		||||
 | 
			
		||||
/* gcc -std=gnu99 -Wall -g -o mylogin login_linux.c -lcrypt */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdio_ext.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <crypt.h>
 | 
			
		||||
#include <shadow.h>
 | 
			
		||||
#include "pwent.h" /* Step 2 */
 | 
			
		||||
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#define LENGTH 16
 | 
			
		||||
 | 
			
		||||
void sighandler() {
 | 
			
		||||
 | 
			
		||||
	/* add signalhandling routines here */
 | 
			
		||||
	/* see 'man 2 signal' */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
 | 
			
		||||
	struct passwd *passwddata; /* this has to be redefined in step 2 */
 | 
			
		||||
	/* see pwent.h */
 | 
			
		||||
	struct spwd *shadowpasswddata; /* this has to be redefined in step 2 */
 | 
			
		||||
	/* see pwent.h */
 | 
			
		||||
 | 
			
		||||
	char important1[LENGTH] = "**IMPORTANT 1**";
 | 
			
		||||
 | 
			
		||||
	char user[LENGTH];
 | 
			
		||||
 | 
			
		||||
	char important2[LENGTH] = "**IMPORTANT 2**";
 | 
			
		||||
 | 
			
		||||
	//char   *c_pass; //you might want to use this variable later...
 | 
			
		||||
	char prompt[] = "password: ";
 | 
			
		||||
	char *user_pass;
 | 
			
		||||
 | 
			
		||||
	sighandler();
 | 
			
		||||
 | 
			
		||||
	while (TRUE) {
 | 
			
		||||
		/* check what important variable contains - do not remove, part of buffer overflow test */
 | 
			
		||||
		printf("Value of variable 'important1' before input of login name: %s\n",
 | 
			
		||||
				important1);
 | 
			
		||||
		printf("Value of variable 'important2' before input of login name: %s\n",
 | 
			
		||||
				important2);
 | 
			
		||||
 | 
			
		||||
		printf("login: ");
 | 
			
		||||
		fflush(NULL); /* Flush all  output buffers */
 | 
			
		||||
		__fpurge(stdin); /* Purge any data in stdin buffer */
 | 
			
		||||
 | 
			
		||||
		if (gets(user) == NULL) /* gets() is vulnerable to buffer */
 | 
			
		||||
			exit(0); /*  overflow attacks.  */
 | 
			
		||||
 | 
			
		||||
		/* check to see if important variable is intact after input of login name - do not remove */
 | 
			
		||||
		printf("Value of variable 'important 1' after input of login name: %*.*s\n",
 | 
			
		||||
				LENGTH - 1, LENGTH - 1, important1);
 | 
			
		||||
		printf("Value of variable 'important 2' after input of login name: %*.*s\n",
 | 
			
		||||
		 		LENGTH - 1, LENGTH - 1, important2);
 | 
			
		||||
 | 
			
		||||
		user_pass = getpass(prompt); //enter password using deprecated function :/
 | 
			
		||||
		//passwddata = getpwnam(user); //get user info from /etc/passwd /* Step 1 */
 | 
			
		||||
 | 
			
		||||
		if (passwddata != NULL) {
 | 
			
		||||
			/* You have to encrypt user_pass for this to work */
 | 
			
		||||
			/* Don't forget to include the salt */
 | 
			
		||||
			shadowpasswddata = getspnam(user); //get encrypted password from /etc/shadow
 | 
			
		||||
			//printf("password in shadow file: %s \n", shadowpasswddata->sp_pwdp);
 | 
			
		||||
 | 
			
		||||
			char *user_pass_encrypted = crypt(user_pass, shadowpasswddata->sp_pwdp);
 | 
			
		||||
			//printf("encryption of typed pass: %s \n", user_pass_encrypted);
 | 
			
		||||
			// schulze:
 | 
			
		||||
			// $6
 | 
			
		||||
			// $Dvon03J3/yxkUTWF$
 | 
			
		||||
			// JiIGRAV22.iMUOMPW9MJidTt.aPsKOYK4Bx.Av5EMcVmifp1SkhRELWHLKPWCGmv3nhcFk7tgi7/9.YCO/C
 | 
			
		||||
			//schulze:$6$Dvon03J3/yxkUTWF$JiIGRAV22.iMUOMPW9MJidTt.aPsKOYK4Bx.Av5EMcVmifp1SkhRELWHLKPWCGmv3nhcFk7tgi7/9.YCO/CnS/:18577:0:99999:7:::
 | 
			
		||||
 | 
			
		||||
			if (!strcmp(user_pass_encrypted, shadowpasswddata->sp_pwdp)) {
 | 
			
		||||
 | 
			
		||||
				printf(" You're in !\n");
 | 
			
		||||
 | 
			
		||||
				/*  check UID, see setuid(2) */
 | 
			
		||||
				/*  start a shell, use execve(2) */
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		printf("Login Incorrect \n");
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								lab1/makepass.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								lab1/makepass.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/* $Header: https://svn.ita.chalmers.se/repos/security/edu/course/computer_security/trunk/lab/login_linux/makepass.c 584 2013-01-19 10:30:22Z pk@CHALMERS.SE $ */
 | 
			
		||||
 | 
			
		||||
/* makepass.c - Make a UNIX password */
 | 
			
		||||
/* compile with: gcc -o makepass makepass.c -lcrypt */
 | 
			
		||||
/* usage: "makepass 'salt'" */
 | 
			
		||||
 | 
			
		||||
#include <crypt.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include  <unistd.h>
 | 
			
		||||
 | 
			
		||||
int is_salt(char *salt) {
 | 
			
		||||
	char salts[] =
 | 
			
		||||
			"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
 | 
			
		||||
 | 
			
		||||
	return strlen(salt) == 2 && strchr(salts, salt[0]) != 0
 | 
			
		||||
			&& strchr(salts, salt[1]) != 0 && salt[0] != '\0' && salt[1] != '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]) {
 | 
			
		||||
	char *clear;
 | 
			
		||||
	char clear1[9];
 | 
			
		||||
	char *clear2;
 | 
			
		||||
 | 
			
		||||
	if (argc != 2) {
 | 
			
		||||
		fprintf(stderr, "Usage: %s salt\n", argv[0]);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!is_salt(argv[1])) {
 | 
			
		||||
		fprintf(stderr, "(%s) is illegal salt!\n", argv[1]);
 | 
			
		||||
		return 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clear = getpass("Password: ");
 | 
			
		||||
	if (clear == NULL) {
 | 
			
		||||
		bzero(clear, 8);
 | 
			
		||||
		fprintf(stderr, "Not a tty!");
 | 
			
		||||
		return 3;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	strncpy(clear1, clear, 8);
 | 
			
		||||
	bzero(clear, 8);
 | 
			
		||||
 | 
			
		||||
	clear2 = getpass("Re-enter password: ");
 | 
			
		||||
	if (clear2 == NULL) {
 | 
			
		||||
		bzero(clear2, 8);
 | 
			
		||||
		fprintf(stderr, "Not a tty!");
 | 
			
		||||
		return 3;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strcmp(clear1, clear2) != 0) {
 | 
			
		||||
		fprintf(stderr, "Sorry, passwords don't match.\n");
 | 
			
		||||
		bzero(clear1, 8);
 | 
			
		||||
		bzero(clear2, 8);
 | 
			
		||||
		return 4;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf("Encrypted password: \"%s\"\n", crypt(clear1, argv[1]));
 | 
			
		||||
	bzero(clear1, 8);
 | 
			
		||||
	bzero(clear2, 8);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								lab1/pwent.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										108
									
								
								lab1/pwent.c
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/* $Header: https://svn.ita.chalmers.se/repos/security/edu/course/computer_security/trunk/lab/login_linux/pwent.c 584 2013-01-19 10:30:22Z pk@CHALMERS.SE $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 A simple library for password databases.  Tobias Gedell 2007
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "pwent.h"
 | 
			
		||||
 | 
			
		||||
#define LINE_BUFFER_LENGTH  1000
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Return pointer to password entry for specified user.
 | 
			
		||||
 
 | 
			
		||||
 Upon error, or if the user couldn't be found, NULL is returned.
 | 
			
		||||
 
 | 
			
		||||
 Note: The returned pointer points to static data.
 | 
			
		||||
 */
 | 
			
		||||
mypwent *mygetpwnam(char *name) {
 | 
			
		||||
	FILE *file;
 | 
			
		||||
	char buffer[LINE_BUFFER_LENGTH];
 | 
			
		||||
 | 
			
		||||
	static char pwname[LINE_BUFFER_LENGTH], passwd[LINE_BUFFER_LENGTH],
 | 
			
		||||
			passwd_salt[LINE_BUFFER_LENGTH];
 | 
			
		||||
	static mypwent ent = { pwname, 0, passwd, passwd_salt, 0, 0 };
 | 
			
		||||
 | 
			
		||||
	/* Open file, return NULL if it failed. */
 | 
			
		||||
	if ((file = fopen(MYPWENT_FILENAME, "rb")) == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	/* Read each line, looking for the right entry. */
 | 
			
		||||
	while (fgets(buffer, sizeof(buffer), file) != NULL) {
 | 
			
		||||
		if (sscanf(buffer, "%[^:]:%d:%[^:]:%[^:]:%d:%d", ent.pwname, &ent.uid,
 | 
			
		||||
				ent.passwd, ent.passwd_salt, &ent.pwfailed, &ent.pwage) != 6)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(pwname, name) == 0) {
 | 
			
		||||
			fclose(file);
 | 
			
		||||
			return &ent;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(file);
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 Update password entry for user.
 | 
			
		||||
 
 | 
			
		||||
 Upon error, or if the user couldn't be found, -1 is returned,
 | 
			
		||||
 otherwise 0.
 | 
			
		||||
 */
 | 
			
		||||
int mysetpwent(char *name, mypwent *pw) {
 | 
			
		||||
	FILE *file;
 | 
			
		||||
	FILE *newfile;
 | 
			
		||||
	char buffer[LINE_BUFFER_LENGTH];
 | 
			
		||||
	char pwname[LINE_BUFFER_LENGTH];
 | 
			
		||||
 | 
			
		||||
	int status = -1;
 | 
			
		||||
 | 
			
		||||
	if ((file = fopen(MYPWENT_FILENAME, "rb")) == NULL)
 | 
			
		||||
		return -1;
 | 
			
		||||
	if ((newfile = fopen(MYPWENT_TMP_FILENAME, "wb")) == NULL) {
 | 
			
		||||
		fclose(file);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Read each line, looking for the right entry. */
 | 
			
		||||
	while (fgets(buffer, sizeof(buffer), file) != NULL) {
 | 
			
		||||
		if (sscanf(buffer, "%[^:]", pwname) != 1) {
 | 
			
		||||
			status = -1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* See if we found the entry to be updated. */
 | 
			
		||||
		if (strcmp(pwname, name) == 0) {
 | 
			
		||||
			if (snprintf(buffer, sizeof(buffer), "%s:%d:%s:%s:%d:%d\n",
 | 
			
		||||
					pw->pwname, pw->uid, pw->passwd, pw->passwd_salt,
 | 
			
		||||
					pw->pwfailed, pw->pwage) >= sizeof(buffer)) {
 | 
			
		||||
				status = -1;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			status = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (fputs(buffer, newfile) < 0) {
 | 
			
		||||
			status = -1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(newfile);
 | 
			
		||||
	fclose(file);
 | 
			
		||||
 | 
			
		||||
	/* Swap files if user successfully updated. */
 | 
			
		||||
	if (status == 0) {
 | 
			
		||||
		if (rename(MYPWENT_TMP_FILENAME, MYPWENT_FILENAME) != 0)
 | 
			
		||||
			status = -1;
 | 
			
		||||
	} else
 | 
			
		||||
		unlink(MYPWENT_TMP_FILENAME);
 | 
			
		||||
 | 
			
		||||
	return status;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								lab1/pwent.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								lab1/pwent.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/* $Header: https://svn.ita.chalmers.se/repos/security/edu/course/computer_security/trunk/lab/login_linux/pwent.h 586 2013-01-19 10:32:53Z pk@CHALMERS.SE $ */
 | 
			
		||||
 | 
			
		||||
/* pwent.h - Password entry header file */
 | 
			
		||||
 | 
			
		||||
/* These routines write and read records from a password database,
 | 
			
		||||
 named "passdb" in the current directory.
 | 
			
		||||
 | 
			
		||||
 The 'mygetpwnam' routine takes as argument a username, and returns
 | 
			
		||||
 NULL on failure to find it in the database, or a pointer to static
 | 
			
		||||
 storage if found. This storage will be overwritten on the next
 | 
			
		||||
 call.
 | 
			
		||||
 | 
			
		||||
 The 'mysetpwent' routine takes a name, and a struct 'mypwent', and
 | 
			
		||||
 replaces the data pertaining to 'name' in the database with the
 | 
			
		||||
 supplied struct. It returns 0 on success, -1 on failure to replace
 | 
			
		||||
 the record.
 | 
			
		||||
 | 
			
		||||
 The database has free form records, the length of which must not
 | 
			
		||||
 exceed 79 characters, the fields are separated by ':', much like
 | 
			
		||||
 the passwd database. The fields are:
 | 
			
		||||
 name:uid:passwd:salt:no_of_failed_attempts:password_age respectively.
 | 
			
		||||
 | 
			
		||||
 Note the separate 'salt' field, to simplify some of non-obligatory
 | 
			
		||||
 assignments, it is of course entirely possible, not to use this
 | 
			
		||||
 field, but instead to include the salt in the password field, in
 | 
			
		||||
 similarity with the passwd database.  */
 | 
			
		||||
 | 
			
		||||
/* Usage: copy the files to your own working directory, and
 | 
			
		||||
 use; #include "pwent.h"   to include it. */
 | 
			
		||||
 | 
			
		||||
#ifndef PWENT_H
 | 
			
		||||
#define PWENT_H
 | 
			
		||||
 | 
			
		||||
/* Names of password files. */
 | 
			
		||||
#define MYPWENT_FILENAME     "passdb"
 | 
			
		||||
#define MYPWENT_TMP_FILENAME "passdb.tmp"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	char *pwname; /* Username */
 | 
			
		||||
	int uid; /* User id */
 | 
			
		||||
	char *passwd; /* Password */
 | 
			
		||||
	char *passwd_salt; /* Make dictionary attack harder */
 | 
			
		||||
	int pwfailed; /* No. of failed attempts */
 | 
			
		||||
	int pwage; /* Age of password in no of logins */
 | 
			
		||||
} mypwent;
 | 
			
		||||
 | 
			
		||||
mypwent *mygetpwnam(char *name); /* Find entry matching username */
 | 
			
		||||
int mysetpwent(char *name, mypwent *pw); /* Set entry based on uid */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user