форум vBSupport.ru > vBSupport.ru > Гурушник > True
Register Меню vBsupport Изображения Files Manager О рекламе Today's Posts Search
  • Родная гавань
  • Блок РКН снят
  • Premoderation
  • For English speaking users
  • Каталог Фрилансеров
  • If you want to buy some product or script
  • Администраторам
VBsupport перешел с домена .ORG на родной .RU Ура! Пожалуйста, обновите свои закладки - VBsupport.ru
Блок РКН снят, форум доступен на всей территории России, включая новые терртории, без VPN
На форуме введена премодерация ВСЕХ новых пользователей

Почта с временных сервисов, типа mailinator.com, gawab.com и/или прочих, которые предоставляют временный почтовый ящик без регистрации и/или почтовый ящик для рассылки спама, отслеживается и блокируется, а так же заносится в спам-блок форума, аккаунты удаляются
for English speaking users:
You may be surprised with restriction of access to the attachments of the forum. The reason is the recent change in vbsupport.org strategy:

- users with reputation < 10 belong to "simple_users" users' group
- if your reputation > 10 then administrator (kerk, Luvilla) can decide to move you into an "improved" group, but only manually

Main idea is to increase motivation of community members to share their ideas and willingness to support to each other. You may write an article for the subject where you are good enough, you may answer questions, you may share vbulletin.com/org content with vbsupport.org users, receiving "thanks" equal your reputation points. We should not only consume, we should produce something.

- you may:
* increase your reputation (doing something useful for another members of community) and being improved
* purchase temporary access to the improved category:
10 $ for 3 months. - this group can download attachments, reputation/posts do not matter.
20 $ for 3 months. - this group can download attachments, reputation/posts do not matter + adds eliminated + Inbox capacity increased + files manager increased permissions.

Please contact kerk or Luvilla regarding payments.

Important!:
- if your reputation will become less then 0, you will be moved into "simple_users" users' group automatically.*
*for temporary groups (pre-paid for 3 months) reputation/posts do not matter.
Уважаемые пользователи!

На форуме открыт новый раздел "Каталог фрилансеров"

и отдельный раздел для платных заказов "Куплю/Закажу"

Если вы хотите приобрести какой то скрипт/продукт/хак из каталогов перечисленных ниже:
Каталог модулей/хаков
Ещё раз обращаем Ваше внимание: всё, что Вы скачиваете и устанавливаете на свой форум, Вы устанавливаете исключительно на свой страх и риск.
Сообщество vBSupport'а физически не в состоянии проверять все стили, хаки и нули, выкладываемые пользователями.
Помните: безопасность Вашего проекта - Ваша забота.
Убедительная просьба: при обнаружении уязвимостей или сомнительных кодов обязательно отписывайтесь в теме хака/стиля
Спасибо за понимание
 
 
 
 
True
Администратор
 
True's Avatar
Default Криптография в vb3
2

Вожусь тут с файлами в ходе апгрейда на пхп8, обнаружил, что в 3-й вобле оказывается есть целый класс, посвящённый криптографии!

Понятно, что он мегодревний, и надо обновить методы, но какова сама идея!) Даже можно настроить шифрованное общение движков форумов через апи! Правда, судя по всему, функционал настолько сильно забыли. что так и не применяли. В движке использований 0. :(

PHP Code:
Example Usage:

Encryption Decryption
-------------------------
$rc4 = new vB_Encrypt("My Key");
$encrypted $rc4->encrypt("Our super sensitive secret");

$data $rc4->decrypt($encrypted);

Shared key generation between two servers
-------------------------
$host Diffie_Hellman::fetch_library();
$host_pkey $host->fetch_public_key();

$client_pkey file_get_contents("http://www.example.com/forums/auth.php?pkey=$host_pkey");

$shared_key $host->fetch_shared_secret($client_pkey); 
Bot
Yandex Bot Yandex Bot is online now
 
Join Date: 05.05.2005
Реклама на форуме А что у нас тут интересного? =)
 
 
True
Администратор
 
True's Avatar
Default
1

Обновил класс с помощью ИИ, получилось как-то так. Вроде работает.

Документация по class_encryption.php

Современный криптографический helper для vBulletin 3.

Файл предоставляет четыре основных механизма:

Code:
vB_Encrypt
    Симметричное шифрование + HMAC

vB_KeyExchange_X25519
    Обмен ключами между двумя сторонами

vB_PublicKey_Encrypt
    Шифрование публичным ключом

vB_Signature_Ed25519
    Цифровые подписи
Также имеется внутренний вспомогательный класс:

Code:
vB_Crypto_Util
Он используется для Base64URL-кодирования и служебных проверок Sodium.


1. Подключение

В vBulletin 3:

PHP Code:
require_once(DIR '/includes/class_encryption.php'); 
Файл защищён от прямого выполнения через браузер.


2. Требования

Для полного функционала рекомендуется расширение PHP Sodium.

Проверка:

PHP Code:
extension_loaded('sodium'); 
Sodium используется для:
  • XChaCha20-Poly1305
  • X25519
  • Sealed Boxes
  • Ed25519

OpenSSL используется для AES-256-GCM и является fallback-вариантом симметричного шифрования.

Получить доступные методы:

PHP Code:
$methods vB_Encrypt::get_available_methods();

print_r($methods); 
Например:

Code:
Array
(
    [0] => xchacha20poly1305
    [1] => aes256gcm
)
Получить предпочтительный алгоритм:

PHP Code:
$method vB_Encrypt::get_preferred_method(); 
При наличии Sodium:

Code:
xchacha20poly1305

vB_Encrypt

Основной класс для симметричного шифрования данных.

Подходит для хранения:
  • API-токенов
  • OAuth access/refresh tokens
  • секретов внешних интеграций
  • токенов ботов
  • секретных настроек
  • персональных данных
  • конфиденциальных значений в БД
  • зашифрованных backup-данных

Поддерживает:

Code:
XChaCha20-Poly1305
AES-256-GCM
HMAC-SHA256
HKDF-SHA256
AAD
Оба алгоритма шифрования являются authenticated encryption.

Это означает, что при расшифровке одновременно проверяется целостность данных.

Если ciphertext был изменён, расшифровка завершится ошибкой.


3. Генерация ключа

Рекомендуемый вариант:

PHP Code:
$key vB_Encrypt::generate_key_base64();

echo 
$key
Генерируется случайный 256-битный ключ.

Для постоянного использования его можно хранить, например, в config.php:

PHP Code:
$config['Crypto']['masterkey'] = 'BASE64URL_KEY_HERE'
Master key желательно хранить отдельно от базы данных.

Если злоумышленник украдёт только MySQL dump, наличие ключа вне базы не позволит ему автоматически расшифровать защищённые значения.


4. Использование Base64-ключа

PHP Code:
$crypto = new vB_Encrypt();

$crypto->set_base64_key(
    
$config['Crypto']['masterkey']
); 
Именно этот способ рекомендуется для ключей, созданных:

PHP Code:
vB_Encrypt::generate_key_base64(); 

5. Raw key

Можно работать с бинарным 32-байтовым ключом:

PHP Code:
$key vB_Encrypt::generate_key();

$crypto = new vB_Encrypt();

$crypto->set_raw_key($key); 
Метод set_raw_key() требует ключ ровно 32 байта.


6. set_key()

Также можно передать секретный материал напрямую:

PHP Code:
$crypto = new vB_Encrypt('some-secret'); 
или:

PHP Code:
$crypto = new vB_Encrypt();

$crypto->set_key('some-secret'); 
Из переданного материала внутренний ключ выводится через HKDF-SHA256.

Это не механизм хранения пользовательских паролей.

Пароли пользователей должны обрабатываться через:

PHP Code:
password_hash();
password_verify(); 

7. Простое шифрование

PHP Code:
$key vB_Encrypt::generate_key_base64();

$crypto = new vB_Encrypt();

$crypto->set_base64_key($key);

$encrypted $crypto->encrypt(
    
'Очень секретный текст'
);

$decrypted $crypto->decrypt(
    
$encrypted
); 
После расшифровки:

Code:
$decrypted === 'Очень секретный текст'

8. Автоматический выбор алгоритма

Обычный вызов:

PHP Code:
$encrypted $crypto->encrypt($data); 
Использует автоматический выбор:

Code:
есть XChaCha20-Poly1305
        |
        +--> используется XChaCha20-Poly1305

иначе

есть AES-256-GCM
        |
        +--> используется AES-256-GCM

иначе
        |
        +--> RuntimeException
Обычно вручную выбирать алгоритм не требуется.


9. Принудительный выбор алгоритма

XChaCha20-Poly1305:

PHP Code:
$encrypted $crypto->encrypt(
    
$data,
    
'',
    
vB_Encrypt::METHOD_XCHACHA20_POLY1305
); 
AES-256-GCM:

PHP Code:
$encrypted $crypto->encrypt(
    
$data,
    
'',
    
vB_Encrypt::METHOD_AES_256_GCM
); 

10. Формат ciphertext

Результат encrypt() является обычной ASCII-строкой.

Её можно хранить в:
  • TEXT / MEDIUMTEXT
  • файлах
  • JSON
  • API
  • настройках форума

XChaCha20-Poly1305:

Code:
VBENC2.xchacha20poly1305.<nonce>.<ciphertext>
AES-256-GCM:

Code:
VBENC2.aes256gcm.<iv>.<tag>.<ciphertext>
Все бинарные части кодируются через Base64URL.

Алгоритм записан непосредственно в ciphertext, поэтому decrypt() самостоятельно определяет, какой метод использовать.


11. AAD — Additional Authenticated Data

AAD позволяет криптографически привязать ciphertext к определённому контексту.

Например:

PHP Code:
$aad 'userid=123|field=api_token';

$encrypted $crypto->encrypt(
    
$token,
    
$aad
); 
Расшифровывать нужно с тем же AAD:

PHP Code:
$token $crypto->decrypt(
    
$encrypted,
    
'userid=123|field=api_token'
); 
Попытка использовать другой контекст:

PHP Code:
$crypto->decrypt(
    
$encrypted,
    
'userid=456|field=api_token'
); 
завершится ошибкой аутентификации.

Практический вариант:

PHP Code:
$aad =
    
'table=user'
    
'|userid=' intval($userid)
    . 
'|field=telegram_token';

$encrypted $crypto->encrypt(
    
$telegram_token,
    
$aad
); 
Теперь ciphertext криптографически привязан:
  • к таблице
  • к пользователю
  • к назначению поля

AAD не является секретным и не шифруется.


12. Обработка ошибок расшифровки

PHP Code:
try
{
    
$plain $crypto->decrypt(
        
$encrypted,
        
$aad
    
);
}
catch (
Throwable $e)
{
    
// Неверный ключ
    // Неверный AAD
    // Повреждённый ciphertext
    // Неподдерживаемый формат
    // Authentication failure

Расшифровка не должна молча возвращать повреждённый plaintext.

При нарушении целостности возникает исключение.


13. HMAC-SHA256

Если данные скрывать не требуется, но необходимо защитить их от изменения, используется HMAC.

Создание подписи:

PHP Code:
$signature $crypto->fetch_signature($data); 
Проверка:

PHP Code:
if ($crypto->verify_signature($data$signature))
{
    
// Подпись правильная
}
else
{
    
// Данные или подпись были изменены

Формат:

Code:
VBMAC1.<signature>
Используется:

Code:
HMAC-SHA256

14. Пример подписи API-запроса

PHP Code:
$payload json_encode(array(
    
'userid'    => 123,
    
'amount'    => 500,
    
'timestamp' => time(),
));

$signature $crypto->fetch_signature($payload); 
На принимающей стороне:

PHP Code:
if (!$crypto->verify_signature($payload$signature))
{
    die(
'Invalid signature');
}

$data json_decode($payloadtrue); 
Если изменить даже одно поле payload, старая подпись больше не будет действительна.

Для защиты API от replay-атак рекомендуется включать в подписываемые данные:
  • timestamp
  • nonce
  • transaction_id
  • userid
  • тип операции


vB_KeyExchange_X25519

Используется для установления общих session keys между двумя сторонами.

Например:

Code:
форум <-> внешний сервис
клиент <-> сервер
worker <-> API
Создание двух участников:

PHP Code:
$client = new vB_KeyExchange_X25519();
$server = new vB_KeyExchange_X25519(); 

15. Получение public key

PHP Code:
$client_public $client->fetch_public_key();

$server_public $server->fetch_public_key(); 
Public key можно свободно передавать другой стороне.


16. Получение session keys

Клиент:

PHP Code:
$client_keys $client->fetch_client_session_keys(
    
$server->fetch_public_key()
); 
Сервер:

PHP Code:
$server_keys $server->fetch_server_session_keys(
    
$client->fetch_public_key()
); 
Возвращаются:

PHP Code:
$client_keys['receive_key'];
$client_keys['send_key'];

$server_keys['receive_key'];
$server_keys['send_key']; 
Соответствие:

Code:
client.send_key
        =
server.receive_key


client.receive_key
        =
server.send_key
Для каждого направления используется отдельный ключ.


17. X25519 + vB_Encrypt

Клиент:

PHP Code:
$client_keys $client->fetch_client_session_keys(
    
$server_public
);

$client_crypto = new vB_Encrypt();

$client_crypto->set_base64_key(
    
$client_keys['send_key']
);

$ciphertext $client_crypto->encrypt(
    
'Hello server'
); 
Сервер:

PHP Code:
$server_keys $server->fetch_server_session_keys(
    
$client_public
);

$server_crypto = new vB_Encrypt();

$server_crypto->set_base64_key(
    
$server_keys['receive_key']
);

$message $server_crypto->decrypt(
    
$ciphertext
); 
Результат:

Code:
Hello server
Для обычных HTTP API X25519 не является заменой HTTPS/TLS.

Использовать его имеет смысл для собственных application-level протоколов и дополнительных криптографических схем.


18. Сохранение X25519 keypair

PHP Code:
$keypair $client->fetch_keypair(); 
Позже объект можно восстановить:

PHP Code:
$client = new vB_KeyExchange_X25519(
    
$saved_keypair
); 
Также доступны:

PHP Code:
$client->fetch_public_key();
$client->fetch_secret_key(); 
Secret key и keypair нельзя публиковать или записывать в открытые логи.


vB_PublicKey_Encrypt

Асимметричное шифрование через Sodium Sealed Boxes.

Принцип:

Code:
PUBLIC KEY
    |
    +--> позволяет шифровать


PRIVATE KEY / KEYPAIR
    |
    +--> позволяет расшифровать
Создание получателя:

PHP Code:
$recipient = new vB_PublicKey_Encrypt(); 
Получение public key:

PHP Code:
$public_key $recipient->fetch_public_key(); 
Public key можно передавать всем отправителям.


19. Шифрование публичным ключом

Отправителю private key не требуется:

PHP Code:
$encrypted vB_PublicKey_Encrypt::encrypt_for(
    
'Очень секретное сообщение',
    
$public_key
); 
Формат:

Code:
VBSEAL1.<ciphertext>

20. Расшифровка

Расшифровать данные может владелец соответствующей keypair:

PHP Code:
$plain $recipient->decrypt(
    
$encrypted
); 

21. Практический сценарий Sealed Boxes

На публичном web-сервере хранится только public key:

PHP Code:
$PUBLIC_KEY '...'
При поступлении секретных данных:

PHP Code:
$encrypted =
    
vB_PublicKey_Encrypt::encrypt_for(
        
$_POST['message'],
        
$PUBLIC_KEY
    
); 
В базе хранится только:

Code:
VBSEAL1....
Private key можно держать:
  • на отдельном сервере
  • в закрытом backend-процессе
  • в специальном secret storage
  • у администратора

Таким образом, публичный сервер умеет принимать и шифровать данные, но не обязан уметь расшифровывать уже сохранённые сообщения.


22. Сохранение keypair

PHP Code:
$keypair $recipient->fetch_keypair(); 
Восстановление:

PHP Code:
$recipient = new vB_PublicKey_Encrypt(
    
$keypair
); 
Также доступны:

PHP Code:
$recipient->fetch_public_key();
$recipient->fetch_secret_key(); 

vB_Signature_Ed25519

Предназначен для настоящих цифровых подписей.

В отличие от HMAC, проверяющей стороне не требуется знать секретный ключ.

Схема:

Code:
PRIVATE KEY
    |
    +--> создаёт подпись


PUBLIC KEY
    |
    +--> проверяет подпись
Подходит для:
  • подписанных API-сообщений
  • обновлений
  • плагинов
  • лицензионных файлов
  • SSO-токенов
  • межсерверных событий
  • подписанных конфигураций


23. Создание Ed25519 keypair

PHP Code:
$signer = new vB_Signature_Ed25519(); 
Public key:

PHP Code:
$public_key $signer->fetch_public_key(); 
Public key можно распространять.

Полная keypair:

PHP Code:
$keypair $signer->fetch_keypair(); 
Её необходимо хранить секретно.


24. Создание подписи

PHP Code:
$message 'userid=123|amount=500';

$signature $signer->sign(
    
$message
); 
Формат:

Code:
VBED25519.<signature>

25. Проверка Ed25519

Для проверки private key не требуется:

PHP Code:
$valid =
    
vB_Signature_Ed25519::verify(
        
$message,
        
$signature,
        
$public_key
    
);

if (
$valid)
{
    echo 
'Signature valid';

Если данные изменить:

PHP Code:
$valid =
    
vB_Signature_Ed25519::verify(
        
'userid=123|amount=500000',
        
$signature,
        
$public_key
    
); 
результат будет:

Code:
false

26. Восстановление Ed25519 keypair

Сохранение:

PHP Code:
$keypair $signer->fetch_keypair(); 
Восстановление:

PHP Code:
$signer = new vB_Signature_Ed25519(
    
$keypair
); 

27. Важное правило для постоянных keypair

Следующие вызовы без аргументов создают новые ключевые пары:

PHP Code:
new vB_KeyExchange_X25519();

new 
vB_PublicKey_Encrypt();

new 
vB_Signature_Ed25519(); 
Если серверу нужна постоянная криптографическая идентичность, нельзя генерировать новую keypair при каждом HTTP-запросе.

Правильно:

PHP Code:
// Создать один раз

$signer = new vB_Signature_Ed25519();

$keypair $signer->fetch_keypair();

// Сохранить $keypair 
При следующих запросах:

PHP Code:
$signer = new vB_Signature_Ed25519(
    
$stored_keypair
); 

28. Где хранить ключи

Для vB_Encrypt:

Code:
MASTER KEY
    |
    +--> config.php / ENV / secret storage


CIPHERTEXT
    |
    +--> MySQL
Не рекомендуется хранить master key рядом с ciphertext в той же таблице базы данных.


Для Ed25519:

Code:
PRIVATE KEY / KEYPAIR
    |
    +--> секретное хранилище


PUBLIC KEY
    |
    +--> можно свободно распространять

Для PublicKey Encryption:

Code:
PRIVATE KEY / KEYPAIR
    |
    +--> секретное хранилище


PUBLIC KEY
    |
    +--> всем отправителям

29. Обработка исключений

Рекомендуемый production-код:

PHP Code:
try
{
    
$plain $crypto->decrypt(
        
$encrypted,
        
$aad
    
);
}
catch (
InvalidArgumentException $e)
{
    
// Некорректный формат
    // Некорректный ключ
    // Некорректные входные данные
}
catch (
RuntimeException $e)
{
    
// Ошибка crypto backend
    // Authentication failure
    // Неправильный ключ
    // Повреждённый ciphertext

Не рекомендуется показывать подробные сообщения исключений конечному пользователю.

Технические подробности лучше писать в серверный лог.


Краткий справочник API

vB_Encrypt

PHP Code:
new vB_Encrypt($key null);

set_key($key);

set_raw_key($key);

set_base64_key($key);

generate_key();

generate_key_base64();

get_available_methods();

get_preferred_method();

encrypt(
    
$plain,
    
$aad '',
    
$method vB_Encrypt::METHOD_AUTO
);

decrypt(
    
$ciphertext,
    
$aad ''
);

fetch_signature($data);

verify_signature(
    
$data,
    
$signature
); 
Константы:

PHP Code:
vB_Encrypt::METHOD_AUTO

vB_Encrypt
::METHOD_XCHACHA20_POLY1305

vB_Encrypt
::METHOD_AES_256_GCM 

vB_KeyExchange_X25519

PHP Code:
new vB_KeyExchange_X25519(
    
$encodedKeypair ''
);

fetch_keypair();

fetch_public_key();

fetch_secret_key();

fetch_client_session_keys(
    
$serverPublicKey
);

fetch_server_session_keys(
    
$clientPublicKey
); 

vB_PublicKey_Encrypt

PHP Code:
new vB_PublicKey_Encrypt(
    
$encodedKeypair ''
);

fetch_keypair();

fetch_public_key();

fetch_secret_key();

vB_PublicKey_Encrypt::encrypt_for(
    
$plainData,
    
$recipientPublicKey
);

decrypt(
    
$encryptedData
); 

vB_Signature_Ed25519

PHP Code:
new vB_Signature_Ed25519(
    
$encodedKeypair ''
);

fetch_keypair();

fetch_public_key();

fetch_secret_key();

sign($data);

vB_Signature_Ed25519::verify(
    
$data,
    
$signature,
    
$publicKey
); 

Какой механизм выбирать

Code:
Нужно скрыть данные и позже расшифровать их тем же сервером?

    vB_Encrypt


Нужно защитить открытые данные от изменения,
и обе стороны могут знать общий секрет?

    HMAC:
    vB_Encrypt::fetch_signature()
    vB_Encrypt::verify_signature()


Нужно подписывать одной стороной,
а проверять множеством систем,
не выдавая им private key?

    vB_Signature_Ed25519


Любой отправитель должен иметь возможность
зашифровать сообщение,
но расшифровать его должен только владелец private key?

    vB_PublicKey_Encrypt


Два сервиса должны договориться
о временных session keys?

    vB_KeyExchange_X25519

Практический пример для vBulletin: шифрование API-токена

В config.php:

PHP Code:
$config['Crypto']['masterkey'] =
    
'BASE64URL_MASTER_KEY_HERE'
Создать master key можно один раз:

PHP Code:
echo vB_Encrypt::generate_key_base64(); 
При сохранении API-токена:

PHP Code:
require_once(DIR '/includes/class_crypto.php');

$crypto = new vB_Encrypt();

$crypto->set_base64_key(
    
$config['Crypto']['masterkey']
);

$aad =
    
'integration=boosty'
    
'|userid=' intval($userid);

$encrypted_token =
    
$crypto->encrypt(
        
$access_token,
        
$aad
    
); 
В MySQL сохраняется строка:

Code:
VBENC2.xchacha20poly1305....
При чтении:

PHP Code:
$access_token =
    
$crypto->decrypt(
        
$encrypted_token,
        
$aad
    
); 

Что этим классом делать не нужно

1. Не шифровать пользовательские пароли.

Неправильно:

PHP Code:
$encrypted_password =
    
$crypto->encrypt($password); 
Пароли должны храниться через необратимое password hashing.


2. Не использовать X25519 как самодельную замену HTTPS/TLS.

Для обычного HTTP API должен использоваться HTTPS.


3. Не публиковать:

Code:
fetch_secret_key()

fetch_keypair()

master encryption key

4. Не записывать секретные ключи в debug output, HTML или обычные application logs.


5. Не генерировать новую постоянную keypair при каждом запросе, если ожидается постоянная идентичность сервера.


Минимальная памятка

Симметричное шифрование:

PHP Code:
$key vB_Encrypt::generate_key_base64();

$c = new vB_Encrypt();

$c->set_base64_key($key);

$enc $c->encrypt('secret');

$dec $c->decrypt($enc); 

HMAC:

PHP Code:
$sig $c->fetch_signature('data');

$ok $c->verify_signature(
    
'data',
    
$sig
); 

Public-key encryption:

PHP Code:
$r = new vB_PublicKey_Encrypt();

$enc =
    
vB_PublicKey_Encrypt::encrypt_for(
        
'secret',
        
$r->fetch_public_key()
    );

$dec $r->decrypt($enc); 

Ed25519:

PHP Code:
$s = new vB_Signature_Ed25519();

$sig $s->sign('data');

$ok =
    
vB_Signature_Ed25519::verify(
        
'data',
        
$sig,
        
$s->fetch_public_key()
    ); 

X25519:

PHP Code:
$client = new vB_KeyExchange_X25519();

$server = new vB_KeyExchange_X25519();

$client_keys =
    
$client->fetch_client_session_keys(
        
$server->fetch_public_key()
    );

$server_keys =
    
$server->fetch_server_session_keys(
        
$client->fetch_public_key()
    ); 
Соответствие session keys:

Code:
$client_keys['send_key']
    ===
$server_keys['receive_key']


$client_keys['receive_key']
    ===
$server_keys['send_key']
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off




All times are GMT +4. The time now is 04:30 PM.


Powered by vBulletin® Version 3.0.7
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.