From c1c885e1de393a97531df09dddba7a082170e4b0 Mon Sep 17 00:00:00 2001 From: schulze Date: Sat, 29 Jan 2022 10:32:11 +0100 Subject: [PATCH] step 1 complete :DDD --- .gitignore | 4 ++ lab1/Makefile | 10 +++++ lab1/login_linux.c | 95 +++++++++++++++++++++++++++++++++++++++ lab1/makepass.c | 67 ++++++++++++++++++++++++++++ lab1/pwent.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ lab1/pwent.h | 50 +++++++++++++++++++++ 6 files changed, 334 insertions(+) create mode 100644 .gitignore create mode 100755 lab1/Makefile create mode 100755 lab1/login_linux.c create mode 100755 lab1/makepass.c create mode 100755 lab1/pwent.c create mode 100755 lab1/pwent.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0bd0ce4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +lab1/login_linux + +lab1/mylogin diff --git a/lab1/Makefile b/lab1/Makefile new file mode 100755 index 0000000..74a4391 --- /dev/null +++ b/lab1/Makefile @@ -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 diff --git a/lab1/login_linux.c b/lab1/login_linux.c new file mode 100755 index 0000000..3bcc9ce --- /dev/null +++ b/lab1/login_linux.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/lab1/makepass.c b/lab1/makepass.c new file mode 100755 index 0000000..5714242 --- /dev/null +++ b/lab1/makepass.c @@ -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 +#include +#include +#include +#include +#include + +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; +} + diff --git a/lab1/pwent.c b/lab1/pwent.c new file mode 100755 index 0000000..b865a36 --- /dev/null +++ b/lab1/pwent.c @@ -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 +#include +#include + +#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; +} diff --git a/lab1/pwent.h b/lab1/pwent.h new file mode 100755 index 0000000..f3d5621 --- /dev/null +++ b/lab1/pwent.h @@ -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