step 1 complete :DDD

This commit is contained in:
schulze 2022-01-29 10:32:11 +01:00
parent 6f97cf1f39
commit c1c885e1de
6 changed files with 334 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
lab1/login_linux
lab1/mylogin

10
lab1/Makefile Executable file
View 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
View 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
View 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
View 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
View 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