实验四 linux下的c语言编程以及gcc工具的使用

实验4

一、实验目的

了解Linux下的用户管理机制,熟练掌握Linux下的C语言编程以及gcc工具的使用。

需要的知识:C/C++语言的基本技能、第9章用户管理知识、第12章gcc的使用。

 

二、实验内容

Linux系统管理的一项重要工作就是用户管理。用户的口令以加密的形式存储在口令文件/etc/shadow中。弱口令就是很容易被猜出来的口令,比如与用户名相同的口令、像“123456、admin、computer”这类常用的口令等,口令字典是指将一些常用弱口令写在一个文本文件。管理员应该定期检测系统中是否存在弱口令。试编写一个c语言程序,主动检查自己的Linux系统中是否存在弱口令。

 

三、实验步骤

步骤1:分析/etc/shadow文件的格式。

可以查看自己的系统中该文件的格式,参照9.1节的介绍,该文件的每一行对应一个用户,下面是一个系统中/etc/shadow文件的实例:

user1:$6$DVLiBPZG$IrR9o0KpjtGQOj7I5WvgxQ.jMQ/Qzl3cJp4w0loUMZs4xQSQ8wkdIK7Sdkdk2pMXeAfOYq9O07r/QuDdJ8f3c0:14748:0:99999:7:::

user2:$6$RR8pmW2aerqIkySA$PcMV7/Z37QFCe9hJrf1rlUjPTAOdmKsW/mfG40V343kxG1QNsWWI7mdzl.50SCJpI4TQ/x4z4zsCoiA48EjAn1:14748:0:99999:7:::

user3:$6$oGG.739y$9ysybZ.VaTQ7dmR1zyz1vR8OiCUSCnzqnFd1PUYvedJMt.t6ElISwUohtOAlqAuT7.sPDjfy.bKCKar82mSp2.:14748:0:99999:7:::

user4:$6$AJerec5o$bwgJnQ0mTPzZMRCZYuivQVsWtD9mlh3.pWK2tR2pZPr4NzSlqk6hhFq3/zfWJXQCNmXJTlZhubwwW9x6a8mtM0:14748:0:99999:7:::

user5:$6$o1DA6WOiXtme7Zsw$Lj6bXgI5c5Kg/GewGWYv.4pQ0fD/AnSYEjMvmXxuvzEK3IYhNYjnTIEnTPQr9pZIMzatBOyrC4FgBjYtR5R.n1:14749:0:99999:7:::

user6:$6$UUXC4WKX$mKyl/32n7xrU1ChPIJYs2gwYuEoObdkNsPcVhxR22xFBIspNjVIfRv4FgoDWsJIxy4TZ.ci70MeDvDMEeExXL0:14749:0:99999:7:::

步骤2:了解Linux下口令加密的原理

口令的加密是使用Linux系统的crypt函数。使用info或者man可以了解该命令的工作原理:Red Hat Linux9中使用的MD5算法,在Fedora 10中默认使用了SHA-512算法。它使用一个字符串作为salt(翻译成盐),长度是8到16个字节,将用户输入的口令key进行加密。函数crypt(key,salt)的结果存入/etc/shadow文件的第2个域。这个域前面$6$salt$就是crypt函数的salt参数。当给用户设置口令时,salt是由系统随机选取的,因此即使是相同的key,因salt不同而第二个域的值也不同。

当用户在登录中输入自己的口令时,系统使用crypt进行同样的计算,如果所得的结果与/etc/shadow中存储的一致,则接受用户的登录。

步骤3:什么是弱口令:弱口令就是很容易被猜出来的口令,比如admin,guest,flower,123456,beauty等等。在口令猜测或者破解时,一般不会穷尽所有字符的所有排列组合,一般都使用一个弱口令字典,字典中包含了常被用来作为口令的字符串。可以到网上查找口令字典。

步骤4:弱口令检查的原理

对每个用户而言,逐个将那些经常被用来作为口令的词,使用crypt做运算,如果运算结果与/etc/shadow所存储的加密后的口令相同,则口令被猜出来。

步骤5:用c语言编写实现口令检查的程序

关键部分的代码如下:

   通过读取/etc/shadow的每一行,获得一个关于用户的数据结构,存放在pwd中。

char saltstr[21];           //存放种子,最多是20个字节

    bzero(saltstr,sizeof(saltstr));//将变了全部清0

strncpy(saltstr,pwd->pw_passwd,20);

//将salt取出,最多20个字节,以其中$作为边界

    cp = crypt (guess, saltstr);         //调用crypt加密函数

    if (strcmp (cp, pwd -> pw_passwd))  //与口令文件中存储的信息比较

          return (0);                     //若不一致则返回

printf ("Warning! Password Problem: Guessed:\t%s\tpasswd: %s\n",

pwd -> pw_name, guess);   //找到口令,显示口令

步骤6:编译程序

gcc –o passchk pass.c –lcrypt

其中-o选项指定编译后的可执行文件名,-l选项表示使用crypt函数库

步骤7:执行口令检查程序 

./passchk –P myshadow –w words –p

    其中passchk是可执行文件名,myshadow是口令文件,如果没有-P选项,则缺省使用Linux系统的/etc/shadow文件,words是存放弱口令的口令字典文件,选项-p表示将破解后的口令输出。 

 

四、实验结果

1、将/etc/shadow拷贝到myshadow

 

2、编辑口令字典words

 

3、编译程序

 

4、运行程序

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int args, char* argv[]){
    char* dir1;
    char* dir2;
    int flag = 0;
    for(int i = 0; i < args; i++){
        if(argv[i][0] == '-'){
            if(argv[i][1] == 'P'){
                dir1 = argv[i + 1];
                flag = 1;
            }
            if(argv[i][1] == 'w'){
                dir2 = argv[i + 1];
            }
        }
    }
    FILE* myshadow;
    if(flag) myshadow = fopen(dir1, "r");
    else myshadow = fopen("/etc/shadow", "r");
    char buf1[500];
	char buf2[500];
    int index[5];

	while(!feof(myshadow)){
        fgets(buf1, 500, myshadow);
        if(feof(myshadow)) break;
        int count = 0, flag = 1;
        for(int i = 0; i < strlen(buf1) && count < 5; i++){
            if(buf1[i] == ':' || buf1[i] == '$'){
                index[count++] = i;
                if(buf1[i] == '$') flag = 0;
            }
        }
        if(flag) continue;
        FILE* words = fopen(dir2, "r");
        while(!feof(words)){
            fgets(buf2, 500, words);
            if(buf2[strlen(buf2) - 1] == '\n') buf2[strlen(buf2) - 1] = '\0';
            char salt[50];
            char psw[500];
            char name[50];
            bzero(salt, sizeof(salt));
            bzero(psw, sizeof(psw));
            bzero(name, sizeof(name));
            strncpy(salt, buf1 + index[0] + 1, index[3] - index[1] + 1);
            strncpy(psw, buf1 + index[0] + 1, index[4] - index[1]);
            strncpy(name, buf1, index[0]);
            char* cp = crypt(buf2, salt);
            if(strcmp(cp, psw) == 0){
                printf("Warning! Password Problem: Guessed:\t%s\tpasswd: %s\n", name, buf2);
               break;
            }
        }
        fclose(words);
	}

	fclose(myshadow);

    return 0;
}

//大吉大利,今晚AC

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值