Monday, September 1, 2014

Unix Prog: Shadow Password File

1. encrypted password

Encrypted password is a copy of user's password that has been put through a one way encryption algorithm, and it can not be inverted back.
But we can guess different passwords and apply algorithm to get the encrypted one, to compare with existing encrypted one to guess the password.

2. Shadow password file

To make it more difficult to obtain the encrypted password, system normally save the encrypted password in another file, shadow password file. Each record in shadow password file has to at least include the user name and encrypted password.

Definition:
The reason to use "sudo" command is, only super user could read /etc/shadow file, since it contains very sensitive information.
 ubuntu@ip-172-31-23-227:~$ sudo less /etc/shadow  
 ......  
 root:*:16228:0:99999:7:::  
 daemon:*:16228:0:99999:7:::  
 bin:*:16228:0:99999:7:::  
 ......  

At Ubuntu System:
1) 1st field: represents the user name
2) 2nd field: represents encrypted password
3) 3rd field: date of last password change(days since 1970, Jan 1)
4) 4th field: minimum password age, since how many days elapsed, the user will be allowed to change the password, in this case, "0" means the user is allowed to change password at any time
5) 5th field: maximum password age, how many days elapsed, the user "has to" change the password when he/she login to the system.
6) 6th field: password warning period, how many days before the expiration date, the user should be warned to change the password
7) 7th field: password inactivity period, after the password expires, during how many days, the password is still accepted to login. In this case, it is empty. meaning, after password expires, the user will never be able to login.
8) 8th field: account expiration date, the number of days since 1970 Jan 1st. After this date, the account will expires, which means, this user can't login any more. Compared to password expiration date, user just can't user this password to login, but his/her account still exists. In this case, it is empty, meaning the account will never expire.
9) 9th field: reserve field for future use.

3. System Calls

Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/shadow.h  
 ......  
 /* Structure of the password file. */  
 struct spwd  
  {  
   char *sp_namp;       /* Login name. */  
   char *sp_pwdp;       /* Encrypted password. */  
   long int sp_lstchg;     /* Date of last change. */  
   long int sp_min;      /* Minimum number of days between changes. */  
   long int sp_max;      /* Maximum number of days between changes. */  
   long int sp_warn;      /* Number of days to warn user to change  
                   the password. */  
   long int sp_inact;     /* Number of days the account may be  
                   inactive. */  
   long int sp_expire;     /* Number of days since 1970-01-01 until  
                   account expires. */  
   unsigned long int sp_flag; /* Reserved. */  
  };  
   
   
 /* Open database for reading.  
   
   This function is not part of POSIX and therefore no official  
   cancellation point. But due to similarity with an POSIX interface  
   or due to the implementation it is a cancellation point and  
   therefore not marked with __THROW. */  
 extern void setspent (void);  
   
 /* Close database.  
   
   This function is not part of POSIX and therefore no official  
   cancellation point. But due to similarity with an POSIX interface  
   or due to the implementation it is a cancellation point and  
   therefore not marked with __THROW. */  
 extern void endspent (void);  
   
 /* Get next entry from database, perhaps after opening the file.  
   
   This function is not part of POSIX and therefore no official  
   cancellation point. But due to similarity with an POSIX interface  
   or due to the implementation it is a cancellation point and  
   therefore not marked with __THROW. */  
 extern struct spwd *getspent (void);  
   
 /* Get shadow entry matching NAME.  
   
   This function is not part of POSIX and therefore no official  
   cancellation point. But due to similarity with an POSIX interface  
   or due to the implementation it is a cancellation point and  
   therefore not marked with __THROW. */  
 extern struct spwd *getspnam (const char *__name);  
 ......  

4. Example:
fileio.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
 #include<string.h>  
 #include<shadow.h>  
   
 void PrintPwd(struct spwd *pd)  
 {  
  printf("struct address: %p  ", pd);  
  printf("%s:%s:%ld:%ld:%ld:%ld:%ld:%ld\n",  
      pd->sp_namp, pd->sp_pwdp, pd->sp_lstchg, pd->sp_min,  
      pd->sp_max, pd->sp_warn, pd->sp_inact, pd->sp_expire);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  struct spwd *pd;  
   
  // Get the root user's shadow password entry  
  if((pd = getspnam("root")) == NULL) {  
   printf("getspnam error!\n");  
   exit(1);  
  }  
   
  PrintPwd(pd);  
   
  // Iterate each user's shadow password entry  
  printf("\nIterate all entries:\n");  
  setspent();  
  while((pd = getspent()) != NULL) {  
   PrintPwd(pd);  
   
   // We can't use free here, it would complain invalid pointer.  
   // Because getspent doesn't use "malloc" to create struct spwd,  
   // we can't free this memory  
   //free(pd);  
  }  
  endspent();  
   
  exit(0);  
 }  

shell:
1) Run the program with current account, it failed. Because /etc/shadow is owned by "root", and it doesn't allow "group/other users" to have any access on it.
2) Run the program with "sudo" command, meaning running with account "root". This time succeeded. It will firstly get the shadow password structure by providing the user name "root". And then iterate all shadow password entries, note that the struct address is the same across the iteration procedure, meaning every time when getspent() is called, it will just overwrite the information at the same place.
 ubuntu@ip-172-31-23-227:~$ ./io.out  
 getspnam error!  
 ubuntu@ip-172-31-23-227:~$ sudo ./io.out  
 struct address: 0x7ffa1c714b40  root:*:16228:0:99999:7:-1:-1  
   
 Iterate all entries:  
 struct address: 0x7ffa1c714ae0  root:*:16228:0:99999:7:-1:-1  
 struct address: 0x7ffa1c714ae0  daemon:*:16228:0:99999:7:-1:-1  
 struct address: 0x7ffa1c714ae0  bin:*:16228:0:99999:7:-1:-1  
 ,,,,,,  

No comments:

Post a Comment