现在的位置: 首页 > 综合 > 正文

VSS 密码

2013年10月23日 ⁄ 综合 ⁄ 共 4251字 ⁄ 字号 评论关闭

当然对于具有本地管理员权限的人只需要覆盖掉date/um.dat文件就可以更改口令。而且VSS本身是靠文件共享的,安全性极差,不过如果不知道其口令,其文件的组织还是比较麻烦的,如果知道了口令的话,就容易处理的多。所以我这篇帖子都不好意思当文章提交的,其实这篇文章重点不是讲如何获取VSS的口令,而是讲一下算法破解的思路。   
    
  VSS的口令认证过程是这样的,从DATE目录下的UM文件读取口令加密字串,而这个文件是任何可以共享VSS目录的人都可以看见的,一般而言这个目录都会设置比较低级别的共享。VSS的加密口令实际上是一个2位的散列:格式如下:   
  55   55   FF   D2   41   64   6D   69-6E   00   00   00   00   00   00   00       UU..Admin.......   
  00   00   00   00   00   00   00   00-00   00   00   00   00   00   00   00       ................   
  00   00   00   00   1A   69   00   00-A8   01   00   00   00   00   00   00       .....i..........   
  00   00   00   00   00   00   00   00-00   00   00   00   38   00   00   00       ............8...   
  55   55   90   80   47   75   65   73-74   00   00   00   00   00   00   00       UU..Guest.......   
  00   00   00   00   00   00   00   00-00   00   00   00   00   00   00   00       ................   
  00   00   00   00   55   69   00   00-3C   02   00   00   00   00   00   00       ....Ui..<.......   
  00   00   00   00   00   00   00   00-00   00   00   00   00   00   00   00       ................   
  其中1A   69就是ADMIN的散列   
  而     55   69就是GUEST的散列   
    
  跟踪一下VSS的算法可以得出如下的加密算法,另外在加密之前,串入的口令会先转化成大写格式的。   
  void   envsspasswd(char   *   passwd,char   *   enpasswd,int   len)   
  {   
          const   char   incstr[15]="BrianDavidHarry";   
          char   passwd1[200];   
          int   i;   
          WORD   a;   
          WORD   b;   
          if(len>15)   
                  return   0;   
          memcpy(passwd1,passwd,len);   
          memcpy(passwd1+len,incstr,15-len);   
          passwd1[15]=0;   
          len   =   15;   
          b   =   0;   
          a   =   0;   
          for(i=0;i<len;i++)   
          {   
                  a   =     passwd1[i];     
                  a   =   a   ^   0x96;   
                  a   =   a*(i+1);   
                  b   +=   a;   
          }   
          printf("%02x",b);   
  }   
    
  OK,其实我们讲到这里,关于VSS的口令破解就一点意义也没有了,而是在一个思路上,从上面可以看到,其口令只具2位长度,因此肯定存在很多散列一致的口令,因此无需真正找到口令,只需要找到一个具备同样散列的口令就可以了。   
  当然,如果只是暴力跑的话,效果会比较差的,因为上面这个算法会导致相同位数的散列是比较靠近的,不同位数的散类差距比较大,如果不知道口令的位数,一位的穷局举的话效果并不会很理想。那么如何来确定密码的位数呢?实际根据上面的加密算法我们可以知道其密码散列递增的规律,下面的实现就是根据这个算法可以最优先的找到密码位数,然后在位数以内进行穷举的实现,使得计算的速度非常高:   
  关键点在于这句:   
          d   =   a   -   b;   
          if((d/num)>154   &&   (d/num)<250)   
  因为我们知道,x^80肯定是会大于128的,对于‘0’到‘Z’的可能口令组合,最小生成的都应该大于154。从而判断这个长度是否可能存在可能的解。   
    
  int   devsspasswd(char   enp[4],char   *   dnp)   
  {   
          const   char   incstr[15]="BrianDavidHarry";   
          int   i;   
          int   j;   
          int   k;   
          long   c1;   
          long   c2;   
          long   c4;   
          int   c3;   
    
          WORD   a;   
          WORD   b;   
          WORD   c;   
          WORD   d;   
          WORD   e;   
          int   num;   
    
          a   =   hextoint(enp[2])*16*16*16+hextoint(enp[3])*16*16+hextoint(enp[0])*16+hextoint(enp[1]);   
          c3   =   'Z'-'0'+1;   
    
          for(i=0;i<15;i++)   
          {   
                  dnp[i]=0;   
                  b   =0;   
                  for(j=0;j<15-i;j++)   
                  {   
                          c   =   incstr[j];     
                          c   =   c   ^   0x96;   
                          c   =   c*(j+1+i);   
                          b   +=   c;   
                  }   
                  if(i==0   &&   b==a)   
                  {   
                          printf("password   is   null/n");   
                          return   0;   
                  }   
                  d   =   a   -   b;   
                  num   =   0;   
                  c2   =   1;   
                  for(j=0;j<i;j++)   
                  {   
                          num   =   num+j+1;   
                          c2   =   c3*c2;   
                  }   
                  if(num>0)   
                  {   
                          c1   =   0;                           
                          if((d/num)>154   &&   (d/num)<250)   
                          {   
                                  memset(dnp,'0',i);   
                                  Sleep(100);   
                                  do{   
                                          c4   =   1;   
                                          for(j=1;j<i-1;j++)   
                                          {   
                                                  c4   =   c4   *   c3;   
                                                  if(c1%c4==0)   
                                                          dnp[j]='0';   
                                                  else   
                                                  {   
                                                          dnp[j]++;   
                                                          break;   
                                                  }   
                                          }   
                                          b   =   0;   
                                          for(k=1;k<i;k++)   
                                          {   
                                                  c   =   dnp[k];     
                                                  c   =   c   ^   0x96;   
                                                  c   =   c*(k+1);   
                                                  b   +=   c;   
                                          }   
                                          e=d-b;           
                                            
                                          if((e^0x96)>='0'   &&   (e^0x96)<='Z')     
                                          {   
                                                  dnp[0]=(e^0x96);   
                                                  printf("%s/n",dnp);   
                                                  return   i;   
                                          }   
                                          c1++;   
                                  }while(c1<c2);                                   
                          }   
                  }   
          }   
          return   0;           
  }   
    
  当然,这个算法对VSS口令破解本身意义不大,拥有um.dat写权限的直接拷贝别人的知道口令的um.dat文件覆盖就可以,或者修改其中的散列,不知道的呢,也可以直接通过共享拷贝数据文件再使用um.dat覆盖或者在vss程序中饶过口令达到图破权限,写这点东西是重点强调一下破解算法的思路。

 

【上篇】
【下篇】

抱歉!评论已关闭.