注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

passwd、shadow及redhat的实现  

2013-08-12 22:50:06|  分类: linux知识 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、login验证
之前就知道login是用来进行用户验证的,由于通常unix验证都是通过密码来校验的,所以login应该能够读取系统敏感的passwd文件,这样一来,login进程应该是具有setuid属性的。但是看了看,redhat中的login进程是没有设置setuid属性的,而用户真正的密码文件是保存在了shadow文件,这个文件是实实在在的具有非常严格的控制权限,严格的级别高到所有的通常用户权限都是被禁止的。
[tsecer@Harry root]$ ll /etc/shadow /etc/passwd
-rw-r--r--. 1 root root 2005 2013-03-16 19:22 /etc/passwd
----------. 1 root root 1173 2013-03-16 19:22 /etc/shadow
而login的权限为
[tsecer@Harry root]$ ll /bin/login
-rwxr-xr-x. 1 root root 22568 2009-10-05 23:28 /bin/login
二、好像有哪里不对劲
这里login要读取密码所在的shadow文件如何读取,这个其他用户是没有读取权限的,此时login如何读取shadow文件进行密码验证呢。这个问题我想了一段时间,没有想出来。所以看了一下login的代码,也挺复杂,里面有比较多的代码,有点混乱,所以只能调试了。
在gdb调试的时候,可以看到gdb会提示创建了子进程,所以我们猜测此时是派生了子进程来进行专门的校验。
三、断点
此时设置
set  follow-fork-mode child
b main
r -f tsecer
断点命中之后,可以看到派生的子进程就是unix_chkpwd,查看该文件
[tsecer@Harry root]$ ll /sbin/unix_chkpwd
-rwsr-xr-x. 1 root root 30700 2009-11-02 17:20 /sbin/unix_chkpwd
,该文件的确是有setuid属性的文件。
四、login的配置
在login进程中,的确是配置了是否支持PAM机制,如果配置了就是使用这种新的PAM机制。当然,如果没有PAM机制,此时login就需要当真具有对shadow文件的读取权限。我想是应该有这种系统的,只是现在手头上没有这种系统。不过在网上搜索一下,发现这个PAM也不是redhat发明的,而是最早在SUN 系统中使用。大致一看,有点小复杂,所以作罢。
五、为什么passwd和shadow文件分开
所有的用户登录都要读取密码文件进行校验,如果所有用户都可以访问包含密码的passwd文件,那么用户就可以看到系统中所有用户加密后的密码。如果系统中的用户很多,而偏偏一个用户安全意识不强,随便定义一个常见密码,例如123456,这样系统的其它用户通过这个文件就可能得到更高权限用户的密码。
所以此时把玩家的密码放在了更加受保护的shadow文件中,此时普通用户不再能够访问该文件。此时可能就是通过进程间通讯完成这种验证了。
六、login中配置
#ifdef HAVE_SECURITY_PAM_MISC_H
    /*
     * username is initialized to NULL
     * and if specified on the command line it is set.
     * Therefore, we are safe not setting it to anything
     */
……
  if(passwd_req == 1) {
    int failcount=0;

    /* if we didn't get a user on the command line, set it to NULL */
    get_pam_username(pamh, &username);

    /* there may be better ways to deal with some of these
       conditions, but at least this way I don't think we'll
       be giving away information... */
    /* Perhaps someday we can trust that all PAM modules will
       pay attention to failure count and get rid of MAX_LOGIN_TRIES? */

    retcode = pam_authenticate(pamh, 0);
    while((failcount++ < PAM_MAX_LOGIN_TRIES) &&
          ((retcode == PAM_AUTH_ERR) ||
           (retcode == PAM_USER_UNKNOWN) ||
           (retcode == PAM_CRED_INSUFFICIENT) ||
           (retcode == PAM_AUTHINFO_UNAVAIL))) {
        get_pam_username(pamh, &username);

        syslog(LOG_NOTICE,_("FAILED LOGIN %d FROM %s FOR %s, %s"),
           failcount, hostname, username, pam_strerror(pamh, retcode));
        logbtmp(tty_name, username, hostname);
        logaudit(tty_name, username, hostname, NULL, 0);

        fprintf(stderr,_("Login incorrect\n\n"));
        pam_set_item(pamh,PAM_USER,NULL);
        retcode = pam_authenticate(pamh, 0);
    }
#else /* ! HAVE_SECURITY_PAM_MISC_H */

    for (cnt = 0;; ask = 1) {

    if (ask) {
        fflag = 0;
        getloginname();
    }

    /* Dirty patch to fix a gigantic security hole when using
       yellow pages. This problem should be solved by the
       libraries, and not by programs, but this must be fixed
       urgently! If the first char of the username is '+', we
       avoid login success.
       Feb 95 <alvaro@etsit.upm.es> */

    if (username[0] == '+') {
        puts(_("Illegal username"));
        badlogin(username);
        sleepexit(1);
    }

    /* (void)strcpy(tbuf, username); why was this here? */
    if ((pwd = getpwnam(username))) {
#  ifdef SHADOW_PWD
        struct spwd *sp;

        if ((sp = getspnam(username)))
          pwd->pw_passwd = sp->sp_pwdp;
#  endif

        salt = pwd->pw_passwd;
    } else
      salt = "xx";
  评论这张
 
阅读(619)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017