天天看點

經常登入Linux,使用者密碼背後的知識了解一下include include

經常登入Linux,使用者密碼背後的知識了解一下

一,使用者密碼存放在哪裡?

說到這個問題,絕大部分的同學肯定都知道/etc/passwd這個檔案,不錯,這個檔案裡存儲的就是使用者名,密碼等資訊。

每一行都是一個account,每一行有7個資訊,分别用 : 隔開,從左往右依次是:使用者名:加密使用者密碼:使用者id:組id:注釋:工作目錄:shell目錄,這些資訊被放在一個叫struct passwd的結構體中統一管理,struct passwd結構體包含以下資訊:

struct passwd {

char pw_name;  /使用者名*/

char pw_passwd;  /加密使用者密碼*/

int pw_uid;      /使用者id/

int pw_gid;     /組id/

char pw_gecos;    /注釋*/

char pw_dir;    /使用者主目錄*/

char pw_shell;    /shell目錄*/

};

但是通過檢視/etc/passwd檔案内容,發現加密密碼一項都用了字元'x'表示。我們了解中的加密密碼應該是一串看不出任何邏輯的字元才對,怎麼會是一個‘x’呢?

二,/etc/shadow檔案

上面一個内容中最後提出了一個疑惑,'x'的來由。這就是一個簡單的曆史遺留問題,早期的posix版本中'x'這個位置确實存放的是加密密碼,也就是一串沒有任何邏輯的字元,這串加密密碼采用的是單向加密算法進行加密,也就是說無法通過反向破解得到密碼,我想這也是早期會直接将加密密碼放在/etc/passwd的原因吧。如果我們生的再早個十幾年,就會直接在/etc/passwd中看到加密密碼了。

但是/etc/passwd這個檔案在同一超級管理者下的各個賬戶裡是透明的,也就是說,誰都可以通路到/etc/passwd這個檔案并且擷取到那一串加密密碼。這樣有啥用,密碼不還是單向加密的嗎?盡管不可破解,但是仍然存在着根據使用者的身份等資訊推測密碼經相同的加密處理後與原來的加密密碼進行對比進而擷取密碼的風險。為了避免這種情況,現在的某些系統将加密密碼存放在一個shadow(陰影)檔案中,并且給這個檔案設定為僅超級管理者可見,而/etc/passwd密碼的位置僅僅用一個'x'意思一下。這個shadow檔案就是/etc/shadow.

mbl:$1$Y/1ISiCx$S5mv/6lKRM1ZobXdP8629LsI2DsNWJpkAUFiO8PlZTN741DoyI6cvOFQVGluS/dF7tCadfACwhbfcFt5v0iK9Y8bp:18307:0:99999:7:::

左邊第二個就是加密密碼所在位置,$1$Y/1ISiCx$S5mv/6lKRM1ZobXdP8629LsI2DsNWJpkAUFiO8PlZTN741DoyI6cvOFQVGluS/dF7tCadfACwhbfcFt5v0iK9Y8bp。前半部分的$1$Y/1ISiCx$是鹽值,從官方文檔中我們可以知道使用者密碼經過了glibc中的crypt算法的處理,處理後會形成鹽值後面的一串字元串,對于相同的密碼,雜湊演算法加密出來的字元串也相同,是以,鹽值的存在就是為了區分這些相同密碼形成的相同加密碼 同時也為破解增加了難度。

/etc/shadow中的各個資訊被struct spwd這個結構體管理。感興趣可以了解一下。

有了/etc/shadow,安全性就大大提高。想要擷取加密密碼?得先知道超級管理者密碼。

如果可以成功的撸到crypt加密算法,下一節的内容就是crypt的算法實作了。

三,小福利

(1)先領略一下crypt的風采吧。

Python3:

C: 編譯的時候要帶上-lcrypt

(2)上面說到了/etc/passwd這個檔案,自己編寫個程式輸出這裡面的内容吧

#include

#include

void printPwRecord(){

struct passwd *ptr = nullptr;
  setpwent();
  while((ptr = getpwent()) != nullptr){
      printf("%s:%s:%u:%u:%s:%s:%s\n", ptr->pw_name, ptr->pw_passwd, ptr->pw
              , ptr->pw_dir, ptr->pw_shell);
  }
  endpwent();           

}

int main(){

printPwRecord();           

這段程式用到了三個函數,setpwent();  getpwent();  endpwent();

       #include

include

struct passwd *getpwent(void);

void setpwent(void);

void endpwent(void);

這三個函數用于通路password file,比如/etc/passwd.

getpwent函數傳回檔案的的下一個記錄項,setpwent函數定位到檔案開始處,endpwent函數關閉這些檔案。注意:在getpwent之前調用setpwent是自我保護性的措施,以便在調用者在此之前已經調用getpwent打開了有關檔案的情況下,重新使他們定位到檔案開始處。最後要調用endpwent關閉這些檔案。

與passwd相關的還有getpwuid和getpwnam這兩個函數,

struct passwd getpwnam(const char name);

struct passwd *getpwuid(uid_t uid);

分别通過使用者名/使用者id擷取該指定使用者的struct passwd結構體,通過這個結構體可以通路該使用者資訊。

原文位址

https://www.cnblogs.com/GuoYuying/p/12685058.html