shadow文件中密码的加密方式
1) 查看shadow文件的内容
cat /etc/shadow
可以得到shadow文件的内容,限于篇幅,我们举例说明:
root:$1$Bg1H/4mz$X89TqH7tpi9dX1B9j5YsF.:14838:0:99999:7:::
其格式为:
{用户名}:{加密后的口令密码}:{口令最后修改时间距原点(1970-1-1)的天数}:{口令最小修改间隔(防止修改口令,如果时限未到,将恢复至旧口令):{口令最大修改间隔}:{口令失效前的警告天数}:{账户不活动天数}:{账号失效天数}:{保留}
【注】:shadow文件为可读文件,普通用户没有读写权限,超级用户拥有读写权限。如果密码字符串为*,则表示系统用户不能被登入;如果字符串为!,则表示用户名被禁用;如果字符串为空,则表示没有密码。
我们可以使用passwd –d 用户名 清空一个用户的口令密码。
2) 解析shadow文件中密码字符串的内容
对于示例的密码域$1$Bg1H/4mz$X89TqH7tpi9dX1B9j5YsF.,我们参考了Linux标准源文件passwd.c,在其中的pw_encrypt函数中找到了加密方法。
我们发现所谓的加密算法,其实就是用明文密码和一个叫salt的东西通过函数crypt()完成加密。
而所谓的密码域密文也是由三部分组成的,即:$id$salt$encrypted。
【注】: id为1时,采用md5进行加密;
id为5时,采用SHA256进行加密;
id为6时,采用SHA512进行加密。
3) 数据加密函数crypt()讲解
i. 头文件:#define _XOPEN_SOURCE
#include <unistd.h>
ii. 函数原型:char *crypt(const char *key, const char *salt);
iii. 函数说明:crypt()将使用DES演算法将参数key所指的字符串加以编码,key字符串长度仅取前8个字符,超过此长度的字符没有意义。参数salt为两个字符组成的字符串,由a-z、A-Z、0-9,’.’和’/’所组成,用来决定使用4096种不同内建表格的哪一种。函数执行成功后会返回指向编码过的字符串指针,参数key所指向的字符串不会有所改动。编码过的字符串长度为13个字符,前两个字符为参数salt代表的字符串。
iv. 返回值:返回一个指向以NULL结尾的密码字符串
v. 附加说明:使用GCC编译时需要加上 –lcrypt
4) 加密参数salt的由来
在我们的示例密码域中salt为Bg1H/4mz,那么它又是如何来的?
我们还是从标准源文件passwd.c中查找答案。在passwd.c中,我们找到了与salt相关的函数crypt_make_salt。
在函数crypt_make_salt中出现了很多的判断条件来选择以何种方式加密(通过id值来判断),但其中对我们最重要的一条语句是gensalt(salt_len)。
我们继续查看了函数static char *gensalt (unsigned int salt_size),才发现原来神秘无比的salt参数只是某个固定长度的随机字符串而已。
5) 最终结论
在我们每次改写密码时,都会随机生成一个这样的salt。我们登录时输入的明文密码经过上述的演化后与shadow里的密码域进行字符串比较,以此来判断是否允许用户登录。
【注】:经过上述的分析,我们发现破解linux下的口令也不是什么难事,但前提是你有机会拿到对方的shadow文件。
6) 示例代码(测试代码):
#include <pwd.h>
#include <stddef.h>
#include <string.h>
#include <shadow.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]){
if(argc < 2)
{
printf("no usrname input");
return 1;
}
if (geteuid() != 0)
{
fprintf(stderr, "must be setuid root");
return -1;
}
struct spwd *shd= getspnam(argv[1]);
if(shd != NULL)
{
static char crypt_char[80];
strcpy(crypt_char, shd->sp_pwdp);
char salt[13];
int i=0,j=0;
while(shd->sp_pwdp[i]!='\0')
{
salt[i]=shd->sp_pwdp[i];
if(salt[i]=='$')
{
j++;
if(j==3)
{
salt[i+1]='\0';
break;
}
}
i++;
}
if(j<3)
perror("file error or user cannot use.");
if(argc==3)
{
printf("salt: %s, crypt: %s\n", salt, crypt(argv[2], salt));
printf("shadowd passwd: %s\n", shd->sp_pwdp);
}
}
return 0;
}
编译: gcc passwd.c -lcrypt -o passwd
运行: ./passwd root 123
结果: salt: $1$Bg1H/4mz$, crypt: $1$Bg1H/4mz$X89TqH7tpi9dX1B9j5YsF.
shadowd passwd: $1$Bg1H/4mz$X89TqH7tpi9dX1B9j5YsF.
shadow文件中密码的加密方式的更多相关文章
- linux的PAM认证和shadow文件中密码的加密方式
它是一种统一的认证方案.PAM 让您能随时改变您的认证方法以及需求,并且不需要重新编译任何代码就封装了所有本地认证方法.具体见 PAM 网站. 对于 PAM 您只需要做: 对您的密码采用不同于 DES ...
- 生成/etc/shadow文件中的密码
shadow文件的格式就不说了.就说说它的第二列--密码列. 通常,passwd直接为用户指定密码就ok了.但在某些情况下,要为待创建的用户事先指定密码,还要求是加密后的密码,例如kickstart文 ...
- 手动生成/etc/shadow文件中的密码
shadow文件的格式就不说了.就说说它的第二列——密码列. 通常,passwd直接为用户指定密码就ok了.但在某些情况下,要为待创建的用户事先指定密码,还要求是加密后的密码,例如kickstart文 ...
- Centos7系统kvm虚机忘记密码进不去, 通过宿主机修改/etc/shadow文件改密码,重启后系统起不来故障排错
问题描述 某天, 因为其他项目组交接问题, kvm里面的堡垒机系统用户root密码登录不上,然后他通过宿主机修改/etc/shadow文件修改密码,但是修改完后重启系统后发现kvm宿主机连接不上虚机了 ...
- SpringBoot项目配置文件中密码的加密
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/15565862.html 版权声明:本文为博主原创文章,转载请附上博文链接! 公众号:追梦1819 ...
- Liferay 6.2 改造系列之二十四:修改liferay密码的加密方式
为了便于后期与Cas集成过程中使用数据库用户的方便,将liferay密码的加密方式改为SHA. 在/portal-master/portal-impl/src/portal.properties配置文 ...
- MyBatis mapper文件中的变量引用方式#{}与${}的差别
MyBatis mapper文件中的变量引用方式#{}与${}的差别 #{},和 ${}传参的区别如下:使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于$ ...
- ASP.NET中MD5的加密方式很简单
在ASP.NET中MD5的加密方式很简单,代码如下: FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5&quo ...
- ][mybatis]MyBatis mapper文件中的变量引用方式#{}与${}的差别
转自https://blog.csdn.net/szwangdf/article/details/26714603 MyBatis mapper文件中的变量引用方式#{}与${}的差别 默认情况下,使 ...
随机推荐
- android实例 listview与sqlite数据绑定
ListView与Sqlite数据库绑定步骤: 1.将Sqlite数据库的内容查询出来并放入数组列表中,形成ListView的数据源: 2.适配器绑定数据源,显示在ListView item中. 本文 ...
- Java查找数组重复元素,并打印重复元素、重复次数、重复元素位置
面试题查找重复元素并打印重复次数和重复位置,一顿懵逼,回来死磕写下来,打印指定重复次数和最大次数,其他在此基础上可以再更新 package sort; import org.testng.annota ...
- Pycharm创建Django项目显示python non-zero exit code(1)错误
好久时间没有做Django的项目了,今天创建项目竟然报Non-zero exit code(1)错误 查明原因是因为pip不是最新版本,需要执行以下命令:python -m pip install - ...
- TensorFlow中使用GPU
TensorFlow默认会占用设备上所有的GPU以及每个GPU的所有显存:如果指定了某块GPU,也会默认一次性占用该GPU的所有显存.可以通过以下方式解决: 1 Python代码中设置环境变量,指定G ...
- Go语言实现:【剑指offer】从上往下打印二叉树
该题目来源于牛客网<剑指offer>专题. 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 不需分层,一维数组. Go语言实现: /** * Definition for a bi ...
- Go语言实现:【剑指offer】数据流中的中位数
该题目来源于牛客网<剑指offer>专题. 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位 ...
- CAS 分析
CAS是什么 (1) CAS(Compare and Swap) 比较并交换, 比较并交换是在多线程并发时用到的一种技术 (2) CAS是原子操作, 保证并发安全性, 而不是保证并发同步. (3) C ...
- 将Spring实战第5版中Spring HATEOAS部分代码迁移到Spring HATEOAS 1.0
最近在阅读Spring实战第五版中文版,书中第6章关于Spring HATEOAS部分代码使用的是Spring HATEOAS 0.25的版本,而最新的Spring HATEOAS 1.0对旧版的AP ...
- Vue简介与基础
一.什么是Vue.js Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App, Vue语法也是可以用于进行手机App开发的,需要借助于 ...
- 论文翻译:2015_DNN-Based Speech Bandwidth Expansion and Its Application to Adding High-Frequency Missing Features for Automatic Speech Recognition of Narrowband Speech
论文地址:基于DNN的语音带宽扩展及其在窄带语音自动识别中加入高频缺失特征的应用 论文代码:github 博客作者:凌逆战 博客地址:https://www.cnblogs.com/LXP-Never ...