Linux System Account SSH Weak Password Detection Automatic By System API
catalog
1. Linux弱口令攻擊向量 2. Linux登錄驗證步驟 3. PAM 4. 弱口令風(fēng)險基線檢查?
1. Linux弱口令攻擊向量
0x1: SSH密碼暴力破解
hydra -l root -P /root/passwdCracker/password.lst -t 16 -vV -e ns 112.124.51.10 ssh對于Linux系統(tǒng)來說,從外部破解系統(tǒng)密碼的途徑只有SSH這一條路,攻擊者必須借助網(wǎng)絡(luò)進行密碼猜解嘗試
0x2: Linux SSH空口令帳號
1. 通過Bash指令: cut -d: -f1 /etc/passwd,獲取當(dāng)前賬戶列表 2. 遍歷列表,調(diào)用getpwnam、getgrgid獲取每個賬戶的pw_name、pw_shell,過濾出是shell為/bin/bash或/bin/sh(非/sbin/nologin)的賬戶 3. 將過濾出的帳號在/etc/shadow中逐行查找,判斷當(dāng)前帳號是否為空口令(第二段為空)但是需要注意的是,用戶賬號剛創(chuàng)建時沒有口令,但是被系統(tǒng)鎖定,無法使用,必須為其指定口令后才可以使用,即使是指定空口令
0x2: /etc/shadow本地暴力破解(john and ripper)
tar zxvf john-1.ll cd john-1.8.0/src make make clean generic cd ../run ./unshadow /etc/passwd /etc/shadow > mypasswd ./john ./mypasswdRelevant Link:
http://www.openwall.com/john/ http://www.openwall.com/john/doc/EXAMPLES.shtml http://www.douban.com/note/326215912/ http://darren.blog.51cto.com/1081720/634241 http://linuxconfig.org/password-cracking-with-john-the-ripper-on-linux http://4506912.blog.51cto.com/4496912/999577 http://www.kafan.cn/edu/42559051.html?
2. Linux登錄驗證步驟
1. 根據(jù)用戶名從/etc/passwd提取uid,gid以及家目錄和shell配置 2. /etc/shadow根據(jù)uid核對密碼 3. 進入shell控制階段 //此時并不意味著登錄成功,若用戶對應(yīng)的shell為/sbin/nologin,則禁止該用戶登錄系統(tǒng),但可以進行其他工作,譬如操作郵件,注: /etc/nologin.txt可以顯示用戶不能登錄的原因 4. 進行PAM驗證,讀取/etc/pam.d/login,必須通過驗證才能最終登錄,該文件內(nèi)容通常如下 auth required pam_securetty.so //pam_securetty.so讀取/etc/securrety,設(shè)定root用戶可以登陸的終端,一般只設(shè)置tty而沒有pts/0,telnet使用該模塊故無法使用root用戶登錄,而sshd沒有使用到該模塊故不受限制 auth required pam_stack.so service=system-auth auth required pam_nologin.so //pam_nologin.so 模塊始終允許root用戶可以登陸,其他用戶只有在/etc/nologin文件不存在時可以登陸, 若/etc/nologin文件存在,則在輸入正確用戶名及任意密碼后將該文件內(nèi)容顯示給用戶 account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth session optional pam_console.so +----------------+| application: X |+----------------+ / +----------+ +================+| authentication-[---->--\--] Linux- |--<--| PAM config file|| + [----<--/--] PAM | |================||[conversation()][--+ \ | | | X auth .. a.so |+----------------+ | / +-n--n-----+ | X auth .. b.so || | | __| | | _____/| service user | A | | |____,-----'| | | V A+----------------+ +------|-----|---------+ -----+------++---u-----u----+ | | || auth.... |--[ a ]--[ b ]--[ c ]+--------------+| acct.... |--[ b ]--[ d ]+--------------+| password |--[ b ]--[ c ]+--------------+| session |--[ e ]--[ c ]+--------------+0x1: 密碼驗證模塊驗證流程
1. 執(zhí)行/usr/bin/passwd,并輸入密碼 2. passwd調(diào)用PAM模塊,讀取/etc/pam.d/passwd配置文件并加載相應(yīng).so文件,對輸入的密碼進行驗證 3. 將驗證結(jié)果傳回passwd程序 //注: passwd修改密碼時,除了參考/etc/login.defs,還要滿足/etc/pam.d/passwd模塊的驗證Relevant Link:
http://blog.itpub.net/15480802/viewspace-1406088?
3. PAM
PAM的英文全稱是Pluggable Authentication Module系統(tǒng),即此程序是有關(guān)執(zhí)行用戶鑒別和帳號維護的服務(wù)。鑒別部分通常通過: (合法性)質(zhì)詢-回應(yīng)的交互來完成的。使用PAM,管理員可以通過不重編輯鑒定程序來定制一些使用方法,PAM有四部分組成
1. libpam: 實現(xiàn)PAM API的庫 2. PAM配置文件: /etc/pam.conf 3. 一套動態(tài)可裝載二進制對象組成,常常用來調(diào)用一些處理實際鑒別(authentication)工作的服務(wù)模塊 4. 使用PAM API的系統(tǒng)命令組成,如login、us、ftp、telnet、etc..0x1: LIBPAM
PAM API的認證(authentication)常規(guī)程序有三個主要函數(shù)組成
1. pam_start( const char *service_name, const char *username, const struct pam_conv *conv, pam_handle_t **pamh_p ); /* pam_start()和pam_end()函數(shù)是開始和結(jié)束一個PAM會話,傳遞給pam_start() 函數(shù)的參數(shù)如下所示: + service_name: 一定義在pam.conf中的特殊服務(wù) + username: 需要鑒權(quán)的用戶登錄名。 + conv: 一指向pam_conf結(jié)構(gòu)的指針 + pamh_p: 一雙精度指向pam_handle_t結(jié)構(gòu)的指針。PAM構(gòu)架會分配或不分配內(nèi)存給這個結(jié)構(gòu),并且一應(yīng)用程序不能直接訪問它。它基本上是用來通過PAM構(gòu)架(framework)來處理多個并發(fā)的PAM會話 pam_conv結(jié)構(gòu)如下所示: struct pam_conv {int (*conv)(int num_msg, const struct pam_message **msg,struct pam_response **resp, void *appdata_ptr);void *appdata_ptr; }*conv是指向PAM對話函數(shù)的指針,appdata_ptr指針指向特殊應(yīng)用程序數(shù)據(jù),它并不常用 */2. pam_end( pam_handle_t *pamh, int exit_status ); /* pam_end()函數(shù)的參數(shù)由在pam_start()函數(shù)中填充的pam_handle_t*組成,并且返回的是exit狀態(tài)。exit狀態(tài)正常情況下是PAM_SUCCESS。pam_edn()會收回與pam_handle_t*相關(guān)聯(lián)的內(nèi)存,并且任何企圖重用這個句柄將返回一個seg fault錯誤 */3. pam_authenticate( pam_handle_t *pamh, int flags ); /* pam_authenticate()函數(shù)也再一次由通過pam_start()填充的pam_handle_t*組成,并且可選的標(biāo)志(flags)可以傳遞給結(jié)構(gòu)(framework) */另外一些可以應(yīng)用于應(yīng)用程序的PAM API函數(shù)如下所示
+ pam_set_item() - 為PAM會話寫狀態(tài)信息 + pam_get_item() - 為PAM獲得狀態(tài)信息 + pam_acct_mgmt() - 檢查當(dāng)前用戶帳號是否合法 + pam_open_session() - 開始一個新的會話 + pam_close_session() - 關(guān)閉當(dāng)前會話進程 + pam_setcred() -管理用戶信任資格(credentials) + pam_chauthtok() - 改變用戶的鑒權(quán)(authentication)token牌 + pam_strerror() - 返回錯誤字符串,類似與perror()函數(shù)0x2: PAM.CONF
PAM配置文件通常位于/etc/pam.conf,它可以分為四個部分
1. 鑒權(quán)(authentication) 2. 帳號管理 3. 會話管理 4. 密碼管理一個標(biāo)準(zhǔn)的一行配置如下所示:
login auth required /usr/lib/security/pam_unix.so.1 try_first_pass1) 第一欄是服務(wù)名,這是參照在pam_start()函數(shù)中的第一個參數(shù)。如果通過pam_start()的服務(wù)請求不列在pam.conf,則將使用默認的"other"服務(wù)。"other"服務(wù)名字可以是"su"和"rlogin",如果服務(wù)名不止一次說明,模塊將會提示"stacked",并且framework將會通過第三欄的值來決定2) 第二欄指示這特定的服務(wù)將執(zhí)行何種類型的行為,合法的值是: "auth"為鑒權(quán)行為、"account"為帳號管理、"session"為會話管理、"password"為密碼管理。不是所有的應(yīng)用程序需要使用每一個行為,如,su僅僅需要使用"auth"鑒權(quán)行為,"passwd"只需要來使用"password"管理行為 3) 第三欄作為一個控制類型的一欄。如果用戶在鑒定行為中失敗,它指示PAM 架構(gòu)(framework)行為。此欄正確的值為:"requisite","required", "sufficient", "optional":3.1) + "requisite"意思指如果用戶在鑒定(quthentication)時失敗,PAM framework會立即返回一失敗信息,其中沒有其他模塊調(diào)用。3.2) + "required"指示如果一個用戶鑒定(quthentication)時失敗,PAM framework只在調(diào)用其他所有模塊后在返回失敗信息。這樣做的話用戶會不知道哪個模塊鑒權(quán)被拒絕,如果一個用戶成功被鑒別,所有"required"模塊必須返回成功3.3) + "optional"意思是用戶將被允許訪問即使鑒權(quán)失敗,失敗的結(jié)果是下一個在堆棧中的模塊將被處理3.4) + "sufficient"指的是如果用戶傳遞一這特定模塊,PAM framework會立即返回成功,即使隨后的模塊有"requisite"或者"required"控制值,類似于"optional" 、"sufficient"回允許訪問即使鑒全步驟失敗4) pam.conf第四欄中是認證模塊的路徑,各個系統(tǒng)路徑不同,如在Linux-PAM系統(tǒng)中PAM模塊在/usr/lib目錄下,而Solaris在/usr/lib/security中維護模塊 5) 第五欄是一個空格分開的module-dependent選項列表,是傳遞給認證模塊調(diào)用0x3: 模塊 MODULES
每一個PAM模塊本質(zhì)上是一個必須輸出特定函數(shù)的庫,這些函數(shù)可以被PAM framework調(diào)用(面向接口編程),通過庫輸出的函數(shù)有如下列表
+ pam_sm_authenticate() + pam_sm_setcred() + pam_sm_acct_mgmt() + pam_sm_open_session() + pam_sm_close_session() + pam_sm_chauthtok()如果實現(xiàn)者不決定在一模塊內(nèi)支持特定的操作,模塊會為此操作返回PAM_SUCCESS,例如:如果一個模塊設(shè)計成為不支持帳號管理(account management),pam_sm_acct_mgmt()函數(shù)會簡單的返回PAM_SUCCESS
pam_sm_authenticate()是按下面的方式聲明的
一個簡單的pam_unix 模塊中的pam_sm_authenticate()函數(shù)應(yīng)該如下所示
#include <security/pam_modules.h> #include <...>extern int pam_sm_authenticate( pam_handle_t *pamh, int flgs, int c, char **v ) {char *user;char *passwd;struct passwd *pwd;int ret;/* ignore flags and optional arguments */if ( (ret = pam_get_user( ..., &user )) != PAM_SUCCESS )return ret;if ( (ret = pam_get_pass( ..., &passwd )) != PAM_SUCCESS )return ret;if ( (pwd = getpwnam(user)) != NULL ) {if ( !strcmp(pwd->pw_passwd, crypt(passwd)) )return PAM_SUCCESS;elsereturn PAM_AUTH_ERR;}return PAM_AUTH_ERR; }0x4: 應(yīng)用程序 APPLICATION
一個應(yīng)用程序處理PAM部分必須由pam_start()和pam_end()組成和一PAM對話函數(shù)。比較幸運的是,user-space PAM API定義的比較成熟和穩(wěn)定所以對話函數(shù)是比較模板型的代碼。一個簡單的su PAM實現(xiàn)所下所示
#include <security/pam_appl.h> #include <...>int su_conv(int, const struct pam_message **,struct pam_response **, void *);static struct pam_conv pam_conv = { su_conv, NULL };int main( int argc, char **argv ) {pam_handle_t *pamh;int ret;struct passwd *pwd;/* assume arguments are correct and argv[1] is the username */ret = pam_start("su", argv[1], &pam_conv, &pamh);if ( ret == PAM_SUCCESS )ret = pam_authenticate(pamh, 0);if ( ret == PAM_SUCCESS )ret = pam_acct_mgmt(pamh, 0);if ( ret == PAM_SUCCESS ) {if ( (pwd = getpwnam(argv[1])) != NULL )setuid(pwd->pw_uid);else {pam_end(pamh, PAM_AUTH_ERR);exit(1);}}pam_end(pamh, PAM_SUCCESS);/* return 0 on success, !0 on failure */return ( ret == PAM_SUCCESS ? 0 : 1 ); }int su_conv(int num_msg, const struct pam_message **msg,struct pam_response **resp, void *appdata) {struct pam_message *m = *msg;struct pam_message *r = *resp;while ( num_msg-- ){switch(m->msg_style) {case PAM_PROMPT_ECHO_ON:fprintf(stdout, "%s", m->msg);r->resp = (char *)malloc(PAM_MAX_RESP_SIZE);fgets(r->resp, PAM_MAX_RESP_SIZE-1, stdin);m++; r++;break;case PAM_PROMPT_ECHO_OFF:r->resp = getpass(m->msg);m++; r++;break;case PAM_ERROR_MSG:fprintf(stderr, "%s\n", m->msg);m++; r++;break;case PAM_TEXT_MSG:fprintf(stdout, "%s\n", m->msg);m++; r++;break;default:break;}}return PAM_SUCCESS; }Relevant Link:
http://www.xfocus.net/articles/200006/45.html http://www.helplib.net/s/linux.die/65_1666/man-3-pam-start.shtml?
3. 弱口令風(fēng)險基線檢查
0x1: 檢測方案
1. 通過Bash指令: cut -d: -f1 /etc/passwd,獲取當(dāng)前賬戶列表 2. 遍歷列表,調(diào)用getpwnam、getgrgid獲取每個賬戶的pw_name、pw_shell,過濾出是shell為非"/sbin/nologin"的賬戶 3. 將上一步得到的賬號在/etc/shadow中查找,過濾出password hash不為空的帳號(即只有顯式通過passwd指令設(shè)置過密碼的賬號才可以登錄) 4. 遍歷過濾出的"可登錄帳號",調(diào)用pam_authenticate API/或者SSH login API進行登錄嘗試 5. 記錄并上報猜解出的弱口令0x2: 基于PAM API框架進行密碼猜解嘗試
對于Linux弱口令風(fēng)險來說,空口令風(fēng)險不存在(帳號創(chuàng)建默認空口令但是被系統(tǒng)鎖定)、john and ripper本地破解/etc/shadow(密碼學(xué)原理)無法防御,因為不可能禁止用戶讀取這個文件,禁止讀取會造成破壞正常業(yè)務(wù)的風(fēng)險
#include <stdlib.h> #include <iostream> #include <fstream> #include <security/pam_appl.h> #include <unistd.h> #include <string.h>// To build this: // g++ test.cpp -lpam -o teststruct pam_response *reply;//function used to get user input int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {*resp = reply;return PAM_SUCCESS; }int main(int argc, char** argv) {if(argc != 2) {fprintf(stderr, "Usage: check_user <username>\n");exit(1);}const char *username;username = argv[1];const struct pam_conv local_conversation = { function_conversation, NULL };pam_handle_t *local_auth_handle = NULL; // this gets set by pam_startint retval;// local_auth_handle gets set based on the service retval = pam_start("login", username, &local_conversation, &local_auth_handle);//retval = pam_start("common-auth", username, &local_conversation, &local_auth_handle);if (retval != PAM_SUCCESS){std::cout << "pam_start returned " << retval << std::endl;exit(retval);}reply = (struct pam_response *)malloc(sizeof(struct pam_response));// *** Get the password by any method, or maybe it was passed into this function.//reply[0].resp = getpass("Password: ");reply[0].resp = strdup("test");reply[0].resp_retcode = 0;retval = pam_authenticate(local_auth_handle, 0 | PAM_DISALLOW_NULL_AUTHTOK);if (retval != PAM_SUCCESS){if (retval == PAM_AUTH_ERR){std::cout << "Authentication failure." << std::endl;}else{std::cout << "pam_authenticate returned " << retval << std::endl;}exit(retval);}std::cout << "Authenticated." << std::endl;retval = pam_end(local_auth_handle, retval);if (retval != PAM_SUCCESS){std::cout << "pam_end returned " << retval << std::endl;exit(retval);}return retval; }pam位于SSH的底層(更下一層),調(diào)用pam_authenticate api不受/sbin/nologin的影響,從本質(zhì)上來說和ssh登錄嘗試是一樣的,在代碼中要注意的是,調(diào)用pam_start時傳入"login"服務(wù)器名即可,因為僅僅需要使用"auth"鑒權(quán)行為
pam_start中的參數(shù)service_name服務(wù)名指定了使用哪個配置文件,如service_name為"login",將使用/etc/pam.d/login這個配置在centos、ubuntu下測試都通過
Relevant Link:
http://stackoverflow.com/questions/5913865/pam-authentication-for-a-legacy-application/5970078#5970078 http://stackoverflow.com/questions/5913865/pam-authentication-for-a-legacy-application http://www.jiancool.com/article/58701980019/;jsessionid=798A5A41EB356A6A1FC5C8E449523F6B?
Copyright (c) 2015 LittleHann All rights reserved
?
轉(zhuǎn)載于:https://www.cnblogs.com/LittleHann/p/4875535.html
總結(jié)
以上是生活随笔為你收集整理的Linux System Account SSH Weak Password Detection Automatic By System API的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OPW-00001: Unable to
- 下一篇: linux学习笔记(4):Ubuntu终