UNIX的master.passwd文件中的密码问题,急

Flysnow 2002-04-12 11:04:46
现在因需要,一程序需要读取master.passwd用户名后面的加密密码,将用户输入密码使用和系统同样的方式加密后比较,判断是否可以登录,但是找来找去就是不知道UNIX系统的该密码是用何方法加密?哈森,MD5都试过了就是加密出来和UNIX系统的不一样,adduser.c,pw.c,passwd.c的源代码全部分析过了,就是没有一点头绪,谁能帮我?
...全文
286 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
twit_book 2002-04-14
  • 打赏
  • 举报
回复
关注
twit_book 2002-04-13
  • 打赏
  • 举报
回复
关注。
我在查书。
jimmychou 2002-04-13
  • 打赏
  • 举报
回复
/*
* Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
* Copyright (c) 1994 Olaf Kirch <okir@monad.swb.de>
* Copyright (c) 1995 Bill Paul <wpaul@ctr.columbia.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#ifdef YP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yppasswd.h>
#include <pw_yp.h>
#include <err.h>
#include "yppasswd_private.h"

extern char *getnewpasswd __P(( struct passwd * , int ));

int
yp_passwd(char *user)
{
struct yppasswd yppasswd;
struct master_yppasswd master_yppasswd;
struct passwd *pw;
CLIENT *clnt;
struct rpc_err err;
char *master;
int *status = NULL;
uid_t uid;
char *sockname = YP_SOCKNAME;

_use_yp = 1;

uid = getuid();

if ((master = get_yp_master(1)) == NULL) {
warnx("failed to find NIS master server");
return(1);
}

/*
* It is presumed that by the time we get here, use_yp()
* has been called and that we have verified that the user
* actually exists. This being the case, the yp_password
* stucture has already been filled in for us.
*/

/* Use the correct password */
pw = (struct passwd *)&yp_password;

if (pw->pw_uid != uid && uid != 0) {
warnx("only the super-user may change account information \
for other users");
return(1);
}

pw->pw_change = 0;

/* Initialize password information */
if (suser_override) {
master_yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd);
master_yppasswd.newpw.pw_name = strdup(pw->pw_name);
master_yppasswd.newpw.pw_uid = pw->pw_uid;
master_yppasswd.newpw.pw_gid = pw->pw_gid;
master_yppasswd.newpw.pw_expire = pw->pw_expire;
master_yppasswd.newpw.pw_change = pw->pw_change;
master_yppasswd.newpw.pw_fields = pw->pw_fields;
master_yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos);
master_yppasswd.newpw.pw_dir = strdup(pw->pw_dir);
master_yppasswd.newpw.pw_shell = strdup(pw->pw_shell);
master_yppasswd.newpw.pw_class = pw->pw_class != NULL ?
strdup(pw->pw_class) : "";
master_yppasswd.oldpass = "";
master_yppasswd.domain = yp_domain;
} else {
yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd);
yppasswd.newpw.pw_name = strdup(pw->pw_name);
yppasswd.newpw.pw_uid = pw->pw_uid;
yppasswd.newpw.pw_gid = pw->pw_gid;
yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos);
yppasswd.newpw.pw_dir = strdup(pw->pw_dir);
yppasswd.newpw.pw_shell = strdup(pw->pw_shell);
yppasswd.oldpass = "";
}

if (suser_override)
printf("Changing NIS password for %s on %s in domain %s.\n",
pw->pw_name, master, yp_domain);
else
printf("Changing NIS password for %s on %s.\n",
pw->pw_name, master);

/* Get old password */

if(pw->pw_passwd[0] && !suser_override) {
yppasswd.oldpass = strdup(getpass("Old Password: "));
if (strcmp(crypt(yppasswd.oldpass, pw->pw_passwd),
pw->pw_passwd))
//仔细看清楚这里,strcmp是一个字符串比较函数,因为UNIX系统所用的加密方法是单向算法,是不可逆的,所以重新加密用户输入的密码与现在密码字串进行比较,php4.1.1(我用过的版本中间也有一个这样的函数)


{
errx(1, "sorry");
}

}

if (suser_override) {
if ((master_yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL)
return(1);
} else {
if ((yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL)
return(1);
}

if (suser_override) {
if ((clnt = clnt_create(sockname, MASTER_YPPASSWDPROG,
MASTER_YPPASSWDVERS, "unix")) == NULL) {
warnx("failed to contact rpc.yppasswdd on host %s: %s",
master, clnt_spcreateerror(""));
return(1);
}
} else {
if ((clnt = clnt_create(master, YPPASSWDPROG,
YPPASSWDVERS, "udp")) == NULL) {
warnx("failed to contact rpc.yppasswdd on host %s: %s",
master, clnt_spcreateerror(""));
return(1);
}
}
/*
* The yppasswd.x file said `unix authentication required',
* so I added it. This is the only reason it is in here.
* My yppasswdd doesn't use it, but maybe some others out there
* do. --okir
*/
clnt->cl_auth = authunix_create_default();

if (suser_override)
status = yppasswdproc_update_master_1(&master_yppasswd, clnt);
else
status = yppasswdproc_update_1(&yppasswd, clnt);

clnt_geterr(clnt, &err);

auth_destroy(clnt->cl_auth);
clnt_destroy(clnt);

if (err.re_status != RPC_SUCCESS || status == NULL || *status) {
errx(1, "failed to change NIS password: %s",
clnt_sperrno(err.re_status));
}

printf("\nNIS password has%s been changed on %s.\n",
(err.re_status != RPC_SUCCESS || status == NULL || *status) ?
" not" : "", master);

return ((err.re_status || status == NULL || *status));
}
#endif /* YP */
zhenshi 2002-04-13
  • 打赏
  • 举报
回复
我说了你别笑我呀。我记的我以前看书。UNIX的用户的加密密码用的加密算法每次加密出的密文都不是一样的。我忘了那个加密算法叫什么了。我给你查查书把。
ssw0989 2002-04-13
  • 打赏
  • 举报
回复
我觉得这么解密很难成功。首先你不知道他的加密算法是那一种或是那几种,其
次,就算你知道了加密算法,你也很难知道它的密钥的生成方法,就象 jimmychou
(老步) 同志所说的64个字符组成的随机数,那这64个字符又怎么得到哪?就算是
取系统随机数作为密钥只要稍加变化你就很难得到。
一般只要加秘密钥是随机生成的,你就很难破解。除非你能得到很多的原文和密文
,然后再从中拆解出密钥才有可能,这一切在你不知道加密算法的情况下就更难
实现了。
jimmychou 2002-04-13
  • 打赏
  • 举报
回复
It's very easy!
刚才把所有关于密码的源代码全部看了一次,我捡几个最关键的说一说:
以FreeBSD 4.5为例:
sub salt {
local($salt); # initialization
local($i, $rand);
local(@itoa64) = ( '0' .. '9', 'a' .. 'z', 'A' .. 'Z' ); # 0 .. 63

warn "calculate salt\n" if $verbose > 1;
# to64
for ($i = 0; $i < 27; $i++) {
srand(time + $rand + $$);
$rand = rand(25*29*17 + $rand);
$salt .= $itoa64[$rand & $#itoa64];
}
warn "Salt is: $salt\n" if $verbose > 1;

return $salt;
}
上面的代码是/usr/sbin/adduser的PERL源代码,从上面可以看出,返回的salt实际上是一个应用64个字符组成的随机数,然后循环26次,让该密钥(书名:干扰字串)更变态(不同版本的UNIX不同,查了一下资料,HP-UX使用25次循环),然后使用用户输入字串,使用随机生成的该密钥作为干扰字串使用crypt函数生成密码字串。
$cryptpwd = crypt($password, &salt) if $password ne "";
上面的代码过程中password变量为用户输入密码。

在用户登录验证的过程中,将master.passwd每个用户的第二个字段密码字串拿出来作为干扰字串,重新加密用户输入的密码然后再与该密码字串比较,如果相同,即可通过身份认证,呵呵
用PHP的语言来做的话可以这样
使用super(一种工具),让nobody可以以ROOT的身份执行chown
先将master.passwd中的密码字串读出,变量名为$biantai
用户输入密码为$sb
if (crypt($sb,$biantai)==$biantai)
{
echo "ok!";
}
最后重新使用chown把master.passwd文件所有权更改为ROOT,更新用户数据库pwd.db文件,搞定!



wenyin 2002-04-13
  • 打赏
  • 举报
回复
呵呵,Unix就是用的不可逆加密,你是想破密么,去黑客网站看看会比较好哦。
zhenshi 2002-04-13
  • 打赏
  • 举报
回复
我看了看书。UNIX的加密算法是向加密对象加入一定的内容在加密。所以每次的加密结果都不一样。加密的结果是加入内容的不同而不同的。你去看看应用密码学。我想那里会介绍的比较详细。我没学过高数。看不懂。我想问。MD5也是单向加密呀。
Flysnow 2002-04-13
  • 打赏
  • 举报
回复
推一下,看一下实力如何
linuxnewer 2002-04-13
  • 打赏
  • 举报
回复
不懂,看看。
不知道它加密的时候都用了什么,同样的密码每次加密的结果都不一样。
不过密码校验的时候就是用的“老步”说得那样。
Flysnow 2002-04-12
  • 打赏
  • 举报
回复
人气这么差,是不是高手都睡觉去了?

19,620

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧