Linux

無法使用自定義 pam 模組在使用者名中走私數據 - input_userauth_request:無效使用者

  • April 24, 2020

我正在嘗試通過添加提供的使用者名將數據添加到通過 ssh 呼叫的程序中,例如

ssh user@smuggledata@host

我已經寫了一個 PAM 模組,但是

  1. sshd 在呼叫 PAM 之前已經確定使用者是壞的
  2. 儘管我已經更改了 PAM_USER,但後續模組仍在根據送出的使用者名進行身份驗證。

我首先嘗試使用auth requisite mymodule.so和 中的程式碼執行程式碼pam_sm_authenticate()。雖然程式碼被解雇了 - 它沒有工作:

May  1 22:40:30 animal sshd[3827]: Invalid user colin@example from 127.0.0.1
May  1 22:40:30 animal sshd[3827]: input_userauth_request: invalid user colin@example [preauth]
May  1 22:40:35 animal pam_pat[3827]: Retrieved username colin@example
May  1 22:40:35 animal pam_pat[3827]: checking char c against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: checking char o against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: checking char l against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: checking char i against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: checking char n against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: checking char @ against 3 dividers
May  1 22:40:35 animal pam_pat[3827]: Found divider @
May  1 22:40:35 animal pam_pat[3827]: user=colin, data=example
May  1 22:40:35 animal sshd[3827]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=127.0.0.1  user=colin
May  1 22:40:37 animal sshd[3827]: Failed password for invalid user colin@example from 127.0.0.1 port 43998 ssh2
May  1 22:41:28 animal sshd[3827]: Connection closed by 127.0.0.1 port 43998 [preauth]

請注意,當執行到達 pam_unix 身份驗證失敗但使用者報告為 PAM_USER 中的轉換值。密碼正確,因此 pam_unix 可能沒有針對 PAM_USER 進行身份驗證。

我也嘗試了account requisite mymodule.so和程式碼pam_sm_acct_mgmt()- 但程式碼沒有被呼叫:

May  1 22:57:10 animal sshd[4105]: Invalid user colin@exmple from 127.0.0.1
May  1 22:57:10 animal sshd[4105]: input_userauth_request: invalid user colin@exmple [preauth]
May  1 22:57:16 animal sshd[4105]: pam_unix(sshd:auth): check pass; user unknown
May  1 22:57:16 animal sshd[4105]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=127.0.0.1
May  1 22:57:18 animal sshd[4105]: Failed password for invalid user colin@exmple from 127.0.0.1 port 44118 ssh2
May  1 22:57:27 animal sshd[4105]: Connection closed by 127.0.0.1 port 44118 [preauth]

查看 pam_unix的原始碼,它檢索pam_get_user()顯然指向 PAM_USER 以外的其他內容的使用者名。

如何更改隨後作為使用者進行身份驗證的值?

  • 如何確保在對使用者名進行任何其他處理之前發生這種情況?
  • 有沒有比寫回 pam_get_user() 返回的指針更好的方法?

更新 程式碼(添加了 pam_get_user()):

   char *submitted_name;
   char work_bufr[PAT_BUFR];
   char log_entry[PAT_BUFR];
   int an_int;
   char dividers[]="@%+";
   int num_dividers;
   char *cursor;
   char divider_found[]="0";
   const char *debug_user;

   openlog("pam_pat",  LOG_CONS | LOG_PID | LOG_NDELAY, LOG_AUTH);
   /* retrieve a copy of the submitted username */
   if (PAM_SUCCESS != pam_get_item(pamh, PAM_USER, (void *) &submitted_name) || !(submitted_name)) {
     syslog (LOG_ERR, "Failed to retrieve username from pam");
     closelog();
     return(PAM_IGNORE);
   }
   syslog (LOG_ERR, "Retrieved username %s", submitted_name);
   strncpy(work_bufr, submitted_name, PAT_BUFR);
   submitted_name=work_bufr;
   /* search for dividers and split string */
   cursor=submitted_name;
   an_int=PAT_BUFR;
   num_dividers=(int)strlen(dividers);
   while (--an_int && '\0'!=*cursor) {
      syslog(LOG_ERR, "checking char %c against %d dividers", (int)*cursor, num_dividers);
      for (int x=0; x<num_dividers; x++) {
         if (*cursor==dividers[x]) {
            syslog(LOG_ERR, "Found divider %c", *cursor);
            an_int=0;
            *divider_found=*cursor;
            *cursor='\0';
            if (PAM_SUCCESS==pam_set_item(pamh, PAM_USER, submitted_name)) {
                ++cursor;
                syslog (LOG_ERR, "user=%s, data=%s",submitted_name,cursor);
                setenv("PAM_PAT_DIVDR", divider_found, 1);
                setenv("PAM_PAT_DATA", cursor, 1);
                if (PAM_SUCCESS == pam_get_user(pamh, &debug_user, NULL)) {
                     syslog (LOG_ERR, "pam_get_user() found %s", debug_user);
                }
                closelog();
                return(PAM_IGNORE);
            } else {
                syslog (LOG_ERR, "Failed to update username");
            }
         }
      }
      cursor++;
   }
   syslog (LOG_ERR, "Extended username not found.");
   closelog();
   return(PAM_IGNORE);
}

input_userauth_request() 是 sshd 中提示輸入使用者名的函式。

從閱讀pam_ldap(本地系統不一定知道被驗證的使用者名)“sshd

$$ xxx $$: input_userauth_request: invalid user …" 未安裝或未配置 LDAP NSS 庫時彈出消息。由此我推斷 sshd 在移交給 PAM(WTF?)之前首先嘗試驗證使用者名。所以為了避免這個初始錯誤,我需要編寫一個 NSS 模組(大概是實現 getpwnam() 但我希望我必須拆開 sshd 以了解它是如何滴答作響的)。 呃!

(我仍然不確定這會解決問題)

的手冊頁pam_get_user(3)說它從通過pam_start(3). 反過來,該函式表示其結構中的元素可以使用pam_set_item(3). 第三個函式的手冊頁提供了一個明確的參考來更改正在測試的使用者名以進行身份驗證。

pam_set_item功能允許應用程序和 PAM 服務模組訪問和更新item_type. 為此,創建了 item 參數指向的對象的​​副本。支持以下 item_types

$$ … $$ PAM_USER 將為其提供身份服務的實體的使用者名。也就是說,在身份驗證之後,PAM_USER 標識了可以使用該服務的本地實體。請注意,該值可以由 PAM 堆棧中的任何模組從某事物(例如“匿名”)映射到其他事物(例如“guest119”)。因此,應用程序應在每次呼叫 PAM 函式後查詢 PAM_USER 的值。

引用自:https://unix.stackexchange.com/questions/362510