step 1 complete :DDD
This commit is contained in:
parent
6f97cf1f39
commit
c1c885e1de
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