分享

linux口令相关(passwd/shadow)及破解方式

 沙门空海 2018-03-24

技术学习视频教程网盘资源整理 https://pan.baidu.com/s/13dbR69NLIEyP1tQyRTl4xw

(前面部分转自网络做说明)

     在linux中,口令文件在/etc/passwd中,早期的这个文件直接存放加密后的密码,前两位是"盐"值,是一个随机数,后面跟的是加密的密码。为了安全,现在的linux都提供了 /etc/shadow这个影子文件,密码放在这个文件里面,并且是只有root可读的。

下面来分析一下/etc/passwd文件,他的每个条目有7个域,分别是名字:密码:用户id:组id:用户信息:主目录:shell 例如:ynguo:x:509:510::/home/ynguo:/bin/bash

在利用了shadow文件的情况下,密码用一个x表示,普通用户看不到任何密码信息。如果你仔细的看看这个文件,会发现一些奇怪的用户名,她们是系 统的缺省账号,缺省账号是攻击者入侵的常用入口,因此一定要熟悉缺省账号,特别要注意密码域是否为空。下面简单介绍一下这些缺省账号

adm拥有账号文件,起始目录/var/adm通常包括日志文件
bin拥有用户命令的可执行文件
daemon用来执行系统守护进程
games用来玩游戏
halt用来执行halt命令
lp拥有打印机后台打印文件
mail拥有与邮件相关的进程和文件
news拥有与usenet相关的进程和文件
nobody被NFS(网络文件系统)使用
shutdown执行shutdown命令
sync执行sync命令
uucp拥有uucp工具和文件

传统上,/etc/passwd文件在很大范围内是可读的,因为许多应用程序需要用他来把UID转换为用户名。例如,如果不能访问/etc/passwd,那么ls -l命令将显示UID而不是用户名。但是使用口令猜测程序,具有加密口令的可读/etc/passwd文件有巨大的安全危险。所以出现了影子文件/etc/shadow。

影子口令系统把口令文件分成两部分:/etc/passwd和/etc/shadow。影子口令文件保存加密的口令;/etc/passwd文件中的密码全部变成x。Shadow只能是root可读,从而保证了安全。/etc/shadow文件每一行的格式如下:

用户名:加密口令:上一次修改的时间(从1970年1月1日起的天数):口令在两次修改间的最小天数:口令修改之前向用户发出警告的天数:口令终止后账号被禁用的天数:从1970年1月1日起账号被禁用的天数:保留域。

例如:root:$1$t4sFPHBq$JXgSGgvkgBDD/D7FVVBBm0:11037:0:99999:7:-1:-1:1075498172

bin:*:11024:0:99999:7:::
daemon:*:11024:0:99999:7:::缺省情况下,口令更新并不开启。如果你的系统没有启动影子文件,那么运行pwconv程序。

####################

Added by iceknife on 20100601

####################

shadow采用DES加密方式,破解方式为暴力破解,可以采用字典攻击:

比如:

username:$1$jMzjGK//$Do9jjAM9TqHVhkH3eSytT.:14576:0:99999:7:::
在这之前已经知道用户名username的密码为123456,那密码是如何得来的呢

采用函数crypt(char* key, char* salt); 注意用-lcrypt链接

       crypt() is  the password encryption function.  It is based on the Data
       Encryption Standard algorithm with  variations  intended  (among  other
       things)  to discourage use of hardware implementations of a key search.

       key is a user’s typed password.

       salt is a two-character string chosen from the set [a–zA–Z0–9./].  This
       string  is used to perturb the algorithm in one of 4096 different ways.

在这里 key=123456

salt=$1$jMzjGK//$

那么crypt得出的结果为$1$jMzjGK//$Do9jjAM9TqHVhkH3eSytT.

一下是一段暴力破解的源代码

/*
 ============================================================================
 Name        : descrack.c
 Author      : iceknife
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

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

char data[37] = "abcdefghijklmnopqrstuvwxyz0123456789";
char *goalPass = "$1$AAODv...$gXPqGkIO3Cu6dnclE";
char mypwd[10];
int minlen = 1; //min password length
int maxlen = 3; //max password length


void subgenerate(int index, int pwdlen)
{
        if (index == pwdlen)
                return;
        int i;
        for (i = 0; i < 36; i++)
        {
                mypwd[index] = data[i];
                memset(mypwd + index + 1, data[0], pwdlen- index -1);
                if (i != 0)
                {
//                     printf("%s      ",mypwd);
                        if (!strcmp(goalPass, crypt(mypwd, "$1$AAODv...$")))
                        {
                                printf("find password:%s", mypwd);
                                exit(0);
                        }
                }
                subgenerate(index + 1, pwdlen);
        }
}

void generate(int pwdlen, int start, int end)
{
        int i;
        for (i = start; i < end; i++) // 多线程可分段
        {
                mypwd[0] = data[i];
                memset(mypwd + 1, data[0], pwdlen-1); //填充长度
//              printf("%s      ",mypwd);
                if (!strcmp(goalPass, crypt(mypwd, "$1$AAODv...$")))
                {
                        printf("find password:%s", mypwd);
                        exit(0);
                }
                subgenerate(1, pwdlen);
        }
}


int main()
{
        char mypwd[10];
        if (maxlen > 9) puts("max password length must little then 9");
        int i,threadnum = 10;
        for (i = minlen; i <= maxlen; i++)
        {
                printf("/npassword length:%d/n", i);
                //password length
                memset(mypwd, 0, 10);
                generate(i,0,36); //留作多线程
        }

        puts("password not found");
        return 0;
}   

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多