• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

  • Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

Secure Remote Password

TuxZer92

New member
29.12.2020
1
0
BIT
0
Здравствуйте, начал изучать безопасную передачу паролей.

Скажите пожалуйста, а можно-ли как-то узнать пароль, который клиент вводит при аутентификации по VNC на удаленном компьютере, если для защиты используется протокол SRP (Secure Remote Password)?
Т.е. на клиентском компьютере запускается Viewer, при помощи которого осуществляется подключение к компьютеру, на котором в свою очередь запущена служба, слушающая на нужном порту.
Клиент запускает Viewer, вводит имя компьютера, сервер предлагает принять сертификат, для того чтобы мы могли убедиться, что сервер тот за кого себя выдает и после его принятия мы вводим пароль и подключаемся.
При этом сам пароль по сети не передается.

Вопрос: Что сможет сделать злоумышленник имея доступ к серверу, где в реестре хранятся данные для аутентификации(Salt, Verifier, vncPassword, Certificate, Key)?
И какие есть варианты узнать пароль в этом случае, если по сети его не перехватить?
Пароль для сервера настраивается на Веб-интерфейсе и распространяется на компьютеры клиентов в реестр.

Вот код с сервера:
Java:
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class JavaCrypto {
  private static final int AES_BLOCK_SIZE = 16;

  private static final String SRP_USER = "User";

  private static final byte colon = 58;

  private static boolean debug = false;

  public static final int SRP_SALT_BITS = 80;

  public static final int SRP_SALT_BYTES = 10;

  public static final int SRP_VERIFIER_BYTES = 1024;

  static final byte[] SRP_MODULUS = new byte[] {
      -1, -1, -1, -1, -1, -1, -1, -1, -55, 15,
      -38, -94, 33, 104, -62, 52, -60, -58, 98, -117,
      Byte.MIN_VALUE, -36, 28, -47, 41, 2, 78, 8, -118, 103,
      108, -70, -50, -44, -69, 27, -37, Byte.MAX_VALUE, 20, 71,
      -26, -52, 37, 75, 51, 32, 81, 81, 43, -41,
      89, -25, -55, Byte.MAX_VALUE, -66, -57, -24, -13, 35, -87,
      122, 126, 54, -52, -120, -66, 15, 29, 69, -73,
      20, -52, 94, -46, 15, Byte.MIN_VALUE, 55, -32, -89, -105,
      -38, 86, -55, -20, 46, -14, -106, 50, 56, Byte.MAX_VALUE,
      -123, -35, -6, -99, 75, Byte.MAX_VALUE, -94, -64, -121, -24,
      121, 104, 51, 3, -19, 91, -35, 58, 6, 43,
      -56, 31, 86, -24, Byte.MIN_VALUE, -71, 110, 113, 96, -55,
      Byte.MIN_VALUE, -35, -104, -19, -45, -33, -1, -1, -1, -1,
      -1, -1, -1, -1 };

  static final byte[] SRP_GENERATOR = new byte[] { 19 };

  public static void main(String[] args) {
    try {
      String vncmetadata = "VNCpaswd";
      String metadata = "This is Password";
      byte[] encryptedBytes = AES_encrypt(vncmetadata.getBytes("UTF-8"));
      System.out.println("AES encryption successful" + ((encryptedBytes != null && encryptedBytes.length > 0) ? 1 : 0));
      byte[] hashedBytes = SHA1_hash(metadata.getBytes("UTF-8"));
      System.out.println("SHA1 Hash successful" + ((hashedBytes != null && hashedBytes.length > 0) ? 1 : 0));
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("Generating SRP Verifier and salt...");
    System.out.println();
    String password = new String("String");
    SRP_Verifier_Salt svs = GenerateSRPVerifier(password);
    System.out.println("Outer verifier size: " + svs.verifier.length);
    System.out.println();
    int i;
    for (i = 0; i < svs.verifier.length; i++)
      System.out.print("[" + svs.verifier[i] + "] ");
    System.out.println();
    System.out.println();
    System.out.println("Outer salt size: " + svs.salt.length);
    System.out.println();
    for (i = 0; i < svs.salt.length; i++)
      System.out.print("[" + svs.salt[i] + "] ");
    System.out.println();
  }

  public static byte[] AES_encrypt(byte[] plainText) throws Exception {
    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128);
    SecretKey sKey = keyGen.generateKey();
    SecretKey sIV = keyGen.generateKey();
    byte[] rawKey = sKey.getEncoded();
    byte[] rawIV = sIV.getEncoded();
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKey key = new SecretKeySpec(rawKey, "AES");
    IvParameterSpec iv = new IvParameterSpec(rawIV);
    cipher.init(1, key, iv);
    byte[] cipherText = cipher.doFinal(plainText);
    byte[] result = new byte[48];
    for (int i = 0; i < 16; i++) {
      result[3 * i] = rawKey[i];
      result[3 * i + 1] = rawIV[i];
      result[3 * i + 2] = cipherText[i];
    }
    return result;
  }

  public static String AES_decrypt(byte[] cipherText) throws Exception {
    byte[] text2decrypt = new byte[16];
    byte[] key = new byte[16];
    byte[] iv = new byte[16];
    for (int i = 0; i < 16; i++) {
      key[i] = cipherText[3 * i];
      iv[i] = cipherText[3 * i + 1];
      text2decrypt[i] = cipherText[3 * i + 2];
    }
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
    IvParameterSpec ivSpec = new IvParameterSpec(iv);
    cipher.init(2, keySpec, ivSpec);
    byte[] results = cipher.doFinal(text2decrypt);
    return new String(results, "UTF-8");
  }

  public static byte[] SHA1_hash(byte[] plainText) throws Exception {
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    md.update(plainText);
    return md.digest();
  }

  public static synchronized SRP_Verifier_Salt GenerateSRPVerifier(String password) {
    for (int i = 0; i < 10; i++) {
      try {
        SRP_Verifier_Salt srp_vs = GenerateOneTimeSRPVerifier(password);
        if (srp_vs != null)
          return srp_vs;
      } catch (Exception e) {
        e.printStackTrace();
      }
      System.out.println("Regenerating verifier...");
    }
    return null;
  }

  private static synchronized SRP_Verifier_Salt GenerateOneTimeSRPVerifier(String password) throws Exception {
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    SRP_Verifier_Salt vs = new SRP_Verifier_Salt();
    byte[] salt = GenerateSRPSalt();
    if (debug == true) {
      System.out.println("Salt size: " + salt.length);
      System.out.println("Salt: ");
      for (int i = 0; i < salt.length; i++)
        System.out.print("[" + salt[i] + "] ");
      System.out.println();
    }
    sha.update("User".getBytes());
    sha.update((byte)58);
    sha.update(password.getBytes());
    byte[] digest = sha.digest();
    if (debug == true) {
      System.out.println();
      System.out.print("#(u+\":\"+p) =");
      System.out.println();
      for (int i = 0; i < digest.length; i++)
        System.out.print("[" + digest[i] + "] ");
      System.out.println();
    }
    sha.reset();
    sha.update(salt);
    sha.update(digest);
    digest = sha.digest();
    if (debug == true) {
      System.out.println();
      System.out.print("#(s+#(u+\":\"+p)) =");
      System.out.println();
      for (int i = 0; i < digest.length; i++)
        System.out.print("[" + digest[i] + "] ");
      System.out.println();
    }
    BigInteger x = new BigInteger(1, digest);
    BigInteger g = new BigInteger(1, SRP_GENERATOR);
    BigInteger n = new BigInteger(1, SRP_MODULUS);
    BigInteger v = g.modPow(x, n);
    byte[] verifier = v.toByteArray();
    if (debug == true) {
      System.out.println("Verifier size: " + verifier.length);
      for (int i = 0; i < verifier.length; i++)
        System.out.print("[" + verifier[i] + "] ");
      System.out.println();
    }
    if (verifier.length == 1024) {
      vs.salt = salt;
      vs.verifier = verifier;
      return vs;
    }
    if (verifier.length == 1025 && verifier[0] == 0) {
      vs.salt = salt;
      vs.verifier = new byte[1024];
      System.arraycopy(verifier, 1, vs.verifier, 0, 1024);
      return vs;
    }
    return null;
  }

  public static synchronized byte[] GenerateSRPSalt() {
    for (int i = 0; i < 10; i++) {
      try {
        byte[] rnd_num = GenerateOneTimeSRPSalt();
        if (rnd_num != null)
          return rnd_num;
        Thread.sleep(100L);
      } catch (Exception e) {
        e.printStackTrace();
      }
      System.out.println("Regenerating salt...");
    }
    return null;
  }

  public static synchronized byte[] GenerateOneTimeSRPSalt() {
    BigInteger big_rnd_num = new BigInteger(80, new Random());
    byte[] rnd_num = big_rnd_num.toByteArray();
    if (rnd_num.length == 10)
      return rnd_num;
    if (rnd_num.length == 11 && rnd_num[0] == 0) {
      byte[] rnd_num_2 = new byte[10];
      System.arraycopy(rnd_num, 1, rnd_num_2, 0, 10);
      return rnd_num_2;
    }
    return null;
  }
}

Можно ли с помощью данного кода "сбрутить" пароль имея данные с удаленного компьютера(Salt, Verifier, vncPassword, Certificate, Key)?
 
Последнее редактирование:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!